Skip to content

Commit 09562de

Browse files
Merge pull request #124 from vojtechhabarta/swagger-annotations
Swagger annotations
2 parents e8ad284 + f76bc8d commit 09562de

File tree

16 files changed

+415
-27
lines changed

16 files changed

+415
-27
lines changed

typescript-generator-core/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@
6868
<version>${jersey.version}</version>
6969
<scope>test</scope>
7070
</dependency>
71+
<dependency>
72+
<groupId>io.swagger</groupId>
73+
<artifactId>swagger-annotations</artifactId>
74+
<version>1.5.10</version>
75+
<scope>test</scope>
76+
</dependency>
7177
</dependencies>
7278

7379
<build>

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/Settings.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public class Settings {
4242
public EnumMapping mapEnum; // default is EnumMapping.asUnion
4343
public ClassMapping mapClasses; // default is ClassMapping.asInterfaces
4444
public boolean disableTaggedUnions = false;
45+
public boolean ignoreSwaggerAnnotations = false;
4546
public boolean generateJaxrsApplicationInterface = false;
4647
public boolean generateJaxrsApplicationClient = false;
4748
public String restResponseType = null;

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/compiler/ModelCompiler.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -385,9 +385,10 @@ private static Map<String, Long> groupingByMethodName(List<JaxrsMethodModel> met
385385
private TsMethodModel processJaxrsMethod(SymbolTable symbolTable, String pathPrefix, Symbol responseSymbol, JaxrsMethodModel method, boolean createLongName, TsType optionsType, boolean implement) {
386386
final String path = Utils.joinPath(pathPrefix, method.getPath());
387387
final PathTemplate pathTemplate = PathTemplate.parse(path);
388-
final List<String> comments = new ArrayList<>();
389-
comments.add("HTTP " + method.getHttpMethod() + " /" + path);
390-
comments.add("Java method: " + method.getOriginClass().getName() + "." + method.getName());
388+
final List<String> comments = Utils.concat(method.getComments(), Arrays.asList(
389+
"HTTP " + method.getHttpMethod() + " /" + path,
390+
"Java method: " + method.getOriginClass().getName() + "." + method.getName()
391+
));
391392
final List<TsParameterModel> parameters = new ArrayList<>();
392393
// path params
393394
for (MethodParameterModel parameter : method.getPathParams()) {

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/parser/Javadoc.java

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
package cz.habarta.typescript.generator.parser;
33

44
import cz.habarta.typescript.generator.compiler.EnumMemberModel;
5+
import cz.habarta.typescript.generator.util.Utils;
56
import cz.habarta.typescript.generator.xmldoclet.Class;
67
import cz.habarta.typescript.generator.xmldoclet.Enum;
78
import cz.habarta.typescript.generator.xmldoclet.EnumConstant;
@@ -73,7 +74,7 @@ private BeanModel enrichBean(BeanModel bean, String beanComment, List<TagInfo> t
7374
final PropertyModel enrichedProperty = enrichProperty(property, dFields, dMethods);
7475
enrichedProperties.add(enrichedProperty);
7576
}
76-
return bean.withProperties(enrichedProperties).withComments(concat(getComments(beanComment, tags), bean.getComments()));
77+
return bean.withProperties(enrichedProperties).withComments(Utils.concat(getComments(beanComment, tags), bean.getComments()));
7778
}
7879

7980
private PropertyModel enrichProperty(PropertyModel property, List<Field> dFields, List<Method> dMethods) {
@@ -104,7 +105,7 @@ private <T> EnumModel<T> enrichEnum(EnumModel<T> enumModel) {
104105
}
105106
final String enumComment = dEnum != null ? dEnum.getComment() : null;
106107
final List<TagInfo> tags = dEnum != null ? dEnum.getTag() : null;
107-
return enumModel.withMembers(enrichedMembers).withComments(concat(getComments(enumComment, tags), enumModel.getComments()));
108+
return enumModel.withMembers(enrichedMembers).withComments(Utils.concat(getComments(enumComment, tags), enumModel.getComments()));
108109
}
109110

110111
private <T> EnumMemberModel<T> enrichEnumMember(EnumMemberModel<T> enumMember, Enum dEnum) {
@@ -216,13 +217,4 @@ private static List<String> splitMultiline(String comments) {
216217
return result;
217218
}
218219

219-
private static <T> List<T> concat(List<? extends T> list1, List<? extends T> list2) {
220-
if (list1 == null && list2 == null) {
221-
return null;
222-
}
223-
final List<T> result = new ArrayList<>();
224-
if (list1 != null) result.addAll(list1);
225-
if (list2 != null) result.addAll(list2);
226-
return result;
227-
}
228220
}

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/parser/JaxrsApplicationParser.java

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
package cz.habarta.typescript.generator.parser;
33

44
import cz.habarta.typescript.generator.JaxrsApplicationScanner;
5+
import cz.habarta.typescript.generator.Settings;
56
import cz.habarta.typescript.generator.util.Parameter;
67
import cz.habarta.typescript.generator.util.Predicate;
78
import cz.habarta.typescript.generator.util.Utils;
@@ -30,12 +31,14 @@
3031

3132
public class JaxrsApplicationParser {
3233

34+
private final Settings settings;
3335
private final Predicate<String> isClassNameExcluded;
3436
private final Set<String> defaultExcludes;
3537
private final JaxrsApplicationModel model;
3638

37-
public JaxrsApplicationParser(Predicate<String> isClassNameExcluded) {
38-
this.isClassNameExcluded = isClassNameExcluded;
39+
public JaxrsApplicationParser(Settings settings) {
40+
this.settings = settings;
41+
this.isClassNameExcluded = settings.getExcludeFilter();
3942
this.defaultExcludes = new LinkedHashSet<>(getDefaultExcludedClassNames());
4043
this.model = new JaxrsApplicationModel();
4144
}
@@ -122,6 +125,20 @@ private void parseResourceMethod(Result result, ResourceContext context, Class<?
122125
// JAX-RS specification - 3.3 Resource Methods
123126
final HttpMethod httpMethod = getHttpMethod(method);
124127
if (httpMethod != null) {
128+
// swagger
129+
final SwaggerOperation swaggerOperation = settings.ignoreSwaggerAnnotations
130+
? new SwaggerOperation()
131+
: Swagger.parseSwaggerAnnotations(method);
132+
if (swaggerOperation.possibleResponses != null) {
133+
for (SwaggerResponse response : swaggerOperation.possibleResponses) {
134+
if (response.responseType != null) {
135+
foundType(result, response.responseType, resourceClass, method.getName());
136+
}
137+
}
138+
}
139+
if (swaggerOperation.hidden) {
140+
return;
141+
}
125142
// path parameters
126143
final List<MethodParameterModel> pathParams = new ArrayList<>();
127144
final PathTemplate pathTemplate = PathTemplate.parse(context.path);
@@ -153,7 +170,12 @@ private void parseResourceMethod(Result result, ResourceContext context, Class<?
153170
if (returnType == void.class) {
154171
modelReturnType = returnType;
155172
} else if (returnType == Response.class) {
156-
modelReturnType = Object.class;
173+
if (swaggerOperation.responseType != null) {
174+
modelReturnType = swaggerOperation.responseType;
175+
foundType(result, modelReturnType, resourceClass, method.getName());
176+
} else {
177+
modelReturnType = Object.class;
178+
}
157179
} else if (genericReturnType instanceof ParameterizedType && returnType == GenericEntity.class) {
158180
final ParameterizedType parameterizedReturnType = (ParameterizedType) genericReturnType;
159181
modelReturnType = parameterizedReturnType.getActualTypeArguments()[0];
@@ -162,8 +184,10 @@ private void parseResourceMethod(Result result, ResourceContext context, Class<?
162184
modelReturnType = genericReturnType;
163185
foundType(result, modelReturnType, resourceClass, method.getName());
164186
}
187+
// comments
188+
final List<String> comments = Swagger.getOperationComments(swaggerOperation);
165189
// create method
166-
model.getMethods().add(new JaxrsMethodModel(resourceClass, method.getName(), modelReturnType, httpMethod.value(), context.path, pathParams, queryParams, entityParameter));
190+
model.getMethods().add(new JaxrsMethodModel(resourceClass, method.getName(), modelReturnType, httpMethod.value(), context.path, pathParams, queryParams, entityParameter, comments));
167191
}
168192
// JAX-RS specification - 3.4.1 Sub Resources
169193
if (pathAnnotation != null && httpMethod == null) {

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/parser/JaxrsMethodModel.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ public class JaxrsMethodModel extends MethodModel {
1414
private final MethodParameterModel entityParam;
1515

1616
public JaxrsMethodModel(Class<?> originClass, String name, Type returnType,
17-
String httpMethod, String path, List<MethodParameterModel> pathParams, List<MethodParameterModel> queryParams, MethodParameterModel entityParam) {
18-
super(originClass, name, null, returnType);
17+
String httpMethod, String path, List<MethodParameterModel> pathParams, List<MethodParameterModel> queryParams, MethodParameterModel entityParam,
18+
List<String> comments) {
19+
super(originClass, name, null, returnType, comments);
1920
this.httpMethod = httpMethod;
2021
this.path = path;
2122
this.pathParams = pathParams;

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/parser/MethodModel.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ public class MethodModel {
1212
private final String name;
1313
private final List<MethodParameterModel> parameters;
1414
private final Type returnType;
15+
private final List<String> comments;
1516

16-
public MethodModel(Class<?> originClass, String name, List<MethodParameterModel> parameters, Type returnType) {
17+
public MethodModel(Class<?> originClass, String name, List<MethodParameterModel> parameters, Type returnType, List<String> comments) {
1718
this.originClass = originClass;
1819
this.name = name;
1920
this.parameters = parameters != null ? parameters : Collections.<MethodParameterModel>emptyList();
2021
this.returnType = returnType;
22+
this.comments = comments;
2123
}
2224

2325
public Class<?> getOriginClass() {
@@ -36,4 +38,8 @@ public Type getReturnType() {
3638
return returnType;
3739
}
3840

41+
public List<String> getComments() {
42+
return comments;
43+
}
44+
3945
}

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/parser/ModelParser.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,14 @@ public Model parseModel(Type type) {
3030
public Model parseModel(List<SourceType<Type>> types) {
3131
typeQueue.addAll(types);
3232
final Model model = parseQueue();
33-
final Model modelWithJavadoc = javadoc.enrichModel(model);
33+
final Model modelWithSwaggerDoc = Swagger.enrichModel(model);
34+
final Model modelWithJavadoc = javadoc.enrichModel(modelWithSwaggerDoc);
3435
return modelWithJavadoc;
3536
}
3637

3738
private Model parseQueue() {
38-
final JaxrsApplicationParser jaxrsApplicationParser = new JaxrsApplicationParser(settings.getExcludeFilter());
39-
final Set<Type> parsedTypes = new LinkedHashSet<>();
39+
final JaxrsApplicationParser jaxrsApplicationParser = new JaxrsApplicationParser(settings);
40+
final Collection<Type> parsedTypes = new ArrayList<>(); // do not use hashcodes, we can only count on `equals` since we use custom `ParameterizedType`s
4041
final List<BeanModel> beans = new ArrayList<>();
4142
final List<EnumModel<?>> enums = new ArrayList<>();
4243
SourceType<? extends Type> sourceType;
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
2+
package cz.habarta.typescript.generator.parser;
3+
4+
import cz.habarta.typescript.generator.util.Utils;
5+
import java.lang.reflect.AnnotatedElement;
6+
import java.lang.reflect.Method;
7+
import java.util.*;
8+
9+
10+
public class Swagger {
11+
12+
static SwaggerOperation parseSwaggerAnnotations(Method method) {
13+
final SwaggerOperation swaggerOperation = new SwaggerOperation();
14+
// @ApiOperation
15+
{
16+
final Object apiOperation = Utils.getAnnotation(method, "io.swagger.annotations.ApiOperation");
17+
if (apiOperation != null) {
18+
final Class<?> response = Utils.getAnnotationElementValue(apiOperation, "response", Class.class);
19+
final String responseContainer = Utils.getAnnotationElementValue(apiOperation, "responseContainer", String.class);
20+
if (responseContainer == null || responseContainer.isEmpty()) {
21+
swaggerOperation.responseType = response;
22+
} else {
23+
switch (responseContainer) {
24+
case "List":
25+
swaggerOperation.responseType = Utils.createParameterizedType(List.class, response);
26+
break;
27+
case "Set":
28+
swaggerOperation.responseType = Utils.createParameterizedType(Set.class, response);
29+
break;
30+
case "Map":
31+
swaggerOperation.responseType = Utils.createParameterizedType(Map.class, String.class, response);
32+
break;
33+
}
34+
}
35+
swaggerOperation.hidden = Utils.getAnnotationElementValue(apiOperation, "hidden", Boolean.class);
36+
swaggerOperation.comment = Utils.getAnnotationElementValue(apiOperation, "value", String.class);
37+
swaggerOperation.comment = swaggerOperation.comment.isEmpty() ? null : swaggerOperation.comment;
38+
}
39+
}
40+
// @ApiResponses
41+
{
42+
final Object[] apiResponses = Utils.getAnnotationElementValue(method, "io.swagger.annotations.ApiResponses", "value", Object[].class);
43+
if (apiResponses != null) {
44+
swaggerOperation.possibleResponses = new ArrayList<>();
45+
for (Object apiResponse : apiResponses) {
46+
final SwaggerResponse response = new SwaggerResponse();
47+
response.code = Utils.getAnnotationElementValue(apiResponse, "code", Integer.class);
48+
response.comment = Utils.getAnnotationElementValue(apiResponse, "message", String.class);
49+
response.responseType = Utils.getAnnotationElementValue(apiResponse, "response", Class.class);
50+
swaggerOperation.possibleResponses.add(response);
51+
}
52+
}
53+
}
54+
return swaggerOperation;
55+
}
56+
57+
static List<String> getOperationComments(SwaggerOperation operation) {
58+
final List<String> comments = new ArrayList<>();
59+
if (operation.comment != null) {
60+
comments.add(operation.comment);
61+
}
62+
if (operation.possibleResponses != null) {
63+
for (SwaggerResponse response : operation.possibleResponses) {
64+
comments.add(String.format("Response code %s - %s", response.code, response.comment));
65+
}
66+
}
67+
return comments.isEmpty() ? null : comments;
68+
}
69+
70+
public static Model enrichModel(Model model) {
71+
final List<BeanModel> dBeans = new ArrayList<>();
72+
for (BeanModel bean : model.getBeans()) {
73+
final BeanModel dBean = enrichBean(bean);
74+
dBeans.add(dBean);
75+
}
76+
return new Model(dBeans, model.getEnums(), model.getJaxrsApplication());
77+
}
78+
79+
private static BeanModel enrichBean(BeanModel bean) {
80+
final List<PropertyModel> enrichedProperties = new ArrayList<>();
81+
for (PropertyModel property : bean.getProperties()) {
82+
final PropertyModel enrichedProperty = enrichProperty(property);
83+
enrichedProperties.add(enrichedProperty);
84+
}
85+
final String comment = Utils.getAnnotationElementValue(bean.getOrigin(), "io.swagger.annotations.ApiModel", "description", String.class);
86+
final List<String> comments = comment != null && !comment.isEmpty() ? Arrays.asList(comment) : null;
87+
return bean.withProperties(enrichedProperties).withComments(Utils.concat(comments, bean.getComments()));
88+
}
89+
90+
private static PropertyModel enrichProperty(PropertyModel property) {
91+
if (property.getOriginalMember() instanceof AnnotatedElement) {
92+
final AnnotatedElement annotatedElement = (AnnotatedElement) property.getOriginalMember();
93+
final String comment = Utils.getAnnotationElementValue(annotatedElement, "io.swagger.annotations.ApiModelProperty", "value", String.class);
94+
final List<String> comments = comment != null && !comment.isEmpty() ? Arrays.asList(comment) : null;
95+
return property.withComments(Utils.concat(comments, property.getComments()));
96+
} else {
97+
return property;
98+
}
99+
}
100+
101+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
package cz.habarta.typescript.generator.parser;
3+
4+
import java.lang.reflect.Type;
5+
import java.util.List;
6+
7+
8+
public class SwaggerOperation {
9+
public Type responseType;
10+
public List<SwaggerResponse> possibleResponses;
11+
public boolean hidden;
12+
public String comment;
13+
}

0 commit comments

Comments
 (0)