22
33import org .dynapi .jsonschema .gen .annotations .*;
44import org .dynapi .jsonschema .gen .schema .*;
5+ import org .json .JSONObject ;
56
67import java .lang .reflect .Field ;
78import java .util .*;
@@ -32,6 +33,8 @@ class AnnotationParser {
3233 throw new RuntimeException ("Unknown properties to hide: " + String .join (", " , diff ));
3334 }
3435
36+ List <Set <String >> mutuallyExclusivesGroups = new ArrayList <>();
37+
3538 for (Field field : clazz .getDeclaredFields ()) {
3639 if (hiddenPropertiesNames .contains (field .getName ()) || field .isAnnotationPresent (Hidden .class )) continue ;
3740
@@ -57,9 +60,41 @@ class AnnotationParser {
5760 jsonSchema .requiredIf (ifField , requiredIf .value ());
5861 }
5962
63+ // finds a mutually exclusive group and adds, or creates a new one
64+ MutuallyExclusiveWith mutuallyExclusiveWith = field .getAnnotation (MutuallyExclusiveWith .class );
65+ if (mutuallyExclusiveWith != null ) {
66+ Set <String > group = new HashSet <>();
67+ group .add (field .getName ());
68+ group .addAll (Arrays .asList (mutuallyExclusiveWith .value ()));
69+ Optional <Set <String >> existingGroup = mutuallyExclusivesGroups .stream ().filter (g -> !Collections .disjoint (g , group )).findFirst ();
70+ if (existingGroup .isPresent ()) {
71+ existingGroup .get ().addAll (group );
72+ } else {
73+ mutuallyExclusivesGroups .add (group );
74+ }
75+ }
76+
6077 jsonSchema .addProperty (field .getName (), fieldSchema );
6178 }
6279
80+ // weird way of adding mutually exclusive fields
81+ if (!mutuallyExclusivesGroups .isEmpty ()) {
82+ AllOf allOf = new AllOf ();
83+ for (Set <String > group : mutuallyExclusivesGroups ) {
84+ OneOf oneOf = new OneOf ();
85+ for (String fieldName : group ) {
86+ Set <String > otherFields = new HashSet <>(group );
87+ otherFields .remove (fieldName );
88+ BackdoorSchema backdoor = new BackdoorSchema ()
89+ .setDirectly ("required" , List .of (fieldName ))
90+ .setDirectly ("not" , new JSONObject ().put ("required" , otherFields ));
91+ oneOf .addSchema (backdoor );
92+ }
93+ allOf .addSchema (oneOf );
94+ }
95+ BackdoorSchema .addExtraSchemaDataFromTo (allOf , jsonSchema );
96+ }
97+
6398 return jsonSchema ;
6499 }
65100
0 commit comments