Skip to content

Commit a2723d8

Browse files
authored
Merge pull request #194 from Apicurio/feature/union-map-list-support
Add support for union maps and union lists
2 parents 9971e76 + 5c29f1a commit a2723d8

25 files changed

Lines changed: 1071 additions & 7 deletions

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@ target/
1010
.settings
1111
.classpath
1212
website
13+
.serena/
14+
PROJECT_INDEX.md
15+
PROJECT_INDEX.json

generator/src/main/java/io/apicurio/umg/pipe/AbstractStage.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ protected boolean isPrimitiveMap(PropertyModel property) {
6464
return property.getType().isMap() && property.getType().getNested().iterator().next().isPrimitiveType();
6565
}
6666

67+
protected boolean isUnionList(PropertyModel property) {
68+
return property.getType().isList() && property.getType().getNested().iterator().next().isUnion();
69+
}
70+
71+
protected boolean isUnionMap(PropertyModel property) {
72+
return property.getType().isMap() && property.getType().getNested().iterator().next().isUnion();
73+
}
74+
6775
protected String singularize(String name) {
6876
return inflector.singularize(name);
6977
}

generator/src/main/java/io/apicurio/umg/pipe/java/AbstractCreateMethodsStage.java

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ protected void createPropertyMethods(JavaSource<?> javaEntity, PropertyModelWith
6868
createGetter(javaEntity, propertyWithOrigin);
6969
createSetter(javaEntity, propertyWithOrigin);
7070
createUnionFactoryMethods(javaEntity, propertyWithOrigin);
71+
} else if (isUnionList(property) || isUnionMap(property)) {
72+
createGetter(javaEntity, propertyWithOrigin);
73+
createSetter(javaEntity, propertyWithOrigin);
74+
createUnionFactoryMethods(javaEntity, propertyWithOrigin);
7175
} else {
7276
warn("Failed to create methods (not yet implemented) for property '" + property.getName() + "' of entity: " + javaEntity.getQualifiedName());
7377
}
@@ -97,6 +101,20 @@ protected void createGetter(JavaSource<?> javaEntity, PropertyModelWithOrigin pr
97101
UnionPropertyType ut = new UnionPropertyType(property.getType());
98102
ut.addImportsTo(javaEntity);
99103
method.setReturnType(ut.toJavaTypeString());
104+
} else if (isUnionList(property)) {
105+
// Handle [Union] -> List<UnionType>
106+
PropertyType unionType = property.getType().getNested().iterator().next();
107+
UnionPropertyType ut = new UnionPropertyType(unionType);
108+
ut.addImportsTo(javaEntity);
109+
javaEntity.addImport(java.util.List.class);
110+
method.setReturnType("List<" + ut.toJavaTypeString() + ">");
111+
} else if (isUnionMap(property)) {
112+
// Handle {Union} -> Map<String, UnionType>
113+
PropertyType unionType = property.getType().getNested().iterator().next();
114+
UnionPropertyType ut = new UnionPropertyType(unionType);
115+
ut.addImportsTo(javaEntity);
116+
javaEntity.addImport(java.util.Map.class);
117+
method.setReturnType("Map<String, " + ut.toJavaTypeString() + ">");
100118
} else {
101119
String propertyOriginNS = propertyWithOrigin.getOrigin().getNamespace().fullName();
102120

@@ -125,6 +143,20 @@ protected void createSetter(JavaSource<?> javaEntity, PropertyModelWithOrigin pr
125143
UnionPropertyType ut = new UnionPropertyType(property.getType());
126144
ut.addImportsTo(javaEntity);
127145
method.addParameter(ut.toJavaTypeString(), "value");
146+
} else if (isUnionList(property)) {
147+
// Handle [Union] -> List<UnionType>
148+
PropertyType unionType = property.getType().getNested().iterator().next();
149+
UnionPropertyType ut = new UnionPropertyType(unionType);
150+
ut.addImportsTo(javaEntity);
151+
javaEntity.addImport(java.util.List.class);
152+
method.addParameter("List<" + ut.toJavaTypeString() + ">", "value");
153+
} else if (isUnionMap(property)) {
154+
// Handle {Union} -> Map<String, UnionType>
155+
PropertyType unionType = property.getType().getNested().iterator().next();
156+
UnionPropertyType ut = new UnionPropertyType(unionType);
157+
ut.addImportsTo(javaEntity);
158+
javaEntity.addImport(java.util.Map.class);
159+
method.addParameter("Map<String, " + ut.toJavaTypeString() + ">", "value");
128160
} else {
129161
JavaType jt = new JavaType(property.getType(), propertyOriginNS);
130162
jt.addImportsTo(javaEntity);
@@ -327,7 +359,19 @@ protected void createInsertMethod(JavaSource<?> javaEntity, PropertyModelWithOri
327359
*/
328360
private void createUnionFactoryMethods(JavaSource<?> javaEntity, PropertyModelWithOrigin propertyWithOrigin) {
329361
PropertyModel property = propertyWithOrigin.getProperty();
330-
UnionPropertyType ut = new UnionPropertyType(property.getType());
362+
PropertyType unionType;
363+
364+
// Extract the union type - it might be directly a union, or wrapped in a list/map
365+
if (property.getType().isUnion()) {
366+
unionType = property.getType();
367+
} else if ((property.getType().isList() || property.getType().isMap()) &&
368+
property.getType().getNested().iterator().next().isUnion()) {
369+
unionType = property.getType().getNested().iterator().next();
370+
} else {
371+
return;
372+
}
373+
374+
UnionPropertyType ut = new UnionPropertyType(unionType);
331375
ut.getNestedTypes().forEach(nestedType -> {
332376
if (nestedType.isEntityType()) {
333377
createFactoryMethod(javaEntity, nestedType);

generator/src/main/java/io/apicurio/umg/pipe/java/AbstractJavaStage.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,14 @@ public boolean isPrimitiveMap() {
462462
return propertyType.isMap() && propertyType.getNested().iterator().next().isPrimitiveType();
463463
}
464464

465+
public boolean isUnionList() {
466+
return propertyType.isList() && propertyType.getNested().iterator().next().isUnion();
467+
}
468+
469+
public boolean isUnionMap() {
470+
return propertyType.isMap() && propertyType.getNested().iterator().next().isUnion();
471+
}
472+
465473
public Class<?> toClass() {
466474
return toClass(propertyType);
467475
}
@@ -506,6 +514,16 @@ public void addImportsTo(Importer<?> importer) {
506514
} else {
507515
importer.addImport(entityType);
508516
}
517+
} else if (isUnionList()) {
518+
PropertyType unionType = propertyType.getNested().iterator().next();
519+
UnionPropertyType ut = new UnionPropertyType(unionType);
520+
ut.addImportsTo(importer);
521+
importer.addImport(List.class);
522+
} else if (isUnionMap()) {
523+
PropertyType unionType = propertyType.getNested().iterator().next();
524+
UnionPropertyType ut = new UnionPropertyType(unionType);
525+
ut.addImportsTo(importer);
526+
importer.addImport(Map.class);
509527
} else if (isEntityList()) {
510528
JavaInterfaceSource listType = useCommonEntityResolution ?
511529
resolveCommonJavaEntity(namespaceContext, propertyType.getNested().iterator().next().getSimpleType()) :
@@ -555,6 +573,14 @@ public String toJavaTypeString() {
555573
} else {
556574
return entityType.getName();
557575
}
576+
} else if (isUnionList()) {
577+
PropertyType unionType = propertyType.getNested().iterator().next();
578+
UnionPropertyType ut = new UnionPropertyType(unionType);
579+
return "List<" + ut.toJavaTypeString() + ">";
580+
} else if (isUnionMap()) {
581+
PropertyType unionType = propertyType.getNested().iterator().next();
582+
UnionPropertyType ut = new UnionPropertyType(unionType);
583+
return "Map<String, " + ut.toJavaTypeString() + ">";
558584
} else if (isEntityList()) {
559585
JavaInterfaceSource listType = useCommonEntityResolution ?
560586
resolveCommonJavaEntity(namespaceContext, propertyType.getNested().iterator().next().getSimpleType()) :
@@ -584,6 +610,9 @@ public static String getTypeName(PropertyType type) {
584610
return type.getSimpleType();
585611
} else if (type.isPrimitiveType()) {
586612
return StringUtils.capitalize(type.getSimpleType());
613+
} else if (type.isUnion()) {
614+
List<PropertyType> nestedTypes = new ArrayList<>(type.getNested());
615+
return getUnionTypeName(nestedTypes);
587616
} else if (type.isList()) {
588617
return getTypeName(type.getNested().iterator().next()) + "List";
589618
} else if (type.isMap()) {

generator/src/main/java/io/apicurio/umg/pipe/java/AbstractUnionTypeJavaStage.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ protected void doProcess() {
1414
Set<PropertyModelWithOrigin> unionProperties = new HashSet<>();
1515
getState().getConceptIndex().findEntities("").stream().filter(entity -> entity.isLeaf()).forEach(entity -> {
1616
Collection<PropertyModelWithOrigin> allProperties = getState().getConceptIndex().getAllEntityProperties(entity);
17-
unionProperties.addAll(allProperties.stream().filter(property -> isUnion(property.getProperty())).collect(Collectors.toSet()));
17+
unionProperties.addAll(allProperties.stream().filter(property ->
18+
isUnion(property.getProperty()) || isUnionList(property.getProperty()) || isUnionMap(property.getProperty())
19+
).collect(Collectors.toSet()));
1820
});
1921

2022
unionProperties.forEach(property -> {

generator/src/main/java/io/apicurio/umg/pipe/java/ApplyUnionTypesStage.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import org.jboss.forge.roaster.model.source.JavaInterfaceSource;
44

55
import io.apicurio.umg.models.concept.PropertyModelWithOrigin;
6+
import io.apicurio.umg.models.concept.PropertyType;
67

78
/**
89
* A union type has already been created (as an interface like StringWidgetUnion) and now must be
@@ -25,7 +26,13 @@ protected void doProcess(PropertyModelWithOrigin property) {
2526
* @param property
2627
*/
2728
private void applyUnionType(PropertyModelWithOrigin property) {
28-
UnionPropertyType unionType = new UnionPropertyType(property.getProperty().getType());
29+
// Extract the actual union type: for simple unions it's the property type itself,
30+
// for union maps/lists it's the nested type
31+
PropertyType actualUnionType = property.getProperty().getType();
32+
if (isUnionList(property.getProperty()) || isUnionMap(property.getProperty())) {
33+
actualUnionType = property.getProperty().getType().getNested().iterator().next();
34+
}
35+
UnionPropertyType unionType = new UnionPropertyType(actualUnionType);
2936
String unionTypeFQN = getUnionTypeFQN(unionType.getName());
3037
JavaInterfaceSource unionTypeSource = getState().getJavaIndex().lookupInterface(unionTypeFQN);
3138

0 commit comments

Comments
 (0)