diff --git a/src/main/java/org/dynapi/jsonschema/gen/AnnotationParser.java b/src/main/java/org/dynapi/jsonschema/gen/AnnotationParser.java index 15bbfe4..ae64909 100644 --- a/src/main/java/org/dynapi/jsonschema/gen/AnnotationParser.java +++ b/src/main/java/org/dynapi/jsonschema/gen/AnnotationParser.java @@ -35,7 +35,18 @@ class AnnotationParser { for (Field field : clazz.getDeclaredFields()) { if (hiddenPropertiesNames.contains(field.getName()) || field.isAnnotationPresent(Hidden.class)) continue; - Schema fieldSchema = generateJsonSchemaForField(state, field.getType()); + Schema fieldSchema; + + Implementations implementations = field.getAnnotation(Implementations.class); + if (implementations != null) { + fieldSchema = new OneOf( + Stream.of(implementations.value()) + .map(implementation -> generateJsonSchemaForObject(state, implementation)) + .toList() + ); + } else { + fieldSchema = generateJsonSchemaForField(state, field.getType()); + } applyDescription(field.getAnnotation(Description.class), fieldSchema); applyExamples(field.getAnnotation(Examples.class), fieldSchema); @@ -96,7 +107,9 @@ class AnnotationParser { } protected static Schema generateJsonSchemaForField(StateData state, Class clazz) { - if (clazz.equals(int.class) || clazz.equals(Integer.class)) { + if (clazz.equals(Number.class)) { + return new TNumber(); + } else if (clazz.equals(int.class) || clazz.equals(Integer.class)) { return new TInteger(); } else if (clazz.equals(long.class) || clazz.equals(Long.class)) { return new TInteger(); diff --git a/src/main/java/org/dynapi/jsonschema/gen/annotations/Implementations.java b/src/main/java/org/dynapi/jsonschema/gen/annotations/Implementations.java new file mode 100644 index 0000000..7f2fdb0 --- /dev/null +++ b/src/main/java/org/dynapi/jsonschema/gen/annotations/Implementations.java @@ -0,0 +1,13 @@ +package org.dynapi.jsonschema.gen.annotations; + +import java.lang.annotation.*; + +/** + * can be used to generate schema based on some implementations of an interface or a subclass + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Implementations { + Class[] value(); +}