|
1 | 1 | /******************************************************************************** |
2 | | - * Copyright (c) 2019 EclipseSource and others. |
| 2 | + * Copyright (c) 2019-2022 EclipseSource and others. |
3 | 3 | * |
4 | 4 | * This program and the accompanying materials are made available under the |
5 | 5 | * terms of the Eclipse Public License v. 2.0 which is available at |
|
10 | 10 | ********************************************************************************/ |
11 | 11 | package org.eclipse.emfcloud.modelserver.jsonschema; |
12 | 12 |
|
| 13 | +import java.text.MessageFormat; |
13 | 14 | import java.util.Collection; |
14 | 15 | import java.util.List; |
| 16 | +import java.util.Map; |
15 | 17 | import java.util.Optional; |
16 | 18 | import java.util.stream.Collectors; |
17 | 19 |
|
@@ -126,20 +128,46 @@ protected JsonNode createJsonSchemaFromEStructuralFeature(final EStructuralFeatu |
126 | 128 | } |
127 | 129 |
|
128 | 130 | protected JsonNode createJsonSchema(final EReference eReference, final boolean featureAsAttribute) { |
| 131 | + EClass eReferenceType = eReference.getEReferenceType(); |
129 | 132 | final ObjectNode objectNode = Json.object(); |
130 | | - if (eReference.getUpperBound() > 1 || eReference.getUpperBound() == -1) { |
131 | | - objectNode.set("type", Json.text("array")); |
132 | | - JsonNode feature = Json.object(); |
133 | | - if (!featureAsAttribute) { |
134 | | - feature = createJsonSchemaFromEClass(eReference.getEReferenceType()); |
| 133 | + if (eReference.isMany()) { |
| 134 | + if (Map.Entry.class.equals(eReferenceType.getInstanceClass()) && eReference.isContainment()) { |
| 135 | + // eReference points to a Map$Entry EClass and should be translated as a Map Object |
| 136 | + EStructuralFeature keyFeature = eReferenceType.getEStructuralFeature("key"); |
| 137 | + if (!Optional.ofNullable(keyFeature).filter(EAttribute.class::isInstance).filter(f -> !f.isMany()) |
| 138 | + .isPresent()) { |
| 139 | + // there is no key attribute in the Map$Entry EClass. The metamodel is incorrect and cannot be supported. |
| 140 | + String msg = MessageFormat.format( |
| 141 | + "The EClass {0} has instance type name 'java.util.Map$Entry', but no 'key' monovalued attribute. It is incorrect, and schema cannot be generated for referencing property {1}::{2}.", |
| 142 | + eReferenceType.getName(), eReference.getEContainingClass().getName(), eReference.getName()); |
| 143 | + throw new IllegalArgumentException(msg); |
| 144 | + } |
| 145 | + EStructuralFeature valueFeature = eReferenceType.getEStructuralFeature("value"); |
| 146 | + if (!Optional.ofNullable(valueFeature).filter(f -> !f.isMany()).isPresent()) { |
| 147 | + // there is no value feature in the Map$Entry EClass. The metamodel is incorrect and cannot be supported. |
| 148 | + String msg = MessageFormat.format( |
| 149 | + "The EClass {0} has instance type name 'java.util.Map$Entry', but no 'value' monovalued property. It is incorrect, and schema cannot be generated for referencing property {1}::{2}.", |
| 150 | + eReferenceType.getName(), eReference.getEContainingClass().getName(), eReference.getName()); |
| 151 | + throw new IllegalArgumentException(msg); |
| 152 | + } |
| 153 | + objectNode.set("type", Json.text("object")); |
| 154 | + JsonNode valueType = createJsonSchemaFromEStructuralFeature(valueFeature); |
| 155 | + objectNode.set("additionalProperties", valueType); |
135 | 156 | } else { |
136 | | - feature = Json.object().set("$ref", |
137 | | - TextNode.valueOf("#/definitions/" + eReference.getEType().getName().trim().toLowerCase())); |
| 157 | + // eReference is multivalued and should be translated as an array |
| 158 | + objectNode.set("type", Json.text("array")); |
| 159 | + JsonNode feature = Json.object(); |
| 160 | + if (!featureAsAttribute) { |
| 161 | + feature = createJsonSchemaFromEClass(eReferenceType); |
| 162 | + } else { |
| 163 | + feature = Json.object().set("$ref", |
| 164 | + TextNode.valueOf("#/definitions/" + eReference.getEType().getName().trim().toLowerCase())); |
| 165 | + } |
| 166 | + objectNode.set("items", feature); |
138 | 167 | } |
139 | | - objectNode.set("items", feature); |
140 | 168 | return objectNode; |
141 | 169 | } |
142 | | - return createJsonSchema(eReference.getEReferenceType(), true); |
| 170 | + return createJsonSchema(eReferenceType, true); |
143 | 171 | } |
144 | 172 |
|
145 | 173 | protected ObjectNode createJsonSchema(final EAttribute eAttribute) { |
|
0 commit comments