Skip to content

Commit 0c3f7a5

Browse files
committed
Merge pull request #770 from swagger-api/jaxrs-interface-generation
Jaxrs interface generation
2 parents 99a1163 + 19de558 commit 0c3f7a5

File tree

17 files changed

+208
-32
lines changed

17 files changed

+208
-32
lines changed

bin/jaxrs-petstore-server.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ fi
2626

2727
# if you've executed sbt assembly previously it will use that instead.
2828
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
29-
ags="$@ generate -t modules/swagger-codegen/src/main/resources/JavaJaxRS -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l jaxrs -o samples/server/petstore/jaxrs"
29+
ags="$@ generate -t modules/swagger-codegen/src/main/resources/JavaJaxRS -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l jaxrs -o samples/server/petstore/jaxrs -Dswagger.codegen.jaxrs.impl.source=src/main/java"
3030

3131
java $JAVA_OPTS -jar $executable $ags

modules/swagger-codegen-cli/src/main/java/com/wordnik/swagger/codegen/cmd/Generate.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,16 @@ public class Generate implements Runnable {
5454
"Pass in a URL-encoded string of name:header with a comma separating multiple values")
5555
private String auth;
5656

57+
@Option( name= {"-D"}, title = "system properties", description = "sets specified system properties in " +
58+
"the format of name=value,name=value")
59+
private String systemProperties;
60+
5761
@Override
5862
public void run() {
5963
verbosed(verbose);
6064

65+
setSystemProperties();
66+
6167
ClientOptInput input = new ClientOptInput();
6268

6369
if (isNotEmpty(auth)) {
@@ -77,6 +83,17 @@ public void run() {
7783
new DefaultGenerator().opts(input.opts(new ClientOpts()).swagger(swagger)).generate();
7884
}
7985

86+
private void setSystemProperties() {
87+
if( systemProperties != null && systemProperties.length() > 0 ){
88+
for( String property : systemProperties.split(",")) {
89+
int ix = property.indexOf('=');
90+
if( ix > 0 && ix < property.length()-1 ){
91+
System.setProperty( property.substring(0, ix), property.substring(ix+1) );
92+
}
93+
}
94+
}
95+
}
96+
8097
/**
8198
* If true parameter, adds system properties which enables debug mode in generator
8299
* @param verbose - if true, enables debug mode

modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/CodegenConfig.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,8 @@ public interface CodegenConfig {
5656
Map<String, Object> postProcessModels(Map<String, Object> objs);
5757
Map<String, Object> postProcessOperations(Map<String, Object> objs);
5858
Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs);
59+
60+
String apiFilename(String templateName, String tag);
61+
62+
boolean shouldOverwrite(String filename);
5963
}

modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/DefaultCodegen.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1227,4 +1227,13 @@ public static String camelize(String word, boolean lowercaseFirstLetter) {
12271227
}
12281228

12291229

1230-
}
1230+
public String apiFilename(String templateName, String tag)
1231+
{
1232+
String suffix = apiTemplateFiles().get(templateName);
1233+
return apiFileFolder() + File.separator + toApiFilename(tag) + suffix;
1234+
}
1235+
1236+
public boolean shouldOverwrite( String filename ){
1237+
return true;
1238+
}
1239+
}

modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/DefaultGenerator.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,11 +179,11 @@ public Reader getTemplate(String name) {
179179
}
180180

181181
for (String templateName : config.apiTemplateFiles().keySet()) {
182-
String suffix = config.apiTemplateFiles().get(templateName);
183-
String filename = config.apiFileFolder() +
184-
File.separator +
185-
config.toApiFilename(tag) +
186-
suffix;
182+
183+
String filename = config.apiFilename( templateName, tag );
184+
if( new File( filename ).exists() && !config.shouldOverwrite( filename )){
185+
continue;
186+
}
187187

188188
String template = readTemplate(config.templateDir() + File.separator + templateName);
189189
Template tmpl = Mustache.compiler()

modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/JavaClientCodegen.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ public String toModelFilename(String name) {
130130
return toModelName(name);
131131
}
132132

133-
134133
@Override
135134
public String getTypeDeclaration(Property p) {
136135
if(p instanceof ArrayProperty) {

modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/JaxRSServerCodegen.java

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package com.wordnik.swagger.codegen.languages;
22

33
import com.wordnik.swagger.models.Operation;
4-
import com.wordnik.swagger.models.Path;
5-
import com.wordnik.swagger.util.Json;
64
import com.wordnik.swagger.codegen.*;
75
import com.wordnik.swagger.models.properties.*;
86

@@ -14,7 +12,6 @@ public class JaxRSServerCodegen extends JavaClientCodegen implements CodegenConf
1412
protected String groupId = "io.swagger";
1513
protected String artifactId = "swagger-jaxrs-server";
1614
protected String artifactVersion = "1.0.0";
17-
protected String sourceFolder = "src/main/java";
1815
protected String title = "Swagger Server";
1916

2017
public CodegenType getTag() {
@@ -31,12 +28,19 @@ public String getHelp() {
3128

3229
public JaxRSServerCodegen() {
3330
super();
34-
outputFolder = "generated-code/javaJaxRS";
31+
32+
sourceFolder = "src/gen/java";
33+
34+
outputFolder = System.getProperty( "swagger.codegen.jaxrs.genfolder", "generated-code/javaJaxRS" );
3535
modelTemplateFiles.put("model.mustache", ".java");
3636
apiTemplateFiles.put("api.mustache", ".java");
37+
apiTemplateFiles.put("apiService.mustache", ".java");
38+
apiTemplateFiles.put("apiServiceImpl.mustache", ".java");
39+
apiTemplateFiles.put("apiServiceFactory.mustache", ".java");
40+
3741
templateDir = "JavaJaxRS";
38-
apiPackage = "io.swagger.api";
39-
modelPackage = "io.swagger.model";
42+
apiPackage = System.getProperty( "swagger.codegen.jaxrs.apipackage", "io.swagger.api") ;
43+
modelPackage = System.getProperty( "swagger.codegen.jaxrs.modelpackage", "io.swagger.model" );
4044

4145
additionalProperties.put("invokerPackage", invokerPackage);
4246
additionalProperties.put("groupId", groupId);
@@ -146,4 +150,44 @@ else if(operation.returnType.startsWith("Set")) {
146150
}
147151
return objs;
148152
}
153+
154+
@Override
155+
public String apiFilename(String templateName, String tag) {
156+
157+
String result = super.apiFilename(templateName, tag);
158+
159+
if( templateName.endsWith( "Impl.mustache")){
160+
int ix = result.lastIndexOf( '/' );
161+
result = result.substring( 0, ix ) + "/impl" + result.substring( ix, result.length()-5 ) + "ServiceImpl.java";
162+
163+
String output = System.getProperty( "swagger.codegen.jaxrs.impl.source" );
164+
if( output != null ){
165+
result = result.replace( apiFileFolder(), implFileFolder(output));
166+
}
167+
}
168+
else if( templateName.endsWith( "Factory.mustache")){
169+
int ix = result.lastIndexOf( '/' );
170+
result = result.substring( 0, ix ) + "/factories" + result.substring( ix, result.length()-5 ) + "ServiceFactory.java";
171+
172+
String output = System.getProperty( "swagger.codegen.jaxrs.impl.source" );
173+
if( output != null ){
174+
result = result.replace( apiFileFolder(), implFileFolder(output));
175+
}
176+
}
177+
else if( templateName.endsWith( "Service.mustache")) {
178+
int ix = result.lastIndexOf('.');
179+
result = result.substring(0, ix) + "Service.java";
180+
}
181+
182+
return result;
183+
}
184+
185+
private String implFileFolder(String output) {
186+
return outputFolder + "/" + output + "/" + apiPackage().replace('.', File.separatorChar);
187+
}
188+
189+
public boolean shouldOverwrite( String filename ){
190+
191+
return !filename.endsWith( "ServiceImpl.java") && !filename.endsWith( "ServiceFactory.java");
192+
}
149193
}
Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package {{package}};
22

33
import {{modelPackage}}.*;
4+
import {{package}}.{{classname}}Service;
5+
import {{package}}.factories.{{classname}}ServiceFactory;
46

57
import com.wordnik.swagger.annotations.ApiParam;
68

@@ -25,24 +27,27 @@ import javax.ws.rs.*;
2527
{{#hasProduces}}@Produces({ {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
2628
@com.wordnik.swagger.annotations.Api(value = "/{{baseName}}", description = "the {{baseName}} API")
2729
{{#operations}}
28-
public class {{classname}} {
29-
{{#operation}}
30-
@{{httpMethod}}
31-
{{#subresourceOperation}}@Path("{{path}}"){{/subresourceOperation}}
32-
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
33-
{{#hasProduces}}@Produces({ {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
34-
@com.wordnik.swagger.annotations.ApiOperation(value = "{{{summary}}}", notes = "{{{notes}}}", response = {{{returnType}}}.class{{#returnContainer}}, responseContainer = "{{{returnContainer}}}"{{/returnContainer}})
35-
@com.wordnik.swagger.annotations.ApiResponses(value = { {{#responses}}
36-
@com.wordnik.swagger.annotations.ApiResponse(code = {{{code}}}, message = "{{{message}}}"){{#hasMore}},
37-
{{/hasMore}}{{/responses}} })
38-
39-
public Response {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},
40-
{{/hasMore}}{{/allParams}})
41-
throws NotFoundException {
42-
// do some magic!
43-
return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")).build();
44-
}
30+
public class {{classname}} {
31+
32+
private final {{classname}}Service delegate = {{classname}}ServiceFactory.get{{classname}}();
33+
34+
{{#operation}}
35+
@{{httpMethod}}
36+
{{#subresourceOperation}}@Path("{{path}}"){{/subresourceOperation}}
37+
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
38+
{{#hasProduces}}@Produces({ {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
39+
@com.wordnik.swagger.annotations.ApiOperation(value = "{{{summary}}}", notes = "{{{notes}}}", response = {{{returnType}}}.class{{#returnContainer}}, responseContainer = "{{{returnContainer}}}"{{/returnContainer}})
40+
@com.wordnik.swagger.annotations.ApiResponses(value = { {{#responses}}
41+
@com.wordnik.swagger.annotations.ApiResponse(code = {{{code}}}, message = "{{{message}}}"){{#hasMore}},
42+
{{/hasMore}}{{/responses}} })
4543

46-
{{/operation}}
44+
public Response {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},
45+
{{/hasMore}}{{/allParams}})
46+
throws NotFoundException {
47+
// do some magic!
48+
return delegate.{{nickname}}({{#allParams}}{{#isFile}}fileDetail{{/isFile}}{{^isFile}}{{paramName}}{{/isFile}}{{#hasMore}},{{/hasMore}}{{/allParams}});
49+
}
50+
{{/operation}}
4751
}
4852
{{/operations}}
53+
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package {{package}};
2+
3+
import {{package}}.*;
4+
import {{modelPackage}}.*;
5+
6+
import com.sun.jersey.multipart.FormDataParam;
7+
8+
{{#imports}}import {{import}};
9+
{{/imports}}
10+
11+
import java.util.List;
12+
import {{package}}.NotFoundException;
13+
14+
import java.io.InputStream;
15+
16+
import com.sun.jersey.core.header.FormDataContentDisposition;
17+
import com.sun.jersey.multipart.FormDataParam;
18+
19+
import javax.ws.rs.core.Response;
20+
21+
{{#operations}}
22+
public abstract class {{classname}}Service {
23+
{{#operation}}
24+
public abstract Response {{nickname}}({{#allParams}}{{>serviceQueryParams}}{{>servicePathParams}}{{>serviceHeaderParams}}{{>serviceBodyParams}}{{>serviceFormParams}}{{#hasMore}},{{/hasMore}}{{/allParams}})
25+
throws NotFoundException;
26+
{{/operation}}
27+
}
28+
{{/operations}}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package {{package}}.factories;
2+
3+
import {{package}}.{{classname}}Service;
4+
import {{package}}.impl.{{classname}}ServiceImpl;
5+
6+
public class {{classname}}ServiceFactory {
7+
8+
private final static {{classname}}Service service = new {{classname}}ServiceImpl();
9+
10+
public static {{classname}}Service get{{classname}}()
11+
{
12+
return service;
13+
}
14+
}

0 commit comments

Comments
 (0)