Skip to content

Commit 1bfe6c4

Browse files
committed
Initial swagger generation
1 parent dd65382 commit 1bfe6c4

File tree

13 files changed

+620
-29
lines changed

13 files changed

+620
-29
lines changed

pom.xml

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
34
<modelVersion>4.0.0</modelVersion>
45

56
<groupId>io.dinject</groupId>
@@ -17,6 +18,10 @@
1718
<tag>HEAD</tag>
1819
</scm>
1920

21+
<properties>
22+
<swagger.version>2.0.8</swagger.version>
23+
</properties>
24+
2025
<dependencies>
2126

2227
<dependency>
@@ -31,6 +36,26 @@
3136
<version>1.6</version>
3237
</dependency>
3338

39+
<dependency>
40+
<groupId>com.fasterxml.jackson.core</groupId>
41+
<artifactId>jackson-databind</artifactId>
42+
<version>2.9.8</version>
43+
</dependency>
44+
45+
<dependency>
46+
<groupId>io.swagger.core.v3</groupId>
47+
<artifactId>swagger-models</artifactId>
48+
<version>${swagger.version}</version>
49+
</dependency>
50+
51+
<dependency>
52+
<groupId>io.swagger.core.v3</groupId>
53+
<artifactId>swagger-annotations</artifactId>
54+
<version>${swagger.version}</version>
55+
</dependency>
56+
57+
<!-- test dependencies -->
58+
3459
<dependency>
3560
<groupId>org.avaje.composite</groupId>
3661
<artifactId>junit</artifactId>

src/main/java/io/dinject/javalin/generator/Constants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ class Constants {
66

77
static final String JAVALIN_ROLES = "io.javalin.security.SecurityUtil.roles";
88

9+
static final String OPENAPIDEFINITION = "io.swagger.v3.oas.annotations.OpenAPIDefinition";
10+
911
static final String SINGLETON = "javax.inject.Singleton";
1012
static final String GENERATED = "javax.annotation.Generated";
1113
static final String API_BUILDER = "io.javalin.apibuilder.ApiBuilder";

src/main/java/io/dinject/javalin/generator/ControllerReader.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@ class ControllerReader {
3030

3131
private final Set<String> importTypes = new TreeSet<>();
3232

33+
// private final String docComment;
34+
3335
ControllerReader(TypeElement beanType, ProcessingContext ctx) {
3436
this.beanType = beanType;
3537
this.ctx = ctx;
38+
// this.docComment = ctx.getDocComment(beanType);
3639
this.roles = Util.findRoles(beanType);
3740
if (ctx.isGeneratedAvailable()) {
3841
importTypes.add(Constants.GENERATED);
@@ -47,6 +50,10 @@ TypeElement getBeanType() {
4750
return beanType;
4851
}
4952

53+
// String getDocComment() {
54+
// return docComment;
55+
// }
56+
5057
void read() {
5158
if (!roles.isEmpty()) {
5259
addStaticImportType(JAVALIN_ROLES);

src/main/java/io/dinject/javalin/generator/ControllerRouteWriter.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ class ControllerRouteWriter {
1111

1212
private final ProcessingContext ctx;
1313

14-
private Append writer;
15-
private String originName;
16-
private String shortName;
17-
private String packageName;
14+
private final String originName;
15+
private final String shortName;
1816
private final String fullName;
17+
private String packageName;
18+
private Append writer;
1919

2020
ControllerRouteWriter(ControllerReader reader, ProcessingContext ctx) {
2121
this.reader = reader;
@@ -29,7 +29,7 @@ class ControllerRouteWriter {
2929

3030
void write() throws IOException {
3131

32-
this.writer = new Append(createFileWriter());
32+
writer = new Append(createFileWriter());
3333
writePackage();
3434
writeImports();
3535
writeClassStart();
@@ -46,6 +46,7 @@ private void writeAddRoutes() {
4646

4747
for (MethodReader method : reader.getMethods()) {
4848
method.addRoute(writer);
49+
method.addMeta(ctx);
4950
}
5051

5152
writer.append(" }").eol().eol();
@@ -90,7 +91,6 @@ private void writePackage() {
9091
}
9192
}
9293

93-
9494
private Writer createFileWriter() throws IOException {
9595

9696
int dp = originName.lastIndexOf('.');

src/main/java/io/dinject/javalin/generator/ElementReader.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
import io.dinject.controller.FormParam;
88
import io.dinject.controller.Header;
99
import io.dinject.controller.QueryParam;
10+
import io.dinject.javalin.generator.javadoc.Javadoc;
11+
import io.swagger.v3.oas.models.Operation;
12+
import io.swagger.v3.oas.models.media.Schema;
13+
import io.swagger.v3.oas.models.parameters.Parameter;
1014

1115
import javax.lang.model.element.Element;
1216
import javax.lang.model.element.TypeElement;
@@ -24,7 +28,7 @@ class ElementReader {
2428
private ParamType paramType;
2529
private boolean impliedParamType;
2630
private String paramDefault;
27-
private String docComment;
31+
// private String docComment;
2832

2933
ElementReader(Element element, ProcessingContext ctx, ParamType defaultType, boolean formMarker) {
3034
this.ctx = ctx;
@@ -35,7 +39,7 @@ class ElementReader {
3539
this.varName = element.getSimpleName().toString();
3640
this.snakeName = Util.snakeCase(varName);
3741
this.paramName = varName;
38-
this.docComment = ctx.docComment(element);
42+
// this.docComment = ctx.getDocComment(element);
3943

4044
readAnnotations(element, defaultType);
4145
}
@@ -138,6 +142,22 @@ void writeParamName(Append writer) {
138142
}
139143
}
140144

145+
void addMeta(Javadoc javadoc, Operation operation) {
146+
if (!isJavalinContext()) {
147+
148+
Parameter param = new Parameter();
149+
param.setName(varName);
150+
param.setDescription(javadoc.getParams().get(paramName));
151+
param.setIn(paramType.getType());
152+
153+
Schema schema = new Schema();
154+
schema.setType("string");
155+
param.setSchema(schema);
156+
157+
operation.addParametersItem(param);
158+
}
159+
}
160+
141161
void writeCtxGet(Append writer, PathSegments segments) {
142162

143163
if (isJavalinContext()) {
@@ -162,6 +182,7 @@ private boolean setValue(Append writer, PathSegments segments, String shortType)
162182
if (formMarker && impliedParamType && typeHandler == null) {
163183
// @Form on method and this type is a "bean" so treat is as a form bean
164184
writeForm(writer, shortType, varName, ParamType.FORMPARAM);
185+
paramType = ParamType.FORM;
165186
return false;
166187
}
167188

@@ -188,6 +209,7 @@ private boolean setValue(Append writer, PathSegments segments, String shortType)
188209
if (asMethod != null) {
189210
writer.append(")");
190211
}
212+
paramType = ParamType.PATHPARAM;
191213
return true;
192214
}
193215
}
@@ -201,6 +223,8 @@ private boolean setValue(Append writer, PathSegments segments, String shortType)
201223
if (typeHandler == null) {
202224
// assuming this is a body (POST, PATCH)
203225
writer.append("ctx.bodyAsClass(%s.class)", shortType);
226+
paramType = ParamType.BODY;
227+
204228
} else {
205229
if (hasParamDefault()) {
206230
writer.append("ctx.%s(\"%s\",\"%s\")", paramType, paramName, paramDefault);
@@ -222,4 +246,5 @@ private void writeForm(Append writer, String shortType, String varName, ParamTyp
222246
BeanParamReader form = new BeanParamReader(ctx, formBeanType, varName, shortType, defaultParamType);
223247
form.write(writer);
224248
}
249+
225250
}

src/main/java/io/dinject/javalin/generator/MethodParam.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package io.dinject.javalin.generator;
22

3+
import io.dinject.javalin.generator.javadoc.Javadoc;
4+
import io.swagger.v3.oas.models.Operation;
5+
36
import javax.lang.model.element.VariableElement;
47

58
class MethodParam {
@@ -21,4 +24,8 @@ void addImports(ControllerReader bean) {
2124
void buildParamName(Append writer) {
2225
elementParam.writeParamName(writer);
2326
}
27+
28+
void addMeta(Javadoc javadoc, Operation operation) {
29+
elementParam.addMeta(javadoc, operation);
30+
}
2431
}

src/main/java/io/dinject/javalin/generator/MethodReader.java

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
import io.dinject.controller.Patch;
77
import io.dinject.controller.Post;
88
import io.dinject.controller.Put;
9+
import io.dinject.javalin.generator.javadoc.Javadoc;
10+
import io.swagger.v3.oas.models.Operation;
11+
import io.swagger.v3.oas.models.PathItem;
12+
import io.swagger.v3.oas.models.Paths;
913

1014
import javax.lang.model.element.ExecutableElement;
1115
import javax.lang.model.element.VariableElement;
@@ -24,6 +28,8 @@ class MethodReader {
2428
private final List<MethodParam> params = new ArrayList<>();
2529
private final String beanPath;
2630

31+
private final Javadoc javadoc;
32+
2733
private WebMethod webMethod;
2834
private String webMethodPath;
2935

@@ -34,13 +40,18 @@ class MethodReader {
3440
*/
3541
private final List<String> methodRoles;
3642

43+
private String fullPath;
44+
45+
private PathSegments segments;
46+
3747
MethodReader(ControllerReader bean, ExecutableElement element, ProcessingContext ctx) {
3848
this.ctx = ctx;
3949
this.bean = bean;
4050
this.beanPath = bean.getPath();
4151
this.element = element;
4252
this.isVoid = element.getReturnType().toString().equals("void");
4353
this.methodRoles = Util.findRoles(element);
54+
this.javadoc = Javadoc.parse(ctx.getDocComment(element));
4455

4556
readMethodAnnotation();
4657
}
@@ -64,12 +75,45 @@ void read() {
6475
}
6576
}
6677

78+
public void addMeta(ProcessingContext ctx) {
79+
80+
if (webMethod != null) {
81+
82+
Paths paths = ctx.getOpenAPI().getPaths();
83+
84+
PathItem pathItem = paths.get(fullPath);
85+
if (pathItem == null) {
86+
pathItem = new PathItem();
87+
paths.addPathItem(fullPath, pathItem);
88+
}
89+
90+
Operation operation = new Operation();
91+
//operation.setDeprecated();
92+
//operation.setOperationId();
93+
operation.setSummary(javadoc.getSummary());
94+
operation.setDescription(javadoc.getDescription());
95+
96+
switch (webMethod) {
97+
case GET: pathItem.setGet(operation); break;
98+
case PUT: pathItem.setPut(operation); break;
99+
case POST: pathItem.setPost(operation); break;
100+
case DELETE: pathItem.setDelete(operation); break;
101+
case PATCH: pathItem.setPatch(operation); break;
102+
}
103+
104+
for (MethodParam param : params) {
105+
param.addMeta(javadoc, operation);
106+
}
107+
}
108+
}
109+
110+
67111
void addRoute(Append writer) {
68112

69113
if (webMethod != null) {
70114

71-
String fullPath = Util.combinePath(beanPath, webMethodPath);
72-
PathSegments segments = PathSegments.parse(fullPath);
115+
fullPath = Util.combinePath(beanPath, webMethodPath);
116+
segments = PathSegments.parse(fullPath);
73117

74118
writer.append(" ApiBuilder.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), segments.fullPath()).eol();
75119
writer.append(" ctx.status(%s);", httpStatusCode()).eol();
@@ -143,12 +187,10 @@ private boolean readMethodAnnotation() {
143187
if (get != null) {
144188
return setWebMethod(WebMethod.GET, get.value());
145189
}
146-
147190
Put put = element.getAnnotation(Put.class);
148191
if (put != null) {
149192
return setWebMethod(WebMethod.PUT, put.value());
150193
}
151-
152194
Post post = element.getAnnotation(Post.class);
153195
if (post != null) {
154196
return setWebMethod(WebMethod.POST, post.value());
@@ -161,7 +203,6 @@ private boolean readMethodAnnotation() {
161203
if (delete != null) {
162204
return setWebMethod(WebMethod.DELETE, delete.value());
163205
}
164-
165206
return false;
166207
}
167208

src/main/java/io/dinject/javalin/generator/ParamType.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,25 @@
22

33
enum ParamType {
44

5-
FORM("form"),
6-
BEANPARAM("beanParam"),
7-
QUERYPARAM("queryParam"),
8-
FORMPARAM("formParam"),
9-
COOKIE("cookie"),
10-
HEADER("header");
5+
BODY("body", "body"),
6+
PATHPARAM("pathParam", "path"),
7+
FORM("form", "form"),
8+
BEANPARAM("beanParam", "bean"),
9+
QUERYPARAM("queryParam", "query"),
10+
FORMPARAM("formParam", "form"),
11+
COOKIE("cookie", "cookie"),
12+
HEADER("header", "header");
1113

1214
private String code;
15+
private String type;
1316

14-
ParamType(String code) {
17+
ParamType(String code, String type) {
1518
this.code = code;
19+
this.type = type;
20+
}
21+
22+
public String getType() {
23+
return type;
1624
}
1725

1826
@Override

0 commit comments

Comments
 (0)