Skip to content

Commit 1d03f0c

Browse files
authored
Merge pull request #2890 from swagger-api/feature/2621-ComposedProperty
#2621 Basic implementation of 'allOf' for properties.
2 parents 437ac07 + c738a7c commit 1d03f0c

File tree

3 files changed

+200
-1
lines changed

3 files changed

+200
-1
lines changed

modules/swagger-core/src/main/java/io/swagger/util/PropertyDeserializer.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import com.fasterxml.jackson.databind.node.TextNode;
1818
import io.swagger.models.Xml;
1919
import io.swagger.models.properties.ArrayProperty;
20+
import io.swagger.models.properties.ComposedProperty;
2021
import io.swagger.models.properties.MapProperty;
2122
import io.swagger.models.properties.ObjectProperty;
2223
import io.swagger.models.properties.Property;
@@ -219,7 +220,7 @@ Property propertyFromNode(JsonNode node) {
219220
return refProperty;
220221
}
221222

222-
if (ObjectProperty.isType(type) || node.get("properties") != null) {
223+
if (ObjectProperty.isType(type) || node.get("properties") != null || node.get("allOf") != null) {
223224
JsonNode example = getDetailNode(node, PropertyBuilder.PropertyId.EXAMPLE);
224225
detailNode = node.get("additionalProperties");
225226
if (detailNode != null && detailNode.getNodeType().equals(JsonNodeType.OBJECT)) {
@@ -237,6 +238,7 @@ Property propertyFromNode(JsonNode node) {
237238
return mapProperty;
238239
}
239240
} else {
241+
JsonNode allOfNode = node.get("allOf");
240242
detailNode = node.get("properties");
241243
String detailNodeType = null;
242244
Map<String, Property> properties = new LinkedHashMap<String, Property>();
@@ -256,6 +258,20 @@ Property propertyFromNode(JsonNode node) {
256258
}
257259
}
258260
}
261+
} else if (allOfNode != null) {
262+
ComposedProperty cp = new ComposedProperty().description(description).title(title);
263+
cp.setExample(example);
264+
cp.setDescription(description);
265+
cp.setVendorExtensions(getVendorExtensions(node));
266+
267+
List<Property> allOf = new ArrayList<Property>();
268+
for (JsonNode innerNode : allOfNode) {
269+
allOf.add(propertyFromNode(innerNode));
270+
}
271+
272+
cp.setAllOf(allOf);
273+
274+
return cp;
259275
}
260276

261277
if("array".equals(detailNodeType)) {
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package io.swagger;
2+
3+
import static org.testng.Assert.assertEquals;
4+
import static org.testng.Assert.assertNotNull;
5+
import static org.testng.Assert.assertTrue;
6+
7+
import java.io.IOException;
8+
9+
import org.testng.annotations.Test;
10+
11+
import io.swagger.models.ModelImpl;
12+
import io.swagger.models.properties.AbstractNumericProperty;
13+
import io.swagger.models.properties.ComposedProperty;
14+
import io.swagger.models.properties.ObjectProperty;
15+
import io.swagger.models.properties.Property;
16+
import io.swagger.models.properties.StringProperty;
17+
import io.swagger.util.Json;
18+
19+
public class ComposedPropertyTest {
20+
21+
@Test(description = "convert a model with object properties")
22+
public void readModelWithObjectProperty() throws IOException {
23+
String json = "{\n" +
24+
" \"properties\":{\n" +
25+
" \"id\":{\n" +
26+
" \"type\":\"string\"\n" +
27+
" },\n" +
28+
" \"someObject\":{\n" +
29+
" \"type\":\"object\",\n" +
30+
" \"x-foo\": \"vendor x\",\n" +
31+
" \"allOf\":[\n" +
32+
" {\n" +
33+
" \"type\":\"object\",\n" +
34+
" \"properties\":{\n" +
35+
" \"innerId\":{\n" +
36+
" \"type\":\"string\"\n" +
37+
" }\n" +
38+
" }\n" +
39+
" },{\n" +
40+
" \"type\":\"object\",\n" +
41+
" \"properties\":{\n" +
42+
" \"innerLength\":{\n" +
43+
" \"type\":\"number\"\n" +
44+
" }\n" +
45+
" }\n" +
46+
" }\n" +
47+
" ]\n" +
48+
" }\n" +
49+
" }\n" +
50+
"}";
51+
52+
ModelImpl model = Json.mapper().readValue(json, ModelImpl.class);
53+
54+
Property p = model.getProperties().get("someObject");
55+
assertTrue(p instanceof ComposedProperty);
56+
57+
ComposedProperty cp = (ComposedProperty) p;
58+
59+
Property op0 = cp.getAllOf().get(0);
60+
Property op1 = cp.getAllOf().get(1);
61+
62+
assertTrue(op0 instanceof ObjectProperty);
63+
assertTrue(op1 instanceof ObjectProperty);
64+
65+
Property sp = ((ObjectProperty) op0).getProperties().get("innerId");
66+
Property np = ((ObjectProperty) op1).getProperties().get("innerLength");
67+
68+
assertTrue(sp instanceof StringProperty);
69+
assertTrue(np instanceof AbstractNumericProperty);
70+
71+
assertTrue(cp.getVendorExtensions() != null);
72+
assertNotNull(cp.getVendorExtensions().get("x-foo"));
73+
assertEquals(cp.getVendorExtensions().get("x-foo"), "vendor x");
74+
}
75+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package io.swagger.models.properties;
2+
3+
import java.util.LinkedList;
4+
import java.util.List;
5+
import java.util.Objects;
6+
7+
import io.swagger.models.Xml;
8+
9+
public class ComposedProperty extends AbstractProperty implements Property {
10+
11+
public static final String TYPE = "object";
12+
private List<Property> allOf = new LinkedList<Property>();
13+
14+
public ComposedProperty() {
15+
super.type = TYPE;
16+
}
17+
18+
public ComposedProperty vendorExtension(String key, Object obj) {
19+
this.setVendorExtension(key, obj);
20+
return this;
21+
}
22+
23+
public ComposedProperty access(String access) {
24+
this.setAccess(access);
25+
return this;
26+
}
27+
28+
@Override
29+
public ComposedProperty description(String description) {
30+
this.setDescription(description);
31+
return this;
32+
}
33+
34+
public ComposedProperty name(String name) {
35+
this.setName(name);
36+
return this;
37+
}
38+
39+
@Override
40+
public ComposedProperty title(String title) {
41+
this.setTitle(title);
42+
return this;
43+
}
44+
45+
public ComposedProperty _default(String _default) {
46+
this.setDefault(_default);
47+
return this;
48+
}
49+
50+
public ComposedProperty readOnly(boolean readOnly) {
51+
this.setReadOnly(readOnly);
52+
return this;
53+
}
54+
55+
public ComposedProperty required(boolean required) {
56+
this.setRequired(required);
57+
return this;
58+
}
59+
60+
public List<Property> getAllOf() {
61+
return allOf;
62+
}
63+
64+
public void setAllOf(List<Property> allOf) {
65+
this.allOf = allOf;
66+
}
67+
68+
public ComposedProperty allOf(List<Property> allOf) {
69+
this.allOf = allOf;
70+
return this;
71+
}
72+
73+
@Override
74+
public ComposedProperty readOnly() {
75+
this.setReadOnly(Boolean.TRUE);
76+
return this;
77+
}
78+
79+
public ComposedProperty xml(Xml xml) {
80+
this.setXml(xml);
81+
return this;
82+
}
83+
84+
public ComposedProperty example(Object example) {
85+
this.setExample(example);
86+
return this;
87+
}
88+
89+
@Override
90+
public boolean equals(Object o) {
91+
if (!(o instanceof ComposedProperty)) {
92+
return false;
93+
}
94+
if (!super.equals(o)) {
95+
return false;
96+
}
97+
98+
return Objects.equals(allOf, ((ComposedProperty) o).allOf);
99+
}
100+
101+
@Override
102+
public int hashCode() {
103+
int result = super.hashCode();
104+
result = 31 * result + (allOf != null ? allOf.hashCode() : 0);
105+
106+
return result;
107+
}
108+
}

0 commit comments

Comments
 (0)