Skip to content

Commit dacf840

Browse files
committed
Merge branch 'develop_2.0' into relative-refs
2 parents eb6100b + c4e00f4 commit dacf840

File tree

15 files changed

+444
-125
lines changed

15 files changed

+444
-125
lines changed

modules/swagger-annotations/src/main/java/io/swagger/annotations/ApiParam.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,9 @@
8787
* Specifies whether the parameter can accept multiple values by having multiple occurrences.
8888
*/
8989
boolean allowMultiple() default false;
90-
}
90+
91+
/**
92+
* Hides the parameter from the list of parameters.
93+
*/
94+
boolean hidden() default false;
95+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package io.swagger.converter;
2+
3+
import java.lang.reflect.Type;
4+
import java.util.Collections;
5+
import java.util.Date;
6+
import java.util.HashSet;
7+
import java.util.Set;
8+
9+
public enum PrimitiveType {
10+
11+
INT(Integer.class, "int", "integer"),
12+
LONG(Long.class, "long"),
13+
FLOAT(Float.class, "float"),
14+
DOUBLE(Double.class, "double"),
15+
STRING(String.class, "string"),
16+
BYTE(Byte.class, "byte"),
17+
BOOLEAN(Boolean.class, "boolean"),
18+
URI(java.net.URI.class, "uri"),
19+
URL(java.net.URL.class, "url"),
20+
UUID(java.util.UUID.class, "uuid"),
21+
DATE_TIME(Date.class, "dateTime");
22+
23+
private final Type type;
24+
private final Set<String> names;
25+
26+
private PrimitiveType(Type type, String name, String ... aliases) {
27+
this.type = type;
28+
final Set<String> tmpNames = new HashSet<String>();
29+
tmpNames.add(name.toUpperCase());
30+
for (String item : aliases) {
31+
tmpNames.add(item.toUpperCase());
32+
}
33+
this.names = Collections.unmodifiableSet(tmpNames);
34+
}
35+
36+
public static PrimitiveType fromName(String name) {
37+
if (name != null) {
38+
final String key = name.toUpperCase();
39+
for (PrimitiveType item : values()) {
40+
if (item.names.contains(key)) {
41+
return item;
42+
}
43+
}
44+
}
45+
return null;
46+
}
47+
48+
public Type getType() {
49+
return type;
50+
}
51+
}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package io.swagger.jackson;
2+
3+
import io.swagger.models.Xml;
4+
import io.swagger.models.properties.ArrayProperty;
5+
import io.swagger.models.properties.MapProperty;
6+
import io.swagger.models.properties.ObjectProperty;
7+
import io.swagger.models.properties.Property;
8+
import io.swagger.models.properties.RefProperty;
9+
10+
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
11+
12+
import org.apache.commons.lang3.StringUtils;
13+
14+
import javax.xml.bind.annotation.XmlAttribute;
15+
import javax.xml.bind.annotation.XmlElement;
16+
import javax.xml.bind.annotation.XmlElementWrapper;
17+
18+
/**
19+
* The <code>JAXBAnnotationsHelper</code> class defines helper methods for
20+
* applying JAXB annotations to property definitions.
21+
*/
22+
class JAXBAnnotationsHelper {
23+
private static final String JAXB_DEFAULT = "##default";
24+
25+
private JAXBAnnotationsHelper() {
26+
}
27+
28+
/**
29+
* Applies annotations to property's {@link Xml} definition.
30+
* @param member annotations provider
31+
* @param property property instance to be updated
32+
*/
33+
public static void apply(AnnotatedMember member, Property property) {
34+
if (member.hasAnnotation(XmlElementWrapper.class) || member.hasAnnotation(XmlElement.class)) {
35+
applyElement(member, property);
36+
} else if (member.hasAnnotation(XmlAttribute.class) && isAttributeAllowed(property)) {
37+
applyAttribute(member, property);
38+
}
39+
}
40+
41+
/**
42+
* Puts definitions for XML element.
43+
* @param member annotations provider
44+
* @param property property instance to be updated
45+
*/
46+
private static void applyElement(AnnotatedMember member, Property property) {
47+
final XmlElementWrapper wrapper = member.getAnnotation(XmlElementWrapper.class);
48+
if (wrapper != null) {
49+
final Xml xml = getXml(property);
50+
xml.setWrapped(true);
51+
setName(wrapper.namespace(), wrapper.name(), property);
52+
}
53+
final XmlElement element = member.getAnnotation(XmlElement.class);
54+
if (element != null) {
55+
setName(element.namespace(), element.name(), property);
56+
}
57+
}
58+
59+
60+
/**
61+
* Puts definitions for XML attribute.
62+
* @param member annotations provider
63+
* @param property property instance to be updated
64+
*/
65+
private static void applyAttribute(AnnotatedMember member, Property property) {
66+
final XmlAttribute attribute = member.getAnnotation(XmlAttribute.class);
67+
if (attribute != null) {
68+
final Xml xml = getXml(property);
69+
xml.setAttribute(true);
70+
setName(attribute.namespace(), attribute.name(), property);
71+
}
72+
}
73+
74+
private static Xml getXml(Property property) {
75+
final Xml existing = property.getXml();
76+
if (existing != null) {
77+
return existing;
78+
}
79+
final Xml created = new Xml();
80+
property.setXml(created);
81+
return created;
82+
}
83+
84+
/**
85+
* Puts name space and name for XML node or attribute.
86+
* @param ns name space
87+
* @param name name
88+
* @param property property instance to be updated
89+
* @return <code>true</code> if name space and name have been set
90+
*/
91+
private static boolean setName(String ns, String name, Property property) {
92+
boolean apply = false;
93+
final String cleanName = StringUtils.trimToNull(name);
94+
final String useName;
95+
if (!isEmpty(cleanName) && !cleanName.equals(property.getName())) {
96+
useName = cleanName;
97+
apply = true;
98+
} else {
99+
useName = null;
100+
}
101+
final String cleanNS = StringUtils.trimToNull(ns);
102+
final String useNS;
103+
if (!isEmpty(cleanNS)) {
104+
useNS = cleanNS;
105+
apply = true;
106+
} else {
107+
useNS = null;
108+
}
109+
// Set everything or nothing
110+
if (apply) {
111+
getXml(property).name(useName).namespace(useNS);
112+
}
113+
return apply;
114+
}
115+
116+
/**
117+
* Checks whether the passed property can be represented as node attribute.
118+
* @param property property instance to be checked
119+
* @return <code>true</code> if the passed property can be represented as
120+
* node attribute
121+
*/
122+
private static boolean isAttributeAllowed(Property property) {
123+
for (Class<?> item : new Class<?>[] { ArrayProperty.class, MapProperty.class, ObjectProperty.class,
124+
RefProperty.class }) {
125+
if (item.isInstance(property)) {
126+
return false;
127+
}
128+
}
129+
return true;
130+
}
131+
132+
private static boolean isEmpty(String name) {
133+
return StringUtils.isEmpty(name) || JAXB_DEFAULT.equals(name);
134+
}
135+
}

modules/swagger-core/src/main/java/io/swagger/jackson/ModelResolver.java

Lines changed: 4 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
1313
import com.fasterxml.jackson.databind.jsontype.NamedType;
1414
import com.fasterxml.jackson.databind.type.TypeFactory;
15+
1516
import io.swagger.annotations.ApiModel;
1617
import io.swagger.annotations.ApiModelProperty;
1718
import io.swagger.converter.ModelConverter;
@@ -27,6 +28,7 @@
2728
import io.swagger.models.properties.Property;
2829
import io.swagger.models.properties.RefProperty;
2930
import io.swagger.models.properties.StringProperty;
31+
3032
import org.apache.commons.lang3.StringUtils;
3133
import org.slf4j.Logger;
3234
import org.slf4j.LoggerFactory;
@@ -36,10 +38,8 @@
3638
import javax.validation.constraints.Max;
3739
import javax.validation.constraints.Min;
3840
import javax.validation.constraints.Size;
39-
import javax.xml.bind.annotation.XmlAttribute;
40-
import javax.xml.bind.annotation.XmlElement;
41-
import javax.xml.bind.annotation.XmlElementWrapper;
4241
import javax.xml.bind.annotation.XmlRootElement;
42+
4343
import java.lang.annotation.Annotation;
4444
import java.lang.reflect.Type;
4545
import java.util.ArrayList;
@@ -407,58 +407,7 @@ public Model resolve(JavaType type, ModelConverterContext context, Iterator<Mode
407407
}
408408
}
409409

410-
if (property != null) {
411-
// check for XML annotations
412-
XmlElementWrapper wrapper = member.getAnnotation(XmlElementWrapper.class);
413-
414-
if (wrapper != null) {
415-
Xml xml = new Xml();
416-
xml.setWrapped(true);
417-
418-
if (wrapper.name() != null) {
419-
if ("##default".equals(wrapper.name())) {
420-
xml.setName(propName);
421-
} else if (!"".equals(wrapper.name())) {
422-
xml.setName(wrapper.name());
423-
}
424-
}
425-
if (wrapper.namespace() != null && !"".equals(wrapper.namespace()) && !"##default".equals(wrapper.namespace())) {
426-
xml.setNamespace(wrapper.namespace());
427-
}
428-
429-
property.setXml(xml);
430-
}
431-
432-
XmlElement element = member.getAnnotation(XmlElement.class);
433-
if (element != null) {
434-
if (!element.name().isEmpty()) {
435-
// don't set Xml object if name is same
436-
if (!element.name().equals(propName) && !"##default".equals(element.name())) {
437-
Xml xml = property.getXml();
438-
if (xml == null) {
439-
xml = new Xml();
440-
property.setXml(xml);
441-
}
442-
xml.setName(element.name());
443-
}
444-
}
445-
}
446-
XmlAttribute attr = member.getAnnotation(XmlAttribute.class);
447-
if (attr != null) {
448-
if (!"".equals(attr.name())) {
449-
// don't set Xml object if name is same
450-
if (!attr.name().equals(propName) && !"##default".equals(attr.name())) {
451-
Xml xml = property.getXml();
452-
if (xml == null) {
453-
xml = new Xml();
454-
property.setXml(xml);
455-
}
456-
xml.setName(attr.name());
457-
}
458-
}
459-
}
460-
461-
}
410+
JAXBAnnotationsHelper.apply(member, property);
462411
applyBeanValidatorAnnotations(property, annotations);
463412
props.add(property);
464413
}
Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,28 @@
11
import io.swagger.converter.ModelConverters
2-
import io.swagger.util.Json
2+
import io.swagger.models.properties.IntegerProperty
3+
import io.swagger.models.properties.StringProperty
34
import models._
5+
46
import org.junit.runner.RunWith
57
import org.scalatest.{FlatSpec, Matchers}
68
import org.scalatest.junit.JUnitRunner
79

10+
import scala.collection.JavaConverters.mapAsScalaMapConverter
11+
812
@RunWith(classOf[JUnitRunner])
913
class JaxBDefaultValueTest extends FlatSpec with Matchers {
1014
it should "convert a model with Guava optionals" in {
1115
val schemas = ModelConverters.getInstance().read(classOf[ModelWithJaxBDefaultValues])
12-
Json.prettyPrint(schemas)
16+
val model = schemas.get("ModelWithJaxBDefaultValues")
17+
for ((name, property) <- model.getProperties.asScala) {
18+
name match {
19+
case "name" =>
20+
property.asInstanceOf[StringProperty].getDefault should be ("Tony")
21+
case "age" =>
22+
property.asInstanceOf[IntegerProperty].getDefault should be (100)
23+
case _ =>
24+
fail(s"""Property "${name}" was not expected""")
25+
}
26+
}
1327
}
1428
}

modules/swagger-core/src/test/scala/XmlModelTest.scala

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import org.scalatest.{FlatSpec, Matchers}
99
import org.scalatest.junit.JUnitRunner
1010

1111
import scala.beans.BeanProperty
12+
import scala.collection.JavaConverters.mapAsScalaMapConverter
1213

1314
@RunWith(classOf[JUnitRunner])
1415
class XmlModelTest extends FlatSpec with Matchers {
@@ -26,7 +27,7 @@ class XmlModelTest extends FlatSpec with Matchers {
2627
property should not be (null)
2728
xml = property.getXml()
2829
xml.getWrapped should equal(true)
29-
xml.getName() should be("children")
30+
xml.getName() should be (null)
3031
}
3132

3233
it should "not create an xml object" in {
@@ -46,13 +47,42 @@ class XmlModelTest extends FlatSpec with Matchers {
4647
val schemas = ModelConverters.getInstance().readAll(classOf[Issue534])
4748
schemas.get("Issue534").getProperties().size() should be(1)
4849
}
49-
}
5050

51-
@RunWith(classOf[JUnitRunner])
52-
class XmlModelTest2 extends FlatSpec with Matchers {
53-
it should "honor xml annotations" in {
54-
val schemas = ModelConverters.getInstance().readAll(classOf[Message])
55-
Json.prettyPrint(schemas)
51+
it should "process a model with JAXB annotations" in {
52+
val schemas = ModelConverters.getInstance().readAll(classOf[ModelWithJAXBAnnotations])
53+
schemas.size should be (1)
54+
val model = schemas.get("ModelWithJAXBAnnotations")
55+
model should not be (null)
56+
model.isInstanceOf[ModelImpl] should be (true)
57+
var rootXml = model.asInstanceOf[ModelImpl].getXml()
58+
rootXml should not be (null)
59+
rootXml.getName() should equal("rootName")
60+
for ((name, property) <- model.getProperties.asScala) {
61+
name match {
62+
case "id" =>
63+
var xml = property.getXml
64+
xml should not be (null)
65+
xml.getName should be (null)
66+
xml.getAttribute should equal (true)
67+
xml.getWrapped should be (null)
68+
case "name" =>
69+
var xml = property.getXml
70+
xml should not be (null)
71+
xml.getName should be ("renamed")
72+
xml.getAttribute should be (null)
73+
xml.getWrapped should be (null)
74+
case "list" | "forcedElement" =>
75+
property.getXml should be (null)
76+
case "wrappedList" =>
77+
var xml = property.getXml
78+
xml should not be (null)
79+
xml.getName should be (null)
80+
xml.getAttribute should be (null)
81+
xml.getWrapped should equal (true)
82+
case _ =>
83+
fail(s"""Property "${name}" was not expected""")
84+
}
85+
}
5686
}
5787
}
5888

@@ -65,4 +95,4 @@ class Monster {
6595
@XmlElement(name = "children")
6696
@BeanProperty
6797
var children: java.util.List[String] = _
68-
}
98+
}

0 commit comments

Comments
 (0)