Merge pull request #2 from swagger-api/master

Update
This commit is contained in:
Mikołaj Przybysz 2016-05-24 11:53:56 +02:00
commit e687ad5823
1070 changed files with 38196 additions and 23539 deletions

34
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,34 @@
<!--
Please follow the issue template below for bug reports and feature requests.
Also please indicate in the issue title which language/library is concerned. Eg: [JAVA] Bug generating foo with bar
-->
##### Description
<!-- describe what is the issue and why this is a problem for you. -->
##### Swagger-codegen version
<!-- which version of swagger-codegen are you using, is it a regression? -->
##### Swagger declaration file content or url
<!-- if it is a bug, a json or yaml that produces it. -->
##### Command line used for generation
<!-- including the language, libraries and various options -->
##### Steps to reproduce
<!-- unambiguous set of steps to reproduce the bug.-->
##### Related issues
<!-- has a similar issue been reported before? -->
##### Suggest a Fix
<!-- if you can't fix the bug yourself, perhaps you can point to what might be
causing the problem (line of code or commit) -->

14
.gitignore vendored
View File

@ -41,6 +41,7 @@ samples/server-generator/scalatra/target
samples/server-generator/scalatra/output/.history
# nodejs
**/node_modules/
samples/server-generator/node/output/node_modules
samples/server/petstore/nodejs/node_modules
samples/server/petstore/nodejs-server/node_modules
@ -116,13 +117,8 @@ samples/client/petstore/python/.venv/
# ts
samples/client/petstore/typescript-node/npm/node_modules
samples/client/petstore/typescript-fetch/with-package-metadata/node_modules
samples/client/petstore/typescript-fetch/with-package-metadata/dist
samples/client/petstore/typescript-fetch/with-package-metadata/typings
samples/client/petstore/typescript-fetch/default/node_modules
samples/client/petstore/typescript-fetch/default/dist
samples/client/petstore/typescript-fetch/default/typings
samples/client/petstore/typescript-fetch/default-es6/node_modules
samples/client/petstore/typescript-fetch/default-es6/dist
samples/client/petstore/typescript-fetch/default-es6/typings
samples/client/petstore/typescript-node/**/typings
samples/client/petstore/typescript-angular/**/typings
samples/client/petstore/typescript-fetch/**/dist/
samples/client/petstore/typescript-fetch/**/typings

View File

@ -10,6 +10,7 @@ services:
before_install:
# required when sudo: required for the Ruby petstore tests
- gem install bundler
- npm install -g typescript
install:

View File

@ -386,6 +386,26 @@ To control the specific files being generated, you can pass a CSV list of what y
-Dmodels=User -DsupportingFiles=StringUtil.java
```
To control generation of docs and tests for api and models, pass false to the option. For api, these options are `-DapiTest=false` and `-DapiDocs=false`. For models, `-DmodelTest=false` and `-DmodelDocs=false`.
These options default to true and don't limit the generation of the feature options listed above (like `-Dapi`):
```
# generate only models (with tests and documentation)
java -Dmodels {opts}
# generate only models (with tests but no documentation)
java -Dmodels -DmodelDocs=false {opts}
# generate only User and Pet models (no tests and no documentation)
java -Dmodels=User,Pet -DmodelTests=false {opts}
# generate only apis (without tests)
java -Dapis -DapiTests=false {opts}
# generate only apis (modelTests option is ignored)
java -Dapis -DmodelTests=false {opts}
```
When using selective generation, _only_ the templates needed for the specific generation will be used.
### Customizing the generator
@ -608,7 +628,7 @@ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
```
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
-i http://petstore.swagger.io/v2/swagger.json \
-l silex \
-l silex-PHP \
-o samples/server/petstore/silex
```
@ -800,6 +820,7 @@ Here are some companies/projects using Swagger Codegen in production. To add you
- [everystory.us](http://everystory.us)
- [Expected Behavior](http://www.expectedbehavior.com/)
- [FH Münster - University of Applied Sciences](http://www.fh-muenster.de)
- [IMS Health](http://www.imshealth.com/en/solution-areas/technology-and-applications)
- [Interactive Intelligence](http://developer.mypurecloud.com/)
- [LANDR Audio](https://www.landr.com/)
- [LiveAgent](https://www.ladesk.com/)
@ -813,12 +834,14 @@ Here are some companies/projects using Swagger Codegen in production. To add you
- [PostAffiliatePro](https://www.postaffiliatepro.com/)
- [Reload! A/S](https://reload.dk/)
- [REstore](https://www.restore.eu)
- [Revault Sàrl](http://revault.ch)
- [Royal Bank of Canada (RBC)](http://www.rbc.com/canada.html)
- [SmartRecruiters](https://www.smartrecruiters.com/)
- [StyleRecipe](http://stylerecipe.co.jp)
- [Svenska Spel AB](https://www.svenskaspel.se/)
- [ThoughtWorks](https://www.thoughtworks.com)
- [uShip](https://www.uship.com/)
- [WEXO A/S](https://www.wexo.dk/)
- [Zalando](https://tech.zalando.com)
- [ZEEF.com](https://zeef.com/)
@ -842,7 +865,7 @@ Swaagger Codegen core team members are contributors who have been making signfic
| Perl | @wing328 (2016/05/01) |
| PHP | @arnested (2016/05/01) |
| Python | @scottrw93 (2016/05/01) |
| Ruby | @wing328 (2016/05/01) |
| Ruby | @wing328 (2016/05/01) @zlx (2016/05/22) |
| Scala | |
| Swift | @jaz-ah (2016/05/01) @Edubits (2016/05/01) |
| TypeScript (Node) | @Vrolijkx (2016/05/01) |
@ -894,6 +917,7 @@ Here is a list of template creators:
* JAX-RS CXF: @hiveship
* PHP Lumen: @abcsum
* PHP Slim: @jfastnacht
* Ruby on Rails 5: @zlx
## How to join the core team

View File

@ -0,0 +1,31 @@
#!/bin/sh
SCRIPT="$0"
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
if [ ! -f "$executable" ]
then
mvn clean package
fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/android -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l android -Dlibrary=httpclient -o samples/client/petstore/android/httpclient"
java $JAVA_OPTS -jar $executable $ags

View File

@ -26,6 +26,6 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/android -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l android -o samples/client/petstore/android/default"
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l android -o samples/client/petstore/android/volley"
java $JAVA_OPTS -jar $executable $ags

31
bin/rails5-petstore-server.sh Executable file
View File

@ -0,0 +1,31 @@
#!/bin/sh
SCRIPT="$0"
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
if [ ! -f "$executable" ]
then
mvn clean package
fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/rails5 -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l rails5 -o samples/server/petstore/rails5"
java $JAVA_OPTS -jar $executable $ags

View File

@ -0,0 +1,7 @@
{
"podSummary": "PetstoreClient",
"podHomepage": "https://github.com/swagger-api/swagger-codegen",
"podAuthors": "",
"projectName": "PetstoreClient",
"responseAs": "PromiseKit"
}

View File

@ -0,0 +1,31 @@
#!/bin/sh
SCRIPT="$0"
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
if [ ! -f "$executable" ]
then
mvn clean package
fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/swift -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l swift -c ./bin/swift-petstore-promisekit.json -o samples/client/petstore/swift-promisekit"
java $JAVA_OPTS -jar $executable $ags

View File

@ -1,4 +1,6 @@
{
"projectName": "PetstoreClient",
"responseAs": "PromiseKit"
"podSummary": "PetstoreClient",
"podHomepage": "https://github.com/swagger-api/swagger-codegen",
"podAuthors": "",
"projectName": "PetstoreClient"
}

0
bin/swift-petstore.sh Executable file → Normal file
View File

View File

@ -1,5 +1,5 @@
#!/bin/sh
./bin/typescript-fetch-petstore-target-es6.sh
./bin/typescript-fetch-petstore-target-with-package-metadata.sh
./bin/typescript-fetch-petstore-with-npm-version.sh
./bin/typescript-fetch-petstore.sh

View File

@ -26,6 +26,6 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l typescript-fetch -c bin/typescript-fetch-petstore-target-es6.json -o samples/client/petstore/typescript-fetch/default-es6"
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l typescript-fetch -c bin/typescript-fetch-petstore-target-es6.json -o samples/client/petstore/typescript-fetch/builds/es6-target"
java $JAVA_OPTS -jar $executable $ags

View File

@ -26,6 +26,6 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l typescript-fetch -c bin/typescript-fetch-petstore-target-with-package-metadata.json -o samples/client/petstore/typescript-fetch/with-package-metadata"
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l typescript-fetch -c bin/typescript-fetch-petstore-with-npm-version.json -o samples/client/petstore/typescript-fetch/builds/with-npm-version"
java $JAVA_OPTS -jar $executable $ags

View File

@ -26,6 +26,6 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l typescript-fetch -o samples/client/petstore/typescript-fetch/default"
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l typescript-fetch -o samples/client/petstore/typescript-fetch/builds/default"
java $JAVA_OPTS -jar $executable $ags

View File

@ -0,0 +1,10 @@
set executable=.\modules\swagger-codegen-cli\target\swagger-codegen-cli.jar
If Not Exist %executable% (
mvn clean package
)
set JAVA_OPTS=%JAVA_OPTS% -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties
set ags=generate -t modules\swagger-codegen\src\main\resources\rails5 -i modules\swagger-codegen\src\test\resources\2_0\petstore.json -l aspnet5 -o samples\server\petstore\rails5\
java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -199,6 +199,9 @@
</plugin>
</plugins>
</reporting>
<properties>
<diffutils-version>1.2.1</diffutils-version>
</properties>
<dependencies>
<dependency>
<groupId>io.swagger</groupId>
@ -279,6 +282,13 @@
<!-- <version>${jmockit-version}</version> -->
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.googlecode.java-diff-utils</groupId>
<artifactId>diffutils</artifactId>
<version>${diffutils-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>

View File

@ -99,6 +99,16 @@ public abstract class AbstractGenerator {
}
}
public String readResourceContents(String resourceFilePath) {
StringBuilder sb = new StringBuilder();
Scanner scanner = new Scanner(this.getClass().getResourceAsStream(getCPResourcePath(resourceFilePath)), "UTF-8");
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
sb.append(line).append('\n');
}
return sb.toString();
}
public boolean embeddedTemplateExists(String name) {
return this.getClass().getClassLoader().getResource(getCPResourcePath(name)) != null;
}

View File

@ -1,10 +1,10 @@
package io.swagger.codegen;
import io.swagger.codegen.auth.AuthMethod;
import java.util.HashMap;
import java.util.Map;
import io.swagger.codegen.auth.AuthMethod;
public class ClientOpts {
protected String uri;
protected String target;

View File

@ -184,4 +184,5 @@ public interface CodegenConfig {
String getHttpUserAgent();
String getCommonTemplateDir();
}

View File

@ -105,4 +105,14 @@ public class CodegenConstants {
public static final String SUPPORTS_ES6 = "supportsES6";
public static final String SUPPORTS_ES6_DESC = "Generate code that conforms to ES6.";
public static final String EXCLUDE_TESTS = "excludeTests";
public static final String EXCLUDE_TESTS_DESC = "Specifies that no tests are to be generated.";
public static final String GENERATE_API_TESTS = "generateApiTests";
public static final String GENERATE_API_TESTS_DESC = "Specifies that api tests are to be generated.";
public static final String GENERATE_MODEL_TESTS = "generateModelTests";
public static final String GENERATE_MODEL_TESTS_DESC = "Specifies that model tests are to be generated.";
}

View File

@ -1,7 +1,13 @@
package io.swagger.codegen;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import io.swagger.models.ExternalDocs;
import java.util.*;
public class CodegenModel {
public String parent, parentSchema;
@ -19,6 +25,8 @@ public class CodegenModel {
public List<CodegenProperty> vars = new ArrayList<CodegenProperty>();
public List<CodegenProperty> requiredVars = new ArrayList<CodegenProperty>(); // a list of required properties
public List<CodegenProperty> optionalVars = new ArrayList<CodegenProperty>(); // a list of optional properties
public List<CodegenProperty> readOnlyVars = new ArrayList<CodegenProperty>(); // a list of read-only properties
public List<CodegenProperty> readWriteVars = new ArrayList<CodegenProperty>(); // a list of properties for read, write
public List<CodegenProperty> allVars;
public Map<String, Object> allowableValues;
@ -27,11 +35,14 @@ public class CodegenModel {
public Set<String> allMandatory;
public Set<String> imports = new TreeSet<String>();
public Boolean hasVars, emptyVars, hasMoreModels, hasEnums, isEnum;
public Boolean hasVars, emptyVars, hasMoreModels, hasEnums, isEnum, hasRequired;
public ExternalDocs externalDocs;
public Map<String, Object> vendorExtensions;
//The type of the value from additional properties. Used in map like objects.
public String additionalPropertiesType;
{
// By default these are the same collections. Where the code generator supports inheritance, composed models
// store the complete closure of owned and inherited properties in allVars and allMandatory.

View File

@ -7,13 +7,16 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Arrays;
public class CodegenOperation {
public final List<CodegenProperty> responseHeaders = new ArrayList<CodegenProperty>();
public Boolean hasAuthMethods, hasConsumes, hasProduces, hasParams, hasOptionalParams,
returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMapContainer,
isListContainer, isMultipart, hasMore = Boolean.TRUE,
isResponseBinary = Boolean.FALSE, hasReference = Boolean.FALSE;
isResponseBinary = Boolean.FALSE, hasReference = Boolean.FALSE,
isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy,
isRestful;
public String path, operationId, returnType, httpMethod, returnBaseType,
returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse, discriminator;
public List<Map<String, String>> consumes, produces;
@ -88,6 +91,81 @@ public class CodegenOperation {
return nonempty(formParams);
}
/**
* Check if act as Restful index method
*
* @return true if act as Restful index method, false otherwise
*/
public boolean isRestfulIndex() {
return "GET".equals(httpMethod) && "".equals(pathWithoutBaseName());
}
/**
* Check if act as Restful show method
*
* @return true if act as Restful show method, false otherwise
*/
public boolean isRestfulShow() {
return "GET".equals(httpMethod) && isMemberPath();
}
/**
* Check if act as Restful create method
*
* @return true if act as Restful create method, false otherwise
*/
public boolean isRestfulCreate() {
return "POST".equals(httpMethod) && "".equals(pathWithoutBaseName());
}
/**
* Check if act as Restful update method
*
* @return true if act as Restful update method, false otherwise
*/
public boolean isRestfulUpdate() {
return Arrays.asList("PUT", "PATCH").contains(httpMethod) && isMemberPath();
}
/**
* Check if act as Restful destroy method
*
* @return true if act as Restful destroy method, false otherwise
*/
public boolean isRestfulDestroy() {
return "DELETE".equals(httpMethod) && isMemberPath();
}
/**
* Check if Restful-style
*
* @return true if Restful-style, false otherwise
*/
public boolean isRestful() {
return isRestfulIndex() || isRestfulShow() || isRestfulCreate() || isRestfulUpdate() || isRestfulDestroy();
}
/**
* Get the substring except baseName from path
*
* @return the substring
*/
private String pathWithoutBaseName() {
return baseName != null ? path.replace("/" + baseName.toLowerCase(), "") : path;
}
/**
* Check if the path match format /xxx/:id
*
* @return true if path act as member
*/
private boolean isMemberPath() {
if (pathParams.size() != 1) return false;
String id = pathParams.get(0).baseName;
return ("/{" + id + "}").equals(pathWithoutBaseName());
}
@Override
public String toString() {
return String.format("%s(%s)", baseName, path);

View File

@ -2,25 +2,76 @@ package io.swagger.codegen;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import io.swagger.codegen.examples.ExampleGenerator;
import io.swagger.models.*;
import io.swagger.models.auth.*;
import io.swagger.models.parameters.*;
import io.swagger.models.properties.*;
import io.swagger.models.properties.PropertyBuilder.PropertyId;
import io.swagger.util.Json;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.io.File;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import io.swagger.codegen.examples.ExampleGenerator;
import io.swagger.models.ArrayModel;
import io.swagger.models.ComposedModel;
import io.swagger.models.Model;
import io.swagger.models.ModelImpl;
import io.swagger.models.Operation;
import io.swagger.models.RefModel;
import io.swagger.models.Response;
import io.swagger.models.Swagger;
import io.swagger.models.auth.ApiKeyAuthDefinition;
import io.swagger.models.auth.BasicAuthDefinition;
import io.swagger.models.auth.In;
import io.swagger.models.auth.OAuth2Definition;
import io.swagger.models.auth.SecuritySchemeDefinition;
import io.swagger.models.parameters.BodyParameter;
import io.swagger.models.parameters.CookieParameter;
import io.swagger.models.parameters.FormParameter;
import io.swagger.models.parameters.HeaderParameter;
import io.swagger.models.parameters.Parameter;
import io.swagger.models.parameters.PathParameter;
import io.swagger.models.parameters.QueryParameter;
import io.swagger.models.parameters.SerializableParameter;
import io.swagger.models.properties.AbstractNumericProperty;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.BaseIntegerProperty;
import io.swagger.models.properties.BinaryProperty;
import io.swagger.models.properties.BooleanProperty;
import io.swagger.models.properties.ByteArrayProperty;
import io.swagger.models.properties.DateProperty;
import io.swagger.models.properties.DateTimeProperty;
import io.swagger.models.properties.DecimalProperty;
import io.swagger.models.properties.DoubleProperty;
import io.swagger.models.properties.FloatProperty;
import io.swagger.models.properties.IntegerProperty;
import io.swagger.models.properties.LongProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.PropertyBuilder;
import io.swagger.models.properties.PropertyBuilder.PropertyId;
import io.swagger.models.properties.RefProperty;
import io.swagger.models.properties.StringProperty;
import io.swagger.models.properties.UUIDProperty;
import io.swagger.util.Json;
public class DefaultCodegen {
protected static final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);
@ -43,6 +94,7 @@ public class DefaultCodegen {
protected Map<String, String> modelDocTemplateFiles = new HashMap<String, String>();
protected String templateDir;
protected String embeddedTemplateDir;
protected String commonTemplateDir = "_common";
protected Map<String, Object> additionalProperties = new HashMap<String, Object>();
protected Map<String, Object> vendorExtensions = new HashMap<String, Object>();
protected List<SupportingFile> supportingFiles = new ArrayList<SupportingFile>();
@ -390,6 +442,14 @@ public class DefaultCodegen {
}
}
public String getCommonTemplateDir() {
return this.commonTemplateDir;
}
public void setCommonTemplateDir(String commonTemplateDir) {
this.commonTemplateDir = commonTemplateDir;
}
public Map<String, String> apiDocTemplateFiles() {
return apiDocTemplateFiles;
}
@ -1207,8 +1267,7 @@ public class DefaultCodegen {
m.dataType = getSwaggerType(p);
}
if (impl.getAdditionalProperties() != null) {
MapProperty mapProperty = new MapProperty(impl.getAdditionalProperties());
addParentContainer(m, name, mapProperty);
addAdditionPropertiesToCodeGenModel(m, impl);
}
addVars(m, impl.getProperties(), impl.getRequired());
}
@ -1221,8 +1280,12 @@ public class DefaultCodegen {
return m;
}
protected void addProperties(Map<String, Property> properties, List<String> required, Model model,
Map<String, Model> allDefinitions) {
protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, ModelImpl swaggerModel) {
MapProperty mapProperty = new MapProperty(swaggerModel.getAdditionalProperties());
addParentContainer(codegenModel, codegenModel.name, mapProperty);
}
protected void addProperties(Map<String, Property> properties, List<String> required, Model model, Map<String, Model> allDefinitions) {
if (model instanceof ModelImpl) {
ModelImpl mi = (ModelImpl) model;
@ -1847,6 +1910,14 @@ public class DefaultCodegen {
}
op.externalDocs = operation.getExternalDocs();
// set Restful Flag
op.isRestfulShow = op.isRestfulShow();
op.isRestfulIndex = op.isRestfulIndex();
op.isRestfulCreate = op.isRestfulCreate();
op.isRestfulUpdate = op.isRestfulUpdate();
op.isRestfulDestroy = op.isRestfulDestroy();
op.isRestful = op.isRestful();
return op;
}
@ -2452,7 +2523,7 @@ public class DefaultCodegen {
}
}
private void addImport(CodegenModel m, String type) {
protected void addImport(CodegenModel m, String type) {
if (type != null && needToImport(type)) {
m.imports.add(type);
}
@ -2465,6 +2536,7 @@ public class DefaultCodegen {
private void addVars(CodegenModel m, Map<String, Property> properties, List<String> required,
Map<String, Property> allProperties, List<String> allRequired) {
m.hasRequired = false;
if (properties != null && !properties.isEmpty()) {
m.hasVars = true;
m.hasEnums = false;
@ -2503,6 +2575,7 @@ public class DefaultCodegen {
} else {
final CodegenProperty cp = fromProperty(key, prop);
cp.required = mandatory.contains(key) ? true : null;
m.hasRequired = Boolean.TRUE.equals(m.hasRequired) || Boolean.TRUE.equals(cp.required);
if (cp.isEnum) {
// FIXME: if supporting inheritance, when called a second time for allProperties it is possible for
// m.hasEnums to be set incorrectly if allProperties has enumerations but properties does not.
@ -2525,11 +2598,19 @@ public class DefaultCodegen {
addImport(m, cp.complexType);
vars.add(cp);
if (Boolean.TRUE.equals(cp.required)) { // if required, add to the list "requiredVars"
// if required, add to the list "requiredVars"
if (Boolean.TRUE.equals(cp.required)) {
m.requiredVars.add(cp);
} else { // else add to the list "optionalVars" for optional property
m.optionalVars.add(cp);
}
// if readonly, add to readOnlyVars (list of properties)
if (Boolean.TRUE.equals(cp.isReadOnly)) {
m.readOnlyVars.add(cp);
} else { // else add to readWriteVars (list of properties)
m.readWriteVars.add(cp);
}
}
}
}

View File

@ -2,6 +2,7 @@ package io.swagger.codegen;
import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Template;
import io.swagger.codegen.ignore.CodegenIgnoreProcessor;
import io.swagger.models.*;
import io.swagger.models.auth.OAuth2Definition;
import io.swagger.models.auth.SecuritySchemeDefinition;
@ -24,6 +25,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
protected CodegenConfig config;
protected ClientOptInput opts;
protected Swagger swagger;
protected CodegenIgnoreProcessor ignoreProcessor;
@Override
public Generator opts(ClientOptInput opts) {
@ -31,8 +33,11 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
this.swagger = opts.getSwagger();
this.config = opts.getConfig();
this.config.additionalProperties().putAll(opts.getOpts().getProperties());
ignoreProcessor = new CodegenIgnoreProcessor(this.config.getOutputDir());
return this;
}
@ -41,6 +46,10 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
Boolean generateApis = null;
Boolean generateModels = null;
Boolean generateSupportingFiles = null;
Boolean generateApiTests = null;
Boolean generateApiDocumentation = null;
Boolean generateModelTests = null;
Boolean generateModelDocumentation = null;
Set<String> modelsToGenerate = null;
Set<String> apisToGenerate = null;
@ -68,6 +77,18 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
supportingFilesToGenerate = new HashSet<String>(Arrays.asList(supportingFiles.split(",")));
}
}
if(System.getProperty("modelTests") != null) {
generateModelTests = Boolean.valueOf(System.getProperty("modelTests"));
}
if(System.getProperty("modelDocs") != null) {
generateModelDocumentation = Boolean.valueOf(System.getProperty("modelDocs"));
}
if(System.getProperty("apiTests") != null) {
generateApiTests = Boolean.valueOf(System.getProperty("apiTests"));
}
if(System.getProperty("apiDocs") != null) {
generateApiDocumentation = Boolean.valueOf(System.getProperty("apiDocs"));
}
if(generateApis == null && generateModels == null && generateSupportingFiles == null) {
// no specifics are set, generate everything
@ -85,6 +106,28 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
}
// model/api tests and documentation options rely on parent generate options (api or model) and no other options.
// They default to true in all scenarios and can only be marked false explicitly
if (generateModelTests == null) {
generateModelTests = true;
}
if (generateModelDocumentation == null) {
generateModelDocumentation = true;
}
if (generateApiTests == null) {
generateApiTests = true;
}
if (generateApiDocumentation == null) {
generateApiDocumentation = true;
}
// Additional properties added for tests to exclude references in project related files
config.additionalProperties().put(CodegenConstants.GENERATE_API_TESTS, generateApiTests);
config.additionalProperties().put(CodegenConstants.GENERATE_MODEL_TESTS, generateModelTests);
if(Boolean.FALSE.equals(generateApiTests) && Boolean.FALSE.equals(generateModelTests)) {
config.additionalProperties().put(CodegenConstants.EXCLUDE_TESTS, Boolean.TRUE);
}
if (swagger == null || config == null) {
throw new RuntimeException("missing swagger input or config!");
}
@ -159,7 +202,6 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
String basePath = hostBuilder.toString();
String basePathWithoutHost = swagger.getBasePath();
// resolve inline models
InlineModelResolver inlineModelResolver = new InlineModelResolver();
inlineModelResolver.flatten(swagger);
@ -267,21 +309,14 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
LOGGER.info("Skipped overwriting " + filename);
continue;
}
String templateFile = getFullTemplateFile(config, templateName);
String template = readTemplate(templateFile);
Template tmpl = Mustache.compiler()
.withLoader(new Mustache.TemplateLoader() {
@Override
public Reader getTemplate(String name) {
return getTemplateReader(getFullTemplateFile(config, name + ".mustache"));
File written = processTemplateToFile(models, templateName, filename);
if(written != null) {
files.add(written);
}
})
.defaultValue("")
.compile(template);
writeToFile(filename, tmpl.execute(models));
files.add(new File(filename));
}
if(generateModelTests) {
// to generate model test files
for (String templateName : config.modelTestTemplateFiles().keySet()) {
String suffix = config.modelTestTemplateFiles().get(templateName);
@ -291,21 +326,15 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
LOGGER.info("File exists. Skipped overwriting " + filename);
continue;
}
String templateFile = getFullTemplateFile(config, templateName);
String template = readTemplate(templateFile);
Template tmpl = Mustache.compiler()
.withLoader(new Mustache.TemplateLoader() {
@Override
public Reader getTemplate(String name) {
return getTemplateReader(getFullTemplateFile(config, name + ".mustache"));
File written = processTemplateToFile(models, templateName, filename);
if (written != null) {
files.add(written);
}
}
})
.defaultValue("")
.compile(template);
writeToFile(filename, tmpl.execute(models));
files.add(new File(filename));
}
if(generateModelDocumentation) {
// to generate model documentation files
for (String templateName : config.modelDocTemplateFiles().keySet()) {
String suffix = config.modelDocTemplateFiles().get(templateName);
@ -314,19 +343,12 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
LOGGER.info("Skipped overwriting " + filename);
continue;
}
String templateFile = getFullTemplateFile(config, templateName);
String template = readTemplate(templateFile);
Template tmpl = Mustache.compiler()
.withLoader(new Mustache.TemplateLoader() {
@Override
public Reader getTemplate(String name) {
return getTemplateReader(getFullTemplateFile(config, name + ".mustache"));
File written = processTemplateToFile(models, templateName, filename);
if (written != null) {
files.add(written);
}
}
})
.defaultValue("")
.compile(template);
writeToFile(filename, tmpl.execute(models));
files.add(new File(filename));
}
} catch (Exception e) {
throw new RuntimeException("Could not generate model '" + name + "'", e);
@ -401,22 +423,13 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
continue;
}
String templateFile = getFullTemplateFile(config, templateName);
String template = readTemplate(templateFile);
Template tmpl = Mustache.compiler()
.withLoader(new Mustache.TemplateLoader() {
@Override
public Reader getTemplate(String name) {
return getTemplateReader(getFullTemplateFile(config, name + ".mustache"));
File written = processTemplateToFile(operation, templateName, filename);
if(written != null) {
files.add(written);
}
})
.defaultValue("")
.compile(template);
writeToFile(filename, tmpl.execute(operation));
files.add(new File(filename));
}
if(generateApiTests) {
// to generate api test files
for (String templateName : config.apiTestTemplateFiles().keySet()) {
String filename = config.apiTestFilename(templateName, tag);
@ -425,22 +438,16 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
LOGGER.info("File exists. Skipped overwriting " + filename);
continue;
}
String templateFile = getFullTemplateFile(config, templateName);
String template = readTemplate(templateFile);
Template tmpl = Mustache.compiler()
.withLoader(new Mustache.TemplateLoader() {
@Override
public Reader getTemplate(String name) {
return getTemplateReader(getFullTemplateFile(config, name + ".mustache"));
}
})
.defaultValue("")
.compile(template);
writeToFile(filename, tmpl.execute(operation));
files.add(new File(filename));
File written = processTemplateToFile(operation, templateName, filename);
if (written != null) {
files.add(written);
}
}
}
if(generateApiDocumentation) {
// to generate api documentation files
for (String templateName : config.apiDocTemplateFiles().keySet()) {
String filename = config.apiDocFilename(templateName, tag);
@ -449,20 +456,11 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
continue;
}
String templateFile = getFullTemplateFile(config, templateName);
String template = readTemplate(templateFile);
Template tmpl = Mustache.compiler()
.withLoader(new Mustache.TemplateLoader() {
@Override
public Reader getTemplate(String name) {
return getTemplateReader(getFullTemplateFile(config, name + ".mustache"));
File written = processTemplateToFile(operation, templateName, filename);
if (written != null) {
files.add(written);
}
}
})
.defaultValue("")
.compile(template);
writeToFile(filename, tmpl.execute(operation));
files.add(new File(filename));
}
} catch (Exception e) {
@ -488,6 +486,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
bundle.put("swagger", this.swagger);
bundle.put("basePath", basePath);
bundle.put("basePathWithoutHost",basePathWithoutHost);
bundle.put("scheme", scheme);
bundle.put("contextPath", contextPath);
bundle.put("apiInfo", apis);
@ -544,6 +543,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
}
if(shouldGenerate) {
if(ignoreProcessor.allowsFile(new File(outputFilename))) {
if (templateFile.endsWith("mustache")) {
String template = readTemplate(templateFile);
Template tmpl = Mustache.compiler()
@ -581,16 +581,57 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
files.add(outputFile);
}
} else {
LOGGER.info("Skipped generation of " + outputFilename + " due to rule in .swagger-codegen-ignore");
}
}
} catch (Exception e) {
throw new RuntimeException("Could not generate supporting file '" + support + "'", e);
}
}
// Consider .swagger-codegen-ignore a supporting file
// Output .swagger-codegen-ignore if it doesn't exist and wasn't explicitly created by a generator
final String swaggerCodegenIgnore = ".swagger-codegen-ignore";
String ignoreFileNameTarget = config.outputFolder() + File.separator + swaggerCodegenIgnore;
File ignoreFile = new File(ignoreFileNameTarget);
if(!ignoreFile.exists()) {
String ignoreFileNameSource = File.separator + config.getCommonTemplateDir() + File.separator + swaggerCodegenIgnore;
String ignoreFileContents = readResourceContents(ignoreFileNameSource);
try {
writeToFile(ignoreFileNameTarget, ignoreFileContents);
} catch (IOException e) {
throw new RuntimeException("Could not generate supporting file '" + swaggerCodegenIgnore + "'", e);
}
files.add(ignoreFile);
}
}
config.processSwagger(swagger);
return files;
}
private File processTemplateToFile(Map<String, Object> templateData, String templateName, String outputFilename) throws IOException {
if(ignoreProcessor.allowsFile(new File(outputFilename.replaceAll("//", "/")))) {
String templateFile = getFullTemplateFile(config, templateName);
String template = readTemplate(templateFile);
Template tmpl = Mustache.compiler()
.withLoader(new Mustache.TemplateLoader() {
@Override
public Reader getTemplate(String name) {
return getTemplateReader(getFullTemplateFile(config, name + ".mustache"));
}
})
.defaultValue("")
.compile(template);
writeToFile(outputFilename, tmpl.execute(templateData));
return new File(outputFilename);
}
LOGGER.info("Skipped generation of " + outputFilename + " due to rule in .swagger-codegen-ignore");
return null;
}
private static void processMimeTypes(List<String> mimeTypeList, Map<String, Object> operation, String source) {
if (mimeTypeList != null && mimeTypeList.size() > 0) {
List<Map<String, String>> c = new ArrayList<Map<String, String>>();

View File

@ -0,0 +1,134 @@
package io.swagger.codegen.ignore;
import com.google.common.collect.ImmutableList;
import io.swagger.codegen.ignore.rules.DirectoryRule;
import io.swagger.codegen.ignore.rules.Rule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class CodegenIgnoreProcessor {
private static final Logger LOGGER = LoggerFactory.getLogger(CodegenIgnoreProcessor.class);
private final String outputPath;
private List<Rule> exclusionRules = new ArrayList<>();
private List<Rule> inclusionRules = new ArrayList<>();
public CodegenIgnoreProcessor(String outputPath) {
this.outputPath = outputPath;
final File directory = new File(outputPath);
if(directory.exists() && directory.isDirectory()){
final File codegenIgnore = new File(directory, ".swagger-codegen-ignore");
if(codegenIgnore.exists() && codegenIgnore.isFile()){
try {
loadCodegenRules(codegenIgnore);
} catch (IOException e) {
LOGGER.error("Could not process .swagger-codegen-ignore.", e.getMessage());
}
} else {
// log info message
LOGGER.info("No .swagger-codegen-ignore file found.");
}
}
}
void loadCodegenRules(File codegenIgnore) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(codegenIgnore))) {
String line;
// NOTE: Comments that start with a : (e.g. //:) are pulled from git documentation for .gitignore
// see: https://github.com/git/git/blob/90f7b16b3adc78d4bbabbd426fb69aa78c714f71/Documentation/gitignore.txt
while ((line = reader.readLine()) != null) {
if(
//: A blank line matches no files, so it can serve as a separator for readability.
line.length() == 0
) continue;
Rule rule = Rule.create(line);
// rule could be null here if it's a COMMENT, for example
if(rule != null) {
if (Boolean.TRUE.equals(rule.getNegated())) {
inclusionRules.add(rule);
} else {
exclusionRules.add(rule);
}
}
}
}
}
public boolean allowsFile(File targetFile) {
File file = new File(new File(this.outputPath).toURI().relativize(targetFile.toURI()).getPath());
Boolean directoryExcluded = false;
Boolean exclude = false;
if(exclusionRules.size() == 0 && inclusionRules.size() == 0) {
return true;
}
// NOTE: We *must* process all exclusion rules
for (int i = 0; i < exclusionRules.size(); i++) {
Rule current = exclusionRules.get(i);
Rule.Operation op = current.evaluate(file.getPath());
switch (op){
case EXCLUDE:
exclude = true;
// Include rule can't override rules that exclude a file by some parent directory.
if(current instanceof DirectoryRule) {
directoryExcluded = true;
}
break;
case INCLUDE:
// This won't happen here.
break;
case NOOP:
break;
case EXCLUDE_AND_TERMINATE:
i = exclusionRules.size();
break;
}
}
if(exclude) {
// Only need to process inclusion rules if we've been excluded
for (int i = 0; exclude && i < inclusionRules.size(); i++) {
Rule current = inclusionRules.get(i);
Rule.Operation op = current.evaluate(file.getPath());
// At this point exclude=true means the file should be ignored.
// op == INCLUDE means we have to flip that flag.
if(op.equals(Rule.Operation.INCLUDE)) {
if(current instanceof DirectoryRule && directoryExcluded) {
// e.g
// baz/
// !foo/bar/baz/
// NOTE: Possibly surprising side effect:
// foo/bar/baz/
// !bar/
exclude = false;
} else if (!directoryExcluded) {
// e.g.
// **/*.log
// !ISSUE_1234.log
exclude = false;
}
}
}
}
return Boolean.FALSE.equals(exclude);
}
public List<Rule> getInclusionRules() {
return ImmutableList.copyOf(inclusionRules);
}
public List<Rule> getExclusionRules() {
return ImmutableList.copyOf(exclusionRules);
}
}

View File

@ -0,0 +1,20 @@
package io.swagger.codegen.ignore.rules;
import java.nio.file.FileSystems;
import java.nio.file.PathMatcher;
import java.util.List;
public class DirectoryRule extends FileRule {
private PathMatcher matcher = null;
DirectoryRule(List<Part> syntax, String definition) {
super(syntax, definition);
matcher = FileSystems.getDefault().getPathMatcher("glob:**/"+this.getPattern());
}
@Override
public Boolean matches(String relativePath) {
return matcher.matches(FileSystems.getDefault().getPath(relativePath));
}
}

View File

@ -0,0 +1,20 @@
package io.swagger.codegen.ignore.rules;
import java.util.List;
/**
* An ignore rule which matches everything.
*/
public class EverythingRule extends Rule {
EverythingRule(List<Part> syntax, String definition) {
super(syntax, definition);
}
@Override
public Boolean matches(String relativePath) {
return true;
}
@Override
protected Operation getExcludeOperation(){ return Operation.EXCLUDE_AND_TERMINATE; }
}

View File

@ -0,0 +1,20 @@
package io.swagger.codegen.ignore.rules;
import java.nio.file.FileSystems;
import java.nio.file.PathMatcher;
import java.util.List;
public class FileRule extends Rule {
private PathMatcher matcher = null;
FileRule(List<Part> syntax, String definition) {
super(syntax, definition);
matcher = FileSystems.getDefault().getPathMatcher("glob:"+this.getPattern());
}
@Override
public Boolean matches(String relativePath) {
return matcher.matches(FileSystems.getDefault().getPath(relativePath));
}
}

View File

@ -0,0 +1,134 @@
package io.swagger.codegen.ignore.rules;
import java.util.ArrayList;
import java.util.List;
public class IgnoreLineParser {
enum Token {
MATCH_ALL("**"),
MATCH_ANY("*"),
ESCAPED_EXCLAMATION("\\!"),
ESCAPED_SPACE("\\ "),
PATH_DELIM("/"),
NEGATE("!"),
TEXT(null),
DIRECTORY_MARKER("/"),
ROOTED_MARKER("/"),
COMMENT(null);
private String pattern;
Token(String pattern) {
this.pattern = pattern;
}
public String getPattern() {
return pattern;
}
}
// NOTE: Comments that start with a : (e.g. //:) are pulled from git documentation for .gitignore
// see: https://github.com/git/git/blob/90f7b16b3adc78d4bbabbd426fb69aa78c714f71/Documentation/gitignore.txt
static List<Part> parse(String text) throws ParserException {
List<Part> parts = new ArrayList<>();
StringBuilder sb = new StringBuilder();
String current = null;
String next = null;
char[] characters = text.toCharArray();
for (int i = 0, totalLength = characters.length; i < totalLength; i++) {
char character = characters[i];
current = String.valueOf(character);
next = i < totalLength - 1 ? String.valueOf(characters[i + 1]) : null;
if (i == 0) {
if ("#".equals(current)) {
//: A line starting with # serves as a comment.
parts.add(new Part(Token.COMMENT, text));
i = totalLength; // rather than early return
continue;
} else if ("!".equals(current)) {
if (i == totalLength - 1) {
throw new ParserException("Negation with no negated pattern.");
} else {
parts.add(new Part(Token.NEGATE));
continue;
}
} else if ("\\".equals(current) && "#".equals(next)) {
//: Put a backslash ("`\`") in front of the first hash for patterns
//: that begin with a hash.
// NOTE: Just push forward and drop the escape character. Falls through to TEXT token.
current = next;
next = null;
i++;
}
}
if (Token.MATCH_ANY.pattern.equals(current)) {
if (Token.MATCH_ANY.pattern.equals(next)) {
// peek ahead for invalid pattern. Slightly inefficient, but acceptable.
if ((i+2 < totalLength - 1) &&
String.valueOf(characters[i+2]).equals(Token.MATCH_ANY.pattern)) {
// It doesn't matter where we are in the pattern, *** is invalid.
throw new ParserException("The pattern *** is invalid.");
}
parts.add(new Part(Token.MATCH_ALL));
i++;
continue;
} else {
parts.add(new Part(Token.MATCH_ANY));
continue;
}
}
if (i == 0 && Token.ROOTED_MARKER.pattern.equals(current)) {
parts.add(new Part(Token.ROOTED_MARKER));
continue;
}
if ("\\".equals(current) && " ".equals(next)) {
parts.add(new Part(Token.ESCAPED_SPACE));
i++;
continue;
} else if ("\\".equals(current) && "!".equals(next)) {
parts.add(new Part(Token.ESCAPED_EXCLAMATION));
i++;
continue;
}
if (Token.PATH_DELIM.pattern.equals(current)) {
if (i != totalLength - 1) {
if (sb.length() > 0) {
parts.add(new Part(Token.TEXT, sb.toString()));
sb.delete(0, sb.length());
}
parts.add(new Part(Token.PATH_DELIM));
if(Token.PATH_DELIM.pattern.equals(next)) {
// ignore doubled path delims. NOTE: doesn't do full lookahead, so /// will result in //
i++;
}
continue;
} else if (i == totalLength - 1) {
parts.add(new Part(Token.TEXT, sb.toString()));
sb.delete(0, sb.length());
parts.add(new Part(Token.DIRECTORY_MARKER));
continue;
}
}
sb.append(current);
}
if (sb.length() > 0) {
// NOTE: All spaces escaped spaces are a special token, ESCAPED_SPACE
//: Trailing spaces are ignored unless they are quoted with backslash ("`\`")
parts.add(new Part(Token.TEXT, sb.toString().trim()));
}
return parts;
}
}

View File

@ -0,0 +1,26 @@
package io.swagger.codegen.ignore.rules;
import java.util.List;
public class InvalidRule extends Rule {
private final String reason;
InvalidRule(List<Part> syntax, String definition, String reason) {
super(syntax, definition);
this.reason = reason;
}
@Override
public Boolean matches(String relativePath) {
return null;
}
@Override
public Operation evaluate(String relativePath) {
return Operation.NOOP;
}
public String getReason() {
return reason;
}
}

View File

@ -0,0 +1,15 @@
package io.swagger.codegen.ignore.rules;
public class ParserException extends Exception {
/**
* Constructs a new exception with the specified detail message. The
* cause is not initialized, and may subsequently be initialized by
* a call to {@link #initCause}.
*
* @param message the detail message. The detail message is saved for
* later retrieval by the {@link #getMessage()} method.
*/
public ParserException(String message) {
super(message);
}
}

View File

@ -0,0 +1,24 @@
package io.swagger.codegen.ignore.rules;
class Part {
private final IgnoreLineParser.Token token;
private final String value;
public Part(IgnoreLineParser.Token token, String value) {
this.token = token;
this.value = value;
}
public Part(IgnoreLineParser.Token token) {
this.token = token;
this.value = token.getPattern();
}
public IgnoreLineParser.Token getToken() {
return token;
}
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,58 @@
package io.swagger.codegen.ignore.rules;
import java.util.List;
import java.util.regex.Pattern;
/**
* A special case rule which matches files only if they're located
* in the same directory as the .swagger-codegen-ignore file.
*/
public class RootedFileRule extends Rule {
private String definedFilename = null;
private String definedExtension = null;
RootedFileRule(List<Part> syntax, String definition) {
super(syntax, definition);
int separatorIndex = definition.lastIndexOf(".");
definedFilename = getFilenamePart(definition, separatorIndex);
definedExtension = getExtensionPart(definition, separatorIndex);
}
private String getFilenamePart(final String input, int stopIndex){
return input.substring('/' == input.charAt(0) ? 1 : 0, stopIndex > 0 ? stopIndex : input.length());
}
private String getExtensionPart(final String input, int stopIndex) {
return input.substring(stopIndex > 0 ? stopIndex+1: input.length(), input.length());
}
@Override
public Boolean matches(String relativePath) {
// NOTE: Windows-style separator isn't supported, so File.pathSeparator would be incorrect here.
// NOTE: lastIndexOf rather than contains because /file.txt is acceptable while path/file.txt is not.
// relativePath will be passed by CodegenIgnoreProcessor and is relative to .codegen-ignore.
boolean isSingleFile = relativePath.lastIndexOf("/") <= 0;
if(isSingleFile) {
int separatorIndex = relativePath.lastIndexOf(".");
final String filename = getFilenamePart(relativePath, separatorIndex);
final String extension = getExtensionPart(relativePath, separatorIndex);
boolean extensionMatches = definedExtension.equals(extension) || definedExtension.equals(IgnoreLineParser.Token.MATCH_ANY.getPattern());
if(extensionMatches && definedFilename.contains(IgnoreLineParser.Token.MATCH_ANY.getPattern())) {
// TODO: Evaluate any other escape requirements here.
Pattern regex = Pattern.compile(
definedFilename
.replaceAll(Pattern.quote("."), "\\\\Q.\\\\E")
.replaceAll(Pattern.quote("*"), ".*?") // non-greedy match on 0+ any character
);
return regex.matcher(filename).matches();
}
return extensionMatches && definedFilename.equals(filename);
}
return false;
}
}

View File

@ -0,0 +1,175 @@
package io.swagger.codegen.ignore.rules;
import java.util.List;
public abstract class Rule {
public enum Operation {EXCLUDE, INCLUDE, NOOP, EXCLUDE_AND_TERMINATE}
// The original rule
private final String definition;
private final List<Part> syntax;
Rule(List<Part> syntax, String definition) {
this.syntax = syntax;
this.definition = definition;
}
public abstract Boolean matches(String relativePath);
public String getDefinition() {
return this.definition;
}
protected String getPattern() {
if(syntax == null) return this.definition;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < syntax.size(); i++) {
Part current = syntax.get(i);
switch(current.getToken()){
case MATCH_ALL:
case MATCH_ANY:
case ESCAPED_EXCLAMATION:
case ESCAPED_SPACE:
case PATH_DELIM:
case TEXT:
case DIRECTORY_MARKER:
sb.append(current.getValue());
break;
case NEGATE:
case ROOTED_MARKER:
case COMMENT:
break;
}
}
return sb.toString();
}
/**
* Whether or not the rule should be negated. !foo means foo should be removed from previous matches.
* Example: **\/*.bak excludes all backup. Adding !/test.bak will include test.bak in the project root.
* <p>
* NOTE: It is not possible to re-include a file if a parent directory of that file is excluded.
*/
public Boolean getNegated() {
return this.syntax != null && this.syntax.size() > 0 && this.syntax.get(0).getToken() == IgnoreLineParser.Token.NEGATE;
}
public Operation evaluate(String relativePath) {
if (Boolean.TRUE.equals(matches(relativePath))) {
if(Boolean.TRUE.equals(this.getNegated())) {
return this.getIncludeOperation();
}
return this.getExcludeOperation();
}
return Operation.NOOP;
}
protected Operation getIncludeOperation(){ return Operation.INCLUDE; }
protected Operation getExcludeOperation(){ return Operation.EXCLUDE; }
public static Rule create(String definition) {
// NOTE: Comments that start with a : (e.g. //:) are pulled from git documentation for .gitignore
// see: https://github.com/git/git/blob/90f7b16b3adc78d4bbabbd426fb69aa78c714f71/Documentation/gitignore.txt
Rule rule = null;
if (definition.equals(".")) {
return new InvalidRule(null, definition, "Pattern '.' is invalid.");
} else if (definition.equals("!.")) {
return new InvalidRule(null, definition, "Pattern '!.' is invalid.");
} else if (definition.startsWith("..")) {
return new InvalidRule(null, definition, "Pattern '..' is invalid.");
}
try {
List<Part> result = IgnoreLineParser.parse(definition);
Boolean directoryOnly = null;
if (result.size() == 0) {
return rule;
} else if (result.size() == 1) {
// single-character filename only
Part part = result.get(0);
if (IgnoreLineParser.Token.MATCH_ANY.equals(part.getToken())) {
rule = new RootedFileRule(result, definition);
} else {
rule = new FileRule(result, definition);
}
} else {
IgnoreLineParser.Token head = result.get(0).getToken();
//: An optional prefix "`!`" which negates the pattern; any
//: matching file excluded by a previous pattern will become
//: included again. It is not possible to re-include a file if a parent
//: directory of that file is excluded. Git doesn't list excluded
//: directories for performance reasons, so any patterns on contained
//: files have no effect, no matter where they are defined.
//: Put a backslash ("`\`") in front of the first "`!`" for patterns
//: that begin with a literal "`!`", for example, "`\!important!.txt`".
// see this.getNegated();
//: If the pattern ends with a slash, it is removed for the
//: purpose of the following description, but it would only find
//: a match with a directory. In other words, `foo/` will match a
//: directory `foo` and paths underneath it, but will not match a
//: regular file or a symbolic link `foo` (this is consistent
//: with the way how pathspec works in general in Git).
directoryOnly = IgnoreLineParser.Token.DIRECTORY_MARKER.equals(result.get(result.size() - 1).getToken());
if (directoryOnly) {
rule = new DirectoryRule(result, definition);
} else if (IgnoreLineParser.Token.PATH_DELIM.equals(head)) {
//: A leading slash matches the beginning of the pathname.
//: For example, "/{asterisk}.c" matches "cat-file.c" but not
//: "mozilla-sha1/sha1.c".
rule = new RootedFileRule(result, definition);
} else {
// case 1
//: If the pattern does not contain a slash '/', Git treats it as
//: a shell glob pattern and checks for a match against the
//: pathname relative to the location of the `.gitignore` file
//: (relative to the toplevel of the work tree if not from a
//: `.gitignore` file).
// case 2
//: Otherwise, Git treats the pattern as a shell glob suitable
//: for consumption by fnmatch(3) with the FNM_PATHNAME flag:
//: wildcards in the pattern will not match a / in the pathname.
//: For example, "Documentation/{asterisk}.html" matches
//: "Documentation/git.html" but not "Documentation/ppc/ppc.html"
//: or "tools/perf/Documentation/perf.html".
// case 3
//: Two consecutive asterisks ("`**`") in patterns matched against
//: full pathname may have special meaning:
//:
//: - A leading "`**`" followed by a slash means match in all
//: directories. For example, "`**/foo`" matches file or directory
//: "`foo`" anywhere, the same as pattern "`foo`". "`**/foo/bar`"
//: matches file or directory "`bar`" anywhere that is directly
//: under directory "`foo`".
//:
//: - A trailing "`/**`" matches everything inside. For example,
//: "`abc/**`" matches all files inside directory "`abc`", relative
//: to the location of the `.gitignore` file, with infinite depth.
//:
//: - A slash followed by two consecutive asterisks then a slash
//: matches zero or more directories. For example, "`a/**/b`"
//: matches "`a/b`", "`a/x/b`", "`a/x/y/b`" and so on.
//:
//: - Other consecutive asterisks are considered invalid.
rule = new FileRule(result, definition);
}
}
} catch (ParserException e) {
e.printStackTrace();
return new InvalidRule(null, definition, e.getMessage());
}
return rule;
}
}

View File

@ -23,6 +23,7 @@ public abstract class AbstractJavaJAXRSServerCodegen extends JavaClientCodegen
public AbstractJavaJAXRSServerCodegen()
{
super();
apiTestTemplateFiles.clear(); // TODO: add test template
}
@Override

View File

@ -1,13 +1,24 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.models.properties.*;
import java.util.*;
import java.io.File;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.FileProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String modelPropertyNaming= "camelCase";

View File

@ -33,6 +33,7 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
// requestPackage and authPackage are used by the "volley" template/library
protected String requestPackage = "io.swagger.client.request";
protected String authPackage = "io.swagger.client.auth";
protected String gradleWrapperPackage = "gradle.wrapper";
protected String apiDocPath = "docs/";
protected String modelDocPath = "docs/";
@ -89,8 +90,8 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
cliOptions.add(CliOption.newBoolean(USE_ANDROID_MAVEN_GRADLE_PLUGIN, "A flag to toggle android-maven gradle plugin.")
.defaultValue(Boolean.TRUE.toString()));
supportedLibraries.put("<default>", "HTTP client: Apache HttpClient 4.3.6. JSON processing: Gson 2.3.1");
supportedLibraries.put("volley", "HTTP client: Volley 1.0.19");
supportedLibraries.put("volley", "HTTP client: Volley 1.0.19 (default)");
supportedLibraries.put("httpclient", "HTTP client: Apache HttpClient 4.3.6. JSON processing: Gson 2.3.1. IMPORTANT: Android client using HttpClient is not actively maintained and will be depecreated in the next major release.");
CliOption library = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use");
library.setEnum(supportedLibraries);
cliOptions.add(library);
@ -382,23 +383,26 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
additionalProperties.put( "modelDocPath", modelDocPath );
if (StringUtils.isEmpty(getLibrary())) {
modelDocTemplateFiles.put( "model_doc.mustache", ".md" );
apiDocTemplateFiles.put( "api_doc.mustache", ".md" );
//supportingFiles.add(new SupportingFile("api_doc.mustache", apiDocPath, "api.md"));
//supportingFiles.add(new SupportingFile("model_doc.mustache", modelDocPath, "model.md"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
addSupportingFilesForDefault();
} else if ("volley".equals(getLibrary())) {
modelDocTemplateFiles.put( "model_doc.mustache", ".md" );
apiDocTemplateFiles.put( "api_doc.mustache", ".md" );
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
//supportingFiles.add(new SupportingFile("api_doc.mustache", apiDocPath, "api.md"));
//supportingFiles.add(new SupportingFile("model_doc.mustache", modelDocPath, "model.md"));
addSupportingFilesForVolley();
}
setLibrary("volley"); // set volley as the default library
}
private void addSupportingFilesForDefault() {
// determine which file (mustache) to add based on library
if ("volley".equals(getLibrary())) {
addSupportingFilesForVolley();
} else if ("httpclient".equals(getLibrary())) {
addSupportingFilesForHttpClient();
} else {
throw new IllegalArgumentException("Invalid 'library' option specified: '" + getLibrary() + "'. Must be 'httpclient' or 'volley' (default)");
}
}
private void addSupportingFilesForHttpClient() {
// documentation files
modelDocTemplateFiles.put( "model_doc.mustache", ".md" );
apiDocTemplateFiles.put( "api_doc.mustache", ".md" );
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle"));
supportingFiles.add(new SupportingFile("build.mustache", "", "build.gradle"));
@ -415,9 +419,25 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
(sourceFolder + File.separator + invokerPackage).replace(".", File.separator), "Pair.java"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
// gradle wrapper files
supportingFiles.add(new SupportingFile( "gradlew.mustache", "", "gradlew" ));
supportingFiles.add(new SupportingFile( "gradlew.bat.mustache", "", "gradlew.bat" ));
supportingFiles.add(new SupportingFile( "gradle-wrapper.properties.mustache",
gradleWrapperPackage.replace(".", File.separator), "gradle-wrapper.properties" ));
supportingFiles.add(new SupportingFile( "gradle-wrapper.jar",
gradleWrapperPackage.replace(".", File.separator), "gradle-wrapper.jar" ));
}
private void addSupportingFilesForVolley() {
// documentation files
modelDocTemplateFiles.put( "model_doc.mustache", ".md" );
apiDocTemplateFiles.put( "api_doc.mustache", ".md" );
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
// supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle"));
supportingFiles.add(new SupportingFile("build.mustache", "", "build.gradle"));
@ -446,6 +466,14 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
(sourceFolder + File.separator + authPackage).replace(".", File.separator), "HttpBasicAuth.java"));
supportingFiles.add(new SupportingFile("auth/authentication.mustache",
(sourceFolder + File.separator + authPackage).replace(".", File.separator), "Authentication.java"));
// gradle wrapper files
supportingFiles.add(new SupportingFile( "gradlew.mustache", "", "gradlew" ));
supportingFiles.add(new SupportingFile( "gradlew.bat.mustache", "", "gradlew.bat" ));
supportingFiles.add(new SupportingFile( "gradle-wrapper.properties.mustache",
gradleWrapperPackage.replace(".", File.separator), "gradle-wrapper.properties" ));
supportingFiles.add(new SupportingFile( "gradle-wrapper.jar",
gradleWrapperPackage.replace(".", File.separator), "gradle-wrapper.jar" ));
}
public Boolean getUseAndroidMavenGradlePlugin() {

View File

@ -137,6 +137,11 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
@Override
public void processOpts() {
super.processOpts();
Boolean excludeTests = false;
if(additionalProperties.containsKey(CodegenConstants.EXCLUDE_TESTS)) {
excludeTests = Boolean.valueOf(additionalProperties.get(CodegenConstants.EXCLUDE_TESTS).toString());
}
apiPackage = "Api";
modelPackage = "Model";
@ -218,6 +223,8 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
binRelativePath += "vendor";
additionalProperties.put("binRelativePath", binRelativePath);
supportingFiles.add(new SupportingFile("IApiAccessor.mustache",
clientPackageDir, "IApiAccessor.cs"));
supportingFiles.add(new SupportingFile("Configuration.mustache",
clientPackageDir, "Configuration.cs"));
supportingFiles.add(new SupportingFile("ApiClient.mustache",
@ -232,7 +239,10 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
// copy package.config to nuget's standard location for project-level installs
supportingFiles.add(new SupportingFile("packages.config.mustache", packageFolder + File.separator, "packages.config"));
if(Boolean.FALSE.equals(excludeTests)) {
supportingFiles.add(new SupportingFile("packages_test.config.mustache", testPackageFolder + File.separator, "packages.config"));
}
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
@ -245,12 +255,10 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
supportingFiles.add(new SupportingFile("Solution.mustache", "", packageName + ".sln"));
supportingFiles.add(new SupportingFile("Project.mustache", packageFolder, packageName + ".csproj"));
// TODO: Check if test project output is enabled, partially related to #2506. Should have options for:
// 1) No test project
// 2) No model tests
// 3) No api tests
if(Boolean.FALSE.equals(excludeTests)) {
supportingFiles.add(new SupportingFile("TestProject.mustache", testPackageFolder, testPackageName + ".csproj"));
}
}
additionalProperties.put("apiDocPath", apiDocPath);
additionalProperties.put("modelDocPath", modelDocPath);

View File

@ -146,6 +146,7 @@ public class GoClientCodegen extends DefaultCodegen implements CodegenConfig {
supportingFiles.add(new SupportingFile("configuration.mustache", "", "configuration.go"));
supportingFiles.add(new SupportingFile("api_client.mustache", "", "api_client.go"));
supportingFiles.add(new SupportingFile("api_response.mustache", "", "api_response.go"));
supportingFiles.add(new SupportingFile(".travis.yml", "", ".travis.yml"));
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
}

View File

@ -19,6 +19,7 @@ public class GroovyClientCodegen extends JavaClientCodegen {
outputFolder = "generated-code/groovy";
modelTemplateFiles.put("model.mustache", ".groovy");
apiTemplateFiles.put(templateFileName, ".groovy");
apiTestTemplateFiles.clear(); // TODO: add test template
embeddedTemplateDir = templateDir = "Groovy";
apiPackage = "io.swagger.api";

View File

@ -36,7 +36,10 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String artifactId = "swagger-java-client";
protected String artifactVersion = "1.0.0";
protected String projectFolder = "src" + File.separator + "main";
protected String projectTestFolder = "src" + File.separator + "test";
protected String sourceFolder = projectFolder + File.separator + "java";
protected String testFolder = projectTestFolder + File.separator + "java";
protected String gradleWrapperPackage = "gradle.wrapper";
protected String localVariablePrefix = "";
protected boolean fullJavaUtil;
protected String javaUtilPrefix = "";
@ -52,6 +55,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
outputFolder = "generated-code" + File.separator + "java";
modelTemplateFiles.put("model.mustache", ".java");
apiTemplateFiles.put("api.mustache", ".java");
apiTestTemplateFiles.put("api_test.mustache", ".java");
embeddedTemplateDir = templateDir = "Java";
apiPackage = "io.swagger.client.api";
modelPackage = "io.swagger.client.model";
@ -107,12 +111,12 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
cliOptions.add(CliOption.newBoolean(USE_RX_JAVA, "Whether to use the RxJava adapter with the retrofit2 library."));
cliOptions.add(new CliOption("hideGenerationTimestamp", "hides the timestamp when files were generated"));
supportedLibraries.put(DEFAULT_LIBRARY, "HTTP client: Jersey client 1.18. JSON processing: Jackson 2.4.2");
supportedLibraries.put("feign", "HTTP client: Netflix Feign 8.1.1");
supportedLibraries.put("jersey2", "HTTP client: Jersey client 2.6");
supportedLibraries.put("okhttp-gson", "HTTP client: OkHttp 2.4.0. JSON processing: Gson 2.3.1");
supportedLibraries.put(RETROFIT_1, "HTTP client: OkHttp 2.4.0. JSON processing: Gson 2.3.1 (Retrofit 1.9.0)");
supportedLibraries.put(RETROFIT_2, "HTTP client: OkHttp 2.5.0. JSON processing: Gson 2.4 (Retrofit 2.0.1). Enable the RxJava adapter using '-DuseRxJava=true'. (RxJava 1.1.2)");
supportedLibraries.put(DEFAULT_LIBRARY, "HTTP client: Jersey client 1.19.1. JSON processing: Jackson 2.7.0");
supportedLibraries.put("feign", "HTTP client: Netflix Feign 8.16.0. JSON processing: Jackson 2.7.0");
supportedLibraries.put("jersey2", "HTTP client: Jersey client 2.22.2. JSON processing: Jackson 2.7.0");
supportedLibraries.put("okhttp-gson", "HTTP client: OkHttp 2.7.5. JSON processing: Gson 2.6.2");
supportedLibraries.put(RETROFIT_1, "HTTP client: OkHttp 2.7.5. JSON processing: Gson 2.3.1 (Retrofit 1.9.0)");
supportedLibraries.put(RETROFIT_2, "HTTP client: OkHttp 3.2.0. JSON processing: Gson 2.6.1 (Retrofit 2.0.2). Enable the RxJava adapter using '-DuseRxJava=true'. (RxJava 1.1.3)");
CliOption library = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use");
library.setDefault(DEFAULT_LIBRARY);
@ -263,6 +267,14 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
final String authFolder = (sourceFolder + '/' + invokerPackage + ".auth").replace(".", "/");
if ("feign".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("FormAwareEncoder.mustache", invokerFolder, "FormAwareEncoder.java"));
//gradleWrapper files
supportingFiles.add( new SupportingFile( "gradlew.mustache", "", "gradlew") );
supportingFiles.add( new SupportingFile( "gradlew.bat.mustache", "", "gradlew.bat") );
supportingFiles.add( new SupportingFile( "gradle-wrapper.properties.mustache",
gradleWrapperPackage.replace( ".", File.separator ), "gradle-wrapper.properties") );
supportingFiles.add( new SupportingFile( "gradle-wrapper.jar",
gradleWrapperPackage.replace( ".", File.separator ), "gradle-wrapper.jar") );
}
supportingFiles.add(new SupportingFile("auth/HttpBasicAuth.mustache", authFolder, "HttpBasicAuth.java"));
supportingFiles.add(new SupportingFile("auth/ApiKeyAuth.mustache", authFolder, "ApiKeyAuth.java"));
@ -281,6 +293,14 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
// generate markdown docs
modelDocTemplateFiles.put("model_doc.mustache", ".md");
apiDocTemplateFiles.put("api_doc.mustache", ".md");
//gradleWrapper files
supportingFiles.add( new SupportingFile( "gradlew.mustache", "", "gradlew") );
supportingFiles.add( new SupportingFile( "gradlew.bat.mustache", "", "gradlew.bat") );
supportingFiles.add( new SupportingFile( "gradle-wrapper.properties.mustache",
gradleWrapperPackage.replace( ".", File.separator ), "gradle-wrapper.properties") );
supportingFiles.add( new SupportingFile( "gradle-wrapper.jar",
gradleWrapperPackage.replace( ".", File.separator ), "gradle-wrapper.jar") );
} else if ("okhttp-gson".equals(getLibrary())) {
// generate markdown docs
modelDocTemplateFiles.put("model_doc.mustache", ".md");
@ -293,14 +313,38 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
supportingFiles.add(new SupportingFile("ProgressResponseBody.mustache", invokerFolder, "ProgressResponseBody.java"));
// "build.sbt" is for development with SBT
supportingFiles.add(new SupportingFile("build.sbt.mustache", "", "build.sbt"));
//gradleWrapper files
supportingFiles.add( new SupportingFile( "gradlew.mustache", "", "gradlew") );
supportingFiles.add( new SupportingFile( "gradlew.bat.mustache", "", "gradlew.bat") );
supportingFiles.add( new SupportingFile( "gradle-wrapper.properties.mustache",
gradleWrapperPackage.replace( ".", File.separator ), "gradle-wrapper.properties") );
supportingFiles.add( new SupportingFile( "gradle-wrapper.jar",
gradleWrapperPackage.replace( ".", File.separator ), "gradle-wrapper.jar") );
} else if (usesAnyRetrofitLibrary()) {
supportingFiles.add(new SupportingFile("auth/OAuthOkHttpClient.mustache", authFolder, "OAuthOkHttpClient.java"));
supportingFiles.add(new SupportingFile("CollectionFormats.mustache", invokerFolder, "CollectionFormats.java"));
//gradleWrapper files
supportingFiles.add( new SupportingFile( "gradlew.mustache", "", "gradlew") );
supportingFiles.add( new SupportingFile( "gradlew.bat.mustache", "", "gradlew.bat") );
supportingFiles.add( new SupportingFile( "gradle-wrapper.properties.mustache",
gradleWrapperPackage.replace( ".", File.separator ), "gradle-wrapper.properties") );
supportingFiles.add( new SupportingFile( "gradle-wrapper.jar",
gradleWrapperPackage.replace( ".", File.separator ), "gradle-wrapper.jar") );
} else if("jersey2".equals(getLibrary())) {
// generate markdown docs
modelDocTemplateFiles.put("model_doc.mustache", ".md");
apiDocTemplateFiles.put("api_doc.mustache", ".md");
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
//gradleWrapper files
supportingFiles.add( new SupportingFile( "gradlew.mustache", "", "gradlew") );
supportingFiles.add( new SupportingFile( "gradlew.bat.mustache", "", "gradlew.bat") );
supportingFiles.add( new SupportingFile( "gradle-wrapper.properties.mustache",
gradleWrapperPackage.replace( ".", File.separator ), "gradle-wrapper.properties") );
supportingFiles.add( new SupportingFile( "gradle-wrapper.jar",
gradleWrapperPackage.replace( ".", File.separator ), "gradle-wrapper.jar") );
}
if(additionalProperties.containsKey(DATE_LIBRARY)) {
@ -366,6 +410,11 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', '/');
}
@Override
public String apiTestFileFolder() {
return outputFolder + "/" + testFolder + "/" + apiPackage().replace('.', '/');
}
@Override
public String modelFileFolder() {
return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', '/');
@ -391,6 +440,11 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
return toModelName(name);
}
@Override
public String toApiTestFilename(String name) {
return toApiName(name) + "Test";
}
@Override
public String toVarName(String name) {
// sanitize name

View File

@ -25,6 +25,7 @@ public class JavaInflectorServerCodegen extends JavaClientCodegen {
sourceFolder = "src/gen/java";
modelTemplateFiles.put("model.mustache", ".java");
apiTemplateFiles.put("api.mustache", ".java");
apiTestTemplateFiles.clear(); // TODO: add test template
embeddedTemplateDir = templateDir = "JavaInflector";
invokerPackage = "io.swagger.handler";
artifactId = "swagger-inflector-server";

View File

@ -31,6 +31,7 @@ public class JavaResteasyServerCodegen extends JavaClientCodegen implements Code
apiTemplateFiles.put("apiService.mustache", ".java");
apiTemplateFiles.put("apiServiceImpl.mustache", ".java");
apiTemplateFiles.put("apiServiceFactory.mustache", ".java");
apiTestTemplateFiles.clear(); // TODO: add test template
apiPackage = "io.swagger.api";
modelPackage = "io.swagger.model";

View File

@ -42,6 +42,9 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String[] specialWords = {"new", "copy"};
protected String apiDocPath = "docs/";
protected String modelDocPath = "docs/";
protected String modelFilesPath = "Model/";
protected String coreFilesPath = "Core/";
protected String apiFilesPath = "Api/";
protected Set<String> advancedMapingTypes = new HashSet<String>();
@ -223,35 +226,35 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
additionalProperties.put("apiDocPath", apiDocPath);
additionalProperties.put("modelDocPath", modelDocPath);
String swaggerFolder = podName;
modelPackage = podName;
apiPackage = podName;
modelPackage = swaggerFolder;
apiPackage = swaggerFolder;
supportingFiles.add(new SupportingFile("Object-header.mustache", swaggerFolder, classPrefix + "Object.h"));
supportingFiles.add(new SupportingFile("Object-body.mustache", swaggerFolder, classPrefix + "Object.m"));
supportingFiles.add(new SupportingFile("QueryParamCollection-header.mustache", swaggerFolder, classPrefix + "QueryParamCollection.h"));
supportingFiles.add(new SupportingFile("QueryParamCollection-body.mustache", swaggerFolder, classPrefix + "QueryParamCollection.m"));
supportingFiles.add(new SupportingFile("ApiClient-header.mustache", swaggerFolder, classPrefix + "ApiClient.h"));
supportingFiles.add(new SupportingFile("ApiClient-body.mustache", swaggerFolder, classPrefix + "ApiClient.m"));
supportingFiles.add(new SupportingFile("JSONResponseSerializer-header.mustache", swaggerFolder, classPrefix + "JSONResponseSerializer.h"));
supportingFiles.add(new SupportingFile("JSONResponseSerializer-body.mustache", swaggerFolder, classPrefix + "JSONResponseSerializer.m"));
supportingFiles.add(new SupportingFile("JSONRequestSerializer-body.mustache", swaggerFolder, classPrefix + "JSONRequestSerializer.m"));
supportingFiles.add(new SupportingFile("JSONRequestSerializer-header.mustache", swaggerFolder, classPrefix + "JSONRequestSerializer.h"));
supportingFiles.add(new SupportingFile("ResponseDeserializer-body.mustache", swaggerFolder, classPrefix + "ResponseDeserializer.m"));
supportingFiles.add(new SupportingFile("ResponseDeserializer-header.mustache", swaggerFolder, classPrefix + "ResponseDeserializer.h"));
supportingFiles.add(new SupportingFile("Sanitizer-body.mustache", swaggerFolder, classPrefix + "Sanitizer.m"));
supportingFiles.add(new SupportingFile("Sanitizer-header.mustache", swaggerFolder, classPrefix + "Sanitizer.h"));
supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601.m", swaggerFolder, "JSONValueTransformer+ISO8601.m"));
supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601.h", swaggerFolder, "JSONValueTransformer+ISO8601.h"));
supportingFiles.add(new SupportingFile("Configuration-body.mustache", swaggerFolder, classPrefix + "Configuration.m"));
supportingFiles.add(new SupportingFile("Configuration-header.mustache", swaggerFolder, classPrefix + "Configuration.h"));
supportingFiles.add(new SupportingFile("Object-header.mustache", coreFileFolder(), classPrefix + "Object.h"));
supportingFiles.add(new SupportingFile("Object-body.mustache", coreFileFolder(), classPrefix + "Object.m"));
supportingFiles.add(new SupportingFile("QueryParamCollection-header.mustache", coreFileFolder(), classPrefix + "QueryParamCollection.h"));
supportingFiles.add(new SupportingFile("QueryParamCollection-body.mustache", coreFileFolder(), classPrefix + "QueryParamCollection.m"));
supportingFiles.add(new SupportingFile("ApiClient-header.mustache", coreFileFolder(), classPrefix + "ApiClient.h"));
supportingFiles.add(new SupportingFile("ApiClient-body.mustache", coreFileFolder(), classPrefix + "ApiClient.m"));
supportingFiles.add(new SupportingFile("JSONResponseSerializer-header.mustache", coreFileFolder(), classPrefix + "JSONResponseSerializer.h"));
supportingFiles.add(new SupportingFile("JSONResponseSerializer-body.mustache", coreFileFolder(), classPrefix + "JSONResponseSerializer.m"));
supportingFiles.add(new SupportingFile("JSONRequestSerializer-body.mustache", coreFileFolder(), classPrefix + "JSONRequestSerializer.m"));
supportingFiles.add(new SupportingFile("JSONRequestSerializer-header.mustache", coreFileFolder(), classPrefix + "JSONRequestSerializer.h"));
supportingFiles.add(new SupportingFile("ResponseDeserializer-body.mustache", coreFileFolder(), classPrefix + "ResponseDeserializer.m"));
supportingFiles.add(new SupportingFile("ResponseDeserializer-header.mustache", coreFileFolder(), classPrefix + "ResponseDeserializer.h"));
supportingFiles.add(new SupportingFile("Sanitizer-body.mustache", coreFileFolder(), classPrefix + "Sanitizer.m"));
supportingFiles.add(new SupportingFile("Sanitizer-header.mustache", coreFileFolder(), classPrefix + "Sanitizer.h"));
supportingFiles.add(new SupportingFile("Logger-body.mustache", coreFileFolder(), classPrefix + "Logger.m"));
supportingFiles.add(new SupportingFile("Logger-header.mustache", coreFileFolder(), classPrefix + "Logger.h"));
supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601.m", coreFileFolder(), "JSONValueTransformer+ISO8601.m"));
supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601.h", coreFileFolder(), "JSONValueTransformer+ISO8601.h"));
supportingFiles.add(new SupportingFile("Configuration-body.mustache", coreFileFolder(), classPrefix + "Configuration.m"));
supportingFiles.add(new SupportingFile("Configuration-header.mustache", coreFileFolder(), classPrefix + "Configuration.h"));
supportingFiles.add(new SupportingFile("api-protocol.mustache", coreFileFolder(), classPrefix + "Api.h"));
supportingFiles.add(new SupportingFile("podspec.mustache", "", podName + ".podspec"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
}
@Override
@ -304,12 +307,12 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
if(innerTypeDeclaration.equalsIgnoreCase(BinaryDataType)) {
return "NSData*";
}
// In this codition, type of property p is array of primitive,
// In this condition, type of property p is array of primitive,
// return container type with pointer, e.g. `NSArray*<NSString*>*'
if (languageSpecificPrimitives.contains(innerTypeDeclaration)) {
return getSwaggerType(p) + "<" + innerTypeDeclaration + "*>*";
}
// In this codition, type of property p is array of model,
// In this condition, type of property p is array of model,
// return container type combine inner type with pointer, e.g. `NSArray<SWGTag>*'
else {
for (String sd : advancedMapingTypes) {
@ -341,18 +344,18 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
} else {
String swaggerType = getSwaggerType(p);
// In this codition, type of p is objective-c primitive type, e.g. `NSSNumber',
// In this condition, type of p is objective-c primitive type, e.g. `NSSNumber',
// return type of p with pointer, e.g. `NSNumber*'
if (languageSpecificPrimitives.contains(swaggerType) &&
foundationClasses.contains(swaggerType)) {
return swaggerType + "*";
}
// In this codition, type of p is c primitive type, e.g. `bool',
// In this condition, type of p is c primitive type, e.g. `bool',
// return type of p, e.g. `bool'
else if (languageSpecificPrimitives.contains(swaggerType)) {
return swaggerType;
}
// In this codition, type of p is objective-c object type, e.g. `SWGPet',
// In this condition, type of p is objective-c object type, e.g. `SWGPet',
// return type of p with pointer, e.g. `SWGPet*'
else {
return swaggerType + "*";
@ -454,12 +457,16 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String apiFileFolder() {
return outputFolder + File.separatorChar + apiPackage();
return (outputFolder + "/"+ apiPackage() + "/" + apiFilesPath).replace("/", File.separator);
}
@Override
public String modelFileFolder() {
return outputFolder + File.separatorChar + modelPackage();
return (outputFolder + "/"+ modelPackage() + "/" + modelFilesPath).replace("/", File.separator);
}
public String coreFileFolder() {
return (apiPackage() + "/" + coreFilesPath).replace("/", File.separator);
}
@Override

View File

@ -3,6 +3,7 @@ package io.swagger.codegen.languages;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.CodegenParameter;
import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.CodegenType;
@ -13,6 +14,7 @@ import io.swagger.models.properties.*;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.HashSet;
import java.util.regex.Matcher;
@ -32,10 +34,10 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
public static final String COMPOSER_VENDOR_NAME = "composerVendorName";
public static final String COMPOSER_PROJECT_NAME = "composerProjectName";
protected String invokerPackage = "Swagger\\Client";
protected String composerVendorName = "swagger";
protected String composerProjectName = "swagger-client";
protected String composerVendorName = null;
protected String composerProjectName = null;
protected String packagePath = "SwaggerClient-php";
protected String artifactVersion = "1.0.0";
protected String artifactVersion = null;
protected String srcBasePath = "lib";
protected String testBasePath = "test";
protected String docsBasePath = "docs";
@ -126,7 +128,9 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
cliOptions.add(new CliOption(PACKAGE_PATH, "The main package name for classes. e.g. GeneratedPetstore"));
cliOptions.add(new CliOption(SRC_BASE_PATH, "The directory under packagePath to serve as source root."));
cliOptions.add(new CliOption(COMPOSER_VENDOR_NAME, "The vendor name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. yaypets. IMPORTANT NOTE (2016/03): composerVendorName will be deprecated and replaced by gitUserId in the next swagger-codegen release"));
cliOptions.add(new CliOption(CodegenConstants.GIT_USER_ID, CodegenConstants.GIT_USER_ID_DESC));
cliOptions.add(new CliOption(COMPOSER_PROJECT_NAME, "The project name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. petstore-client. IMPORTANT NOTE (2016/03): composerProjectName will be deprecated and replaced by gitRepoId in the next swagger-codegen release"));
cliOptions.add(new CliOption(CodegenConstants.GIT_REPO_ID, CodegenConstants.GIT_REPO_ID_DESC));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_VERSION, "The version to use in the composer package version field. e.g. 1.2.3"));
}
@ -214,12 +218,24 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
additionalProperties.put(COMPOSER_PROJECT_NAME, composerProjectName);
}
if (additionalProperties.containsKey(CodegenConstants.GIT_USER_ID)) {
this.setGitUserId((String) additionalProperties.get(CodegenConstants.GIT_USER_ID));
} else {
additionalProperties.put(CodegenConstants.GIT_USER_ID, gitUserId);
}
if (additionalProperties.containsKey(COMPOSER_VENDOR_NAME)) {
this.setComposerVendorName((String) additionalProperties.get(COMPOSER_VENDOR_NAME));
} else {
additionalProperties.put(COMPOSER_VENDOR_NAME, composerVendorName);
}
if (additionalProperties.containsKey(CodegenConstants.GIT_REPO_ID)) {
this.setGitRepoId((String) additionalProperties.get(CodegenConstants.GIT_REPO_ID));
} else {
additionalProperties.put(CodegenConstants.GIT_REPO_ID, gitRepoId);
}
if (additionalProperties.containsKey(CodegenConstants.ARTIFACT_VERSION)) {
this.setArtifactVersion((String) additionalProperties.get(CodegenConstants.ARTIFACT_VERSION));
} else {
@ -626,4 +642,14 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
// process enum in models
return postProcessModelsEnum(objs);
}
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation op : operationList) {
op.vendorExtensions.put("x-testOperationId", camelize(op.operationId));
}
return objs;
}
}

View File

@ -116,6 +116,11 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
@Override
public void processOpts() {
super.processOpts();
Boolean excludeTests = false;
if(additionalProperties.containsKey(CodegenConstants.EXCLUDE_TESTS)) {
excludeTests = Boolean.valueOf(additionalProperties.get(CodegenConstants.EXCLUDE_TESTS).toString());
}
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
@ -145,13 +150,20 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("setup.mustache", "", "setup.py"));
supportingFiles.add(new SupportingFile("tox.mustache", "", "tox.ini"));
supportingFiles.add(new SupportingFile("test-requirements.mustache", "", "test-requirements.txt"));
supportingFiles.add(new SupportingFile("requirements.mustache", "", "requirements.txt"));
supportingFiles.add(new SupportingFile("api_client.mustache", swaggerFolder, "api_client.py"));
supportingFiles.add(new SupportingFile("rest.mustache", swaggerFolder, "rest.py"));
supportingFiles.add(new SupportingFile("configuration.mustache", swaggerFolder, "configuration.py"));
supportingFiles.add(new SupportingFile("__init__package.mustache", swaggerFolder, "__init__.py"));
supportingFiles.add(new SupportingFile("__init__model.mustache", modelPackage, "__init__.py"));
supportingFiles.add(new SupportingFile("__init__api.mustache", apiPackage, "__init__.py"));
if(Boolean.FALSE.equals(excludeTests)) {
supportingFiles.add(new SupportingFile("__init__test.mustache", testFolder, "__init__.py"));
}
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
}

View File

@ -0,0 +1,323 @@
package io.swagger.codegen.languages;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.Swagger;
import io.swagger.util.Yaml;
import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Rails5ServerCodegen extends DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(Rails5ServerCodegen.class);
protected String gemName;
protected String moduleName;
protected String gemVersion = "1.0.0";
protected String appFolder = "app";
protected String channelsFolder = appFolder + File.separator + "channels";
protected String applicationCableFolder = channelsFolder + File.separator + "application_cable";
protected String controllersFolder = appFolder + File.separator + "controllers";
protected String jobsFolder = appFolder + File.separator + "jobs";
protected String mailersFolder = appFolder + File.separator + "mailers";
protected String modelsFolder = appFolder + File.separator + "models";
protected String viewsFolder = appFolder + File.separator + "views";
protected String layoutsFolder = viewsFolder + File.separator + "layouts";
protected String binFolder = "bin";
protected String configFolder = "config";
protected String environmentsFolder = configFolder + File.separator + "config";
protected String initializersFolder = configFolder + File.separator + "initializers";
protected String localesFolder = configFolder + File.separator + "locales";
protected String dbFolder = "db";
protected String migrateFolder = dbFolder + File.separator + "migrate";
protected String libFolder = "lib";
protected String tasksFolder = libFolder + File.separator + "tasks";
protected String logFolder = "log";
protected String publicFolder = "public";
protected String testFolder = "test";
protected String tmpFolder = "tmp";
protected String cacheFolder = tmpFolder + File.separator + "cache";
protected String pidFolder = tmpFolder + File.separator + "pids";
protected String socketsFolder = tmpFolder + File.separator + "sockets";
protected String vendorFolder = "vendor";
public Rails5ServerCodegen() {
super();
apiPackage = "app/controllers";
outputFolder = "generated-code" + File.separator + "rails5";
// no model
modelTemplateFiles.clear();
apiTemplateFiles.put("controller.mustache", ".rb");
embeddedTemplateDir = templateDir = "rails5";
typeMapping.clear();
languageSpecificPrimitives.clear();
setReservedWordsLowerCase(
Arrays.asList(
"__FILE__", "and", "def", "end", "in", "or", "self", "unless", "__LINE__",
"begin", "defined?", "ensure", "module", "redo", "super", "until", "BEGIN",
"break", "do", "false", "next", "rescue", "then", "when", "END", "case",
"else", "for", "nil", "retry", "true", "while", "alias", "class", "elsif",
"if", "not", "return", "undef", "yield")
);
languageSpecificPrimitives.add("int");
languageSpecificPrimitives.add("array");
languageSpecificPrimitives.add("map");
languageSpecificPrimitives.add("string");
languageSpecificPrimitives.add("DateTime");
typeMapping.put("long", "int");
typeMapping.put("integer", "int");
typeMapping.put("Array", "array");
typeMapping.put("String", "string");
typeMapping.put("List", "array");
typeMapping.put("map", "map");
//TODO binary should be mapped to byte array
// mapped to String as a workaround
typeMapping.put("binary", "string");
// remove modelPackage and apiPackage added by default
cliOptions.clear();
}
@Override
public void processOpts() {
super.processOpts();
// use constant model/api package (folder path)
//setModelPackage("models");
setApiPackage("app/controllers");
supportingFiles.add(new SupportingFile("Gemfile", "", "Gemfile"));
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
supportingFiles.add(new SupportingFile("Rakefile", "", "Rakefile"));
supportingFiles.add(new SupportingFile("config.ru", "", "config.ru"));
supportingFiles.add(new SupportingFile("channel.rb", applicationCableFolder, "channel.rb"));
supportingFiles.add(new SupportingFile("connection.rb", applicationCableFolder, "connection.rb"));
supportingFiles.add(new SupportingFile("application_controller.rb", controllersFolder, "application_controller.rb"));
supportingFiles.add(new SupportingFile("application_job.rb", jobsFolder, "application_job.rb"));
supportingFiles.add(new SupportingFile("application_mailer.rb", mailersFolder, "application_mailer.rb"));
supportingFiles.add(new SupportingFile("application_record.rb", modelsFolder, "application_record.rb"));
supportingFiles.add(new SupportingFile("mailer.html.erb", layoutsFolder, "mailer.html.erb"));
supportingFiles.add(new SupportingFile("mailer.text.erb", layoutsFolder, "mailer.text.erb"));
supportingFiles.add(new SupportingFile("bundle", binFolder, "bundle"));
supportingFiles.add(new SupportingFile("rails", binFolder, "rails"));
supportingFiles.add(new SupportingFile("rake", binFolder, "rake"));
supportingFiles.add(new SupportingFile("setup", binFolder, "setup"));
supportingFiles.add(new SupportingFile("update", binFolder, "update"));
supportingFiles.add(new SupportingFile("development.rb", environmentsFolder, "development.rb"));
supportingFiles.add(new SupportingFile("production.rb", environmentsFolder, "production.rb"));
supportingFiles.add(new SupportingFile("active_record_belongs_to_required_by_default.rb", initializersFolder, "active_record_belongs_to_required_by_default.rb"));
supportingFiles.add(new SupportingFile("application_controller_renderer.rb", initializersFolder, "application_controller_renderer.rb"));
supportingFiles.add(new SupportingFile("backtrace_silencers.rb", initializersFolder, "backtrace_silencers.rb"));
supportingFiles.add(new SupportingFile("callback_terminator.rb", initializersFolder, "callback_terminator.rb"));
supportingFiles.add(new SupportingFile("cors.rb", initializersFolder, "cors.rb"));
supportingFiles.add(new SupportingFile("filter_parameter_logging.rb", initializersFolder, "filter_parameter_logging.rb"));
supportingFiles.add(new SupportingFile("inflections.rb", initializersFolder, "inflections.rb"));
supportingFiles.add(new SupportingFile("mime_types.rb", initializersFolder, "mime_types.rb"));
supportingFiles.add(new SupportingFile("ssl_options.rb", initializersFolder, "ssl_options.rb"));
supportingFiles.add(new SupportingFile("to_time_preserves_timezone.rb", initializersFolder, "to_time_preserves_timezone.rb"));
supportingFiles.add(new SupportingFile("en.yml", localesFolder, "en.yml"));
supportingFiles.add(new SupportingFile("application.rb", configFolder, "application.rb"));
supportingFiles.add(new SupportingFile("boot.rb", configFolder, "boot.rb"));
supportingFiles.add(new SupportingFile("cable.yml", configFolder, "cable.yml"));
supportingFiles.add(new SupportingFile("database.yml", configFolder, "database.yml"));
supportingFiles.add(new SupportingFile("environment.rb", configFolder, "environment.rb"));
supportingFiles.add(new SupportingFile("puma.rb", configFolder, "puma.rb"));
supportingFiles.add(new SupportingFile("routes.mustache", configFolder, "routes.rb"));
supportingFiles.add(new SupportingFile("secrets.yml", configFolder, "secrets.yml"));
supportingFiles.add(new SupportingFile("spring.rb", configFolder, "spring.rb"));
supportingFiles.add(new SupportingFile(".keep", migrateFolder, ".keep"));
supportingFiles.add(new SupportingFile("schema.rb", dbFolder, "schema.rb"));
supportingFiles.add(new SupportingFile("seeds.rb", dbFolder, "seeds.rb"));
supportingFiles.add(new SupportingFile(".keep", tasksFolder, ".keep"));
supportingFiles.add(new SupportingFile(".keep", logFolder, ".keep"));
supportingFiles.add(new SupportingFile("404.html", publicFolder, "404.html"));
supportingFiles.add(new SupportingFile("422.html", publicFolder, "422.html"));
supportingFiles.add(new SupportingFile("500.html", publicFolder, "500.html"));
supportingFiles.add(new SupportingFile("apple-touch-icon-precomposed.png", publicFolder, "apple-touch-icon-precomposed.png"));
supportingFiles.add(new SupportingFile("apple-touch-icon.png", publicFolder, "apple-touch-icon.png"));
supportingFiles.add(new SupportingFile("favicon.ico", publicFolder, "favicon.ico"));
supportingFiles.add(new SupportingFile("robots.txt", publicFolder, "robots.txt"));
supportingFiles.add(new SupportingFile("robots.txt", publicFolder, "robots.txt"));
supportingFiles.add(new SupportingFile("test_helper.rb", testFolder, "test_helper.rb"));
supportingFiles.add(new SupportingFile(".keep", cacheFolder, ".keep"));
supportingFiles.add(new SupportingFile(".keep", pidFolder, ".keep"));
supportingFiles.add(new SupportingFile(".keep", socketsFolder, ".keep"));
supportingFiles.add(new SupportingFile("restart.txt", tmpFolder, "restart.txt"));
supportingFiles.add(new SupportingFile(".keep", vendorFolder, ".keep"));
}
@Override
public CodegenType getTag() {
return CodegenType.SERVER;
}
@Override
public String getName() {
return "rails5";
}
@Override
public String getHelp() {
return "Generates a Rails5 server library.";
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
}
@Override
public String apiFileFolder() {
return outputFolder + File.separator + apiPackage.replace("/", File.separator);
}
@Override
public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]";
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return getSwaggerType(p) + "[string," + getTypeDeclaration(inner) + "]";
}
return super.getTypeDeclaration(p);
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
String type = null;
if (typeMapping.containsKey(swaggerType)) {
type = typeMapping.get(swaggerType);
if (languageSpecificPrimitives.contains(type)) {
return type;
}
} else {
type = swaggerType;
}
if (type == null) {
return null;
}
return type;
}
@Override
public String toDefaultValue(Property p) {
return "null";
}
@Override
public String toVarName(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
// if it's all uppper case, convert to lower case
if (name.matches("^[A-Z_]*$")) {
name = name.toLowerCase();
}
// camelize (lower first character) the variable name
// petId => pet_id
name = underscore(name);
// for reserved word or word starting with number, append _
if (isReservedWord(name) || name.matches("^\\d.*")) {
name = escapeReservedWord(name);
}
return name;
}
@Override
public String toParamName(String name) {
// should be the same as variable name
return toVarName(name);
}
@Override
public String toModelName(String name) {
// model name cannot use reserved keyword, e.g. return
if (isReservedWord(name)) {
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
}
// camelize the model name
// phone_number => PhoneNumber
return camelize(name);
}
@Override
public String toModelFilename(String name) {
// model name cannot use reserved keyword, e.g. return
if (isReservedWord(name)) {
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
}
// underscore the model file name
// PhoneNumber.rb => phone_number.rb
return underscore(name);
}
@Override
public String toApiFilename(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
// e.g. PhoneNumberApi.rb => phone_number_api.rb
return underscore(name) + "_controllers";
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "ApiController";
}
// e.g. phone_number_api => PhoneNumberApi
return camelize(name) + "Controller";
}
@Override
public String toOperationId(String operationId) {
// method name cannot use reserved keyword, e.g. return
if (isReservedWord(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
}
return underscore(operationId);
}
@Override
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
Swagger swagger = (Swagger)objs.get("swagger");
if(swagger != null) {
try {
objs.put("swagger-yaml", Yaml.mapper().writeValueAsString(swagger));
} catch (JsonProcessingException e) {
LOGGER.error(e.getMessage(), e);
}
}
return super.postProcessSupportingFileData(objs);
}
}

View File

@ -5,6 +5,7 @@ import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.CodegenParameter;
import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile;
@ -527,6 +528,57 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
return camelize(name) + "Api";
}
@Override
public String toEnumValue(String value, String datatype) {
if ("Integer".equals(datatype) || "Float".equals(datatype)) {
return value;
} else {
return "\"" + escapeText(value) + "\"";
}
}
@Override
public String toEnumVarName(String name, String datatype) {
// number
if ("Integer".equals(datatype) || "Float".equals(datatype)) {
String varName = new String(name);
varName = varName.replaceAll("-", "MINUS_");
varName = varName.replaceAll("\\+", "PLUS_");
varName = varName.replaceAll("\\.", "_DOT_");
return varName;
}
// string
String enumName = sanitizeName(underscore(name).toUpperCase());
enumName = enumName.replaceFirst("^_", "");
enumName = enumName.replaceFirst("_$", "");
if (enumName.matches("\\d.*")) { // starts with number
return "N" + enumName;
} else {
return enumName;
}
}
@Override
public String toEnumName(CodegenProperty property) {
String enumName = underscore(toModelName(property.name)).toUpperCase();
enumName = enumName.replaceFirst("^_", "");
enumName = enumName.replaceFirst("_$", "");
if (enumName.matches("\\d.*")) { // starts with number
return "N" + enumName;
} else {
return enumName;
}
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
// process enum in models
return postProcessModelsEnum(objs);
}
@Override
public String toOperationId(String operationId) {
// rename to empty_method_name_1 (e.g.) if method name is empty

View File

@ -20,6 +20,7 @@ public class SpringBootServerCodegen extends JavaClientCodegen implements Codege
outputFolder = "generated-code/javaSpringBoot";
modelTemplateFiles.put("model.mustache", ".java");
apiTemplateFiles.put(templateFileName, ".java");
apiTestTemplateFiles.clear(); // TODO: add test template
embeddedTemplateDir = templateDir = "JavaSpringBoot";
apiPackage = "io.swagger.api";
modelPackage = "io.swagger.model";

View File

@ -18,6 +18,7 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
outputFolder = "generated-code/javaSpringMVC";
modelTemplateFiles.put("model.mustache", ".java");
apiTemplateFiles.put(templateFileName, ".java");
apiTestTemplateFiles.clear(); // TODO: add test template
embeddedTemplateDir = templateDir = "JavaSpringMVC";
apiPackage = "io.swagger.api";
modelPackage = "io.swagger.model";

View File

@ -342,7 +342,7 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
// Ensure that the enum type doesn't match a reserved word or
// the variable name doesn't match the generated enum type or the
// Swift compiler will generate an error
if (isReservedWord(codegenProperty.datatypeWithEnum) || name.equals(codegenProperty.datatypeWithEnum)) {
if (isReservedWord(codegenProperty.datatypeWithEnum) || toVarName(name).equals(codegenProperty.datatypeWithEnum)) {
codegenProperty.datatypeWithEnum = codegenProperty.datatypeWithEnum + "Enum";
}
}
@ -355,8 +355,8 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
if (value.matches("[A-Z][a-z0-9]+[a-zA-Z0-9]*")) {
return value;
}
char[] separators = {'-', '_', ' '};
return WordUtils.capitalizeFully(StringUtils.lowerCase(value), separators).replaceAll("[-_ ]", "");
char[] separators = {'-', '_', ' ', ':'};
return WordUtils.capitalizeFully(StringUtils.lowerCase(value), separators).replaceAll("[-_ :]", "");
}
@ -502,6 +502,7 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String toEnumVarName(String name, String datatype) {
// TODO: this code is probably useless, because the var name is computed from the value in map.put("enum", toSwiftyEnumName(value));
// number
if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) {
String varName = new String(name);
@ -525,8 +526,9 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String toEnumName(CodegenProperty property) {
String enumName = underscore(toModelName(property.name)).toUpperCase();
String enumName = toModelName(property.name);
// TODO: toModelName already does something for names starting with number, so this code is probably never called
if (enumName.matches("\\d.*")) { // starts with number
return "_" + enumName;
} else {

View File

@ -5,12 +5,15 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenModel;
import io.swagger.codegen.CodegenParameter;
import io.swagger.codegen.SupportingFile;
import io.swagger.models.ModelImpl;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.BooleanProperty;
import io.swagger.models.properties.FileProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.ObjectProperty;
import io.swagger.models.properties.Property;
public class TypeScriptAngular2ClientCodegen extends AbstractTypeScriptClientCodegen {
@ -43,6 +46,12 @@ public class TypeScriptAngular2ClientCodegen extends AbstractTypeScriptClientCod
this.cliOptions.add(new CliOption(SNAPSHOT, "When setting this property to true the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm", BooleanProperty.TYPE).defaultValue(Boolean.FALSE.toString()));
}
@Override
protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, ModelImpl swaggerModel) {
codegenModel.additionalPropertiesType = getSwaggerType(swaggerModel.getAdditionalProperties());
addImport(codegenModel, codegenModel.additionalPropertiesType);
}
@Override
public String getName() {
return "typescript-angular2";
@ -106,14 +115,19 @@ public class TypeScriptAngular2ClientCodegen extends AbstractTypeScriptClientCod
MapProperty mp = (MapProperty)p;
inner = mp.getAdditionalProperties();
return "{ [key: string]: " + this.getTypeDeclaration(inner) + "; }";
} else if(p instanceof FileProperty || p instanceof ObjectProperty) {
return "any";
} else {
return p instanceof FileProperty ? "any" : super.getTypeDeclaration(p);
return super.getTypeDeclaration(p);
}
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
if(languageSpecificPrimitives.contains(swaggerType)) {
return swaggerType;
}
return addModelPrefix(swaggerType);
}
@ -121,13 +135,25 @@ public class TypeScriptAngular2ClientCodegen extends AbstractTypeScriptClientCod
String type = null;
if (typeMapping.containsKey(swaggerType)) {
type = typeMapping.get(swaggerType);
if (languageSpecificPrimitives.contains(type))
return type;
} else
} else {
type = swaggerType;
}
if (!startsWithLanguageSpecificPrimitiv(type)) {
type = "models." + swaggerType;
}
return type;
}
private boolean startsWithLanguageSpecificPrimitiv(String type) {
for (String langPrimitive:languageSpecificPrimitives) {
if (type.startsWith(langPrimitive)) {
return true;
}
}
return false;
}
@Override
public void postProcessParameter(CodegenParameter parameter) {
super.postProcessParameter(parameter);

View File

@ -26,7 +26,6 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
super.processOpts();
supportingFiles.add(new SupportingFile("api.mustache", "", "api.ts"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("assign.ts", "", "assign.ts"));
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
supportingFiles.add(new SupportingFile("package.json.mustache", "", "package.json"));
supportingFiles.add(new SupportingFile("typings.json.mustache", "", "typings.json"));

View File

@ -78,12 +78,12 @@ public class {{classname}} {
{{/formParams}}
final String[] {{localVariablePrefix}}localVarAccepts = {
{{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}}
{{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}}
};
final String {{localVariablePrefix}}localVarAccept = {{localVariablePrefix}}apiClient.selectHeaderAccept({{localVariablePrefix}}localVarAccepts);
final String[] {{localVariablePrefix}}localVarContentTypes = {
{{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}
{{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}
};
final String {{localVariablePrefix}}localVarContentType = {{localVariablePrefix}}apiClient.selectHeaderContentType({{localVariablePrefix}}localVarContentTypes);

View File

@ -75,8 +75,8 @@ Name | Type | Description | Notes
### HTTP request headers
- **Content-Type**: {{#consumes}}{{mediaType}}{{#hasMore}}, {{/hasMore}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
- **Accept**: {{#produces}}{{mediaType}}{{#hasMore}}, {{/hasMore}}{{/produces}}{{^produces}}Not defined{{/produces}}
- **Content-Type**: {{#consumes}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
- **Accept**: {{#produces}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/produces}}{{^produces}}Not defined{{/produces}}
{{/operation}}
{{/operations}}

View File

@ -0,0 +1,41 @@
package {{package}};
import {{invokerPackage}}.ApiException;
{{#imports}}import {{import}};
{{/imports}}
import org.junit.Test;
{{^fullJavaUtil}}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
{{/fullJavaUtil}}
/**
* API tests for {{classname}}
*/
public class {{classname}}Test {
private final {{classname}} api = new {{classname}}();
{{#operations}}{{#operation}}
/**
* {{summary}}
*
* {{notes}}
*
* @throws ApiException
* if the Api call fails
*/
@Test
public void {{operationId}}Test() throws ApiException {
{{#allParams}}
{{{dataType}}} {{paramName}} = null;
{{/allParams}}
// {{#returnType}}{{{returnType}}} response = {{/returnType}}api.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
// TODO: test validations
}
{{/operation}}{{/operations}}
}

View File

@ -8,5 +8,8 @@
*.war
*.ear
# exclude jar for gradle wrapper
!gradle/wrapper/*.jar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

View File

@ -0,0 +1,6 @@
#Tue May 17 23:08:05 CST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.6-bin.zip

View File

@ -0,0 +1,90 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -0,0 +1,160 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

View File

@ -0,0 +1,44 @@
package {{package}};
import {{invokerPackage}}.ApiClient;
{{#imports}}import {{import}};
{{/imports}}
import org.junit.Before;
import org.junit.Test;
{{^fullJavaUtil}}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
{{/fullJavaUtil}}
/**
* API tests for {{classname}}
*/
public class {{classname}}Test {
private {{classname}} api;
@Before
public void setup() {
api = new ApiClient().buildClient({{classname}}.class);
}
{{#operations}}{{#operation}}
/**
* {{summary}}
*
* {{notes}}
*/
@Test
public void {{operationId}}Test() {
{{#allParams}}
{{{dataType}}} {{paramName}} = null;
{{/allParams}}
// {{#returnType}}{{{returnType}}} response = {{/returnType}}api.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
// TODO: test validations
}
{{/operation}}{{/operations}}
}

View File

@ -23,14 +23,17 @@ import feign.Request.Options;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import feign.Response;
import feign.RetryableException;
import feign.Util;
import {{invokerPackage}}.StringUtil;
public class OAuth implements RequestInterceptor {
static final int MILLIS_PER_SECOND = 1000;
public interface AccessTokenListener {
public void notify(BasicOAuthToken token);
void notify(BasicOAuthToken token);
}
private volatile String accessToken;
@ -41,21 +44,13 @@ public class OAuth implements RequestInterceptor {
private AccessTokenListener accessTokenListener;
public OAuth(Client client, TokenRequestBuilder requestBuilder) {
setOauthClient(client);
this.oauthClient = new OAuthClient(new OAuthFeignClient(client));
this.tokenRequestBuilder = requestBuilder;
}
public OAuth(Client client, OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
this(client, OAuthClientRequest.tokenLocation(tokenUrl).setScope(scopes));
setFlow(flow);
authenticationRequestBuilder = OAuthClientRequest.authorizationLocation(authorizationUrl);
}
public OAuth(OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
this(new Client.Default(null, null), flow, authorizationUrl, tokenUrl, scopes);
}
public void setFlow(OAuthFlow flow) {
switch(flow) {
case accessCode:
case implicit:
@ -70,6 +65,11 @@ public class OAuth implements RequestInterceptor {
default:
break;
}
authenticationRequestBuilder = OAuthClientRequest.authorizationLocation(authorizationUrl);
}
public OAuth(OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
this(new Client.Default(null, null), flow, authorizationUrl, tokenUrl, scopes);
}
@Override
@ -80,24 +80,20 @@ public class OAuth implements RequestInterceptor {
}
// If first time, get the token
if (expirationTimeMillis == null || System.currentTimeMillis() >= expirationTimeMillis) {
try {
updateAccessToken();
} catch (OAuthSystemException e) {
e.printStackTrace();
return;
} catch (OAuthProblemException e) {
e.printStackTrace();
return;
}
}
if (getAccessToken() != null) {
template.header("Authorization", "Bearer " + getAccessToken());
}
}
public synchronized void updateAccessToken() throws OAuthSystemException, OAuthProblemException {
if (getAccessToken() == null) {
OAuthJSONAccessTokenResponse accessTokenResponse = oauthClient.accessToken(tokenRequestBuilder.buildBodyMessage());
public synchronized void updateAccessToken() {
OAuthJSONAccessTokenResponse accessTokenResponse;
try {
accessTokenResponse = oauthClient.accessToken(tokenRequestBuilder.buildBodyMessage());
} catch (Exception e) {
throw new RetryableException(e.getMessage(), e,null);
}
if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) {
setAccessToken(accessTokenResponse.getAccessToken(), accessTokenResponse.getExpiresIn());
if (accessTokenListener != null) {
@ -105,9 +101,8 @@ public class OAuth implements RequestInterceptor {
}
}
}
}
public void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
public synchronized void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
this.accessTokenListener = accessTokenListener;
}
@ -117,7 +112,7 @@ public class OAuth implements RequestInterceptor {
public synchronized void setAccessToken(String accessToken, Long expiresIn) {
this.accessToken = accessToken;
this.expirationTimeMillis = System.currentTimeMillis() + expiresIn * 1000;
this.expirationTimeMillis = System.currentTimeMillis() + expiresIn * MILLIS_PER_SECOND;
}
public TokenRequestBuilder getTokenRequestBuilder() {
@ -148,7 +143,7 @@ public class OAuth implements RequestInterceptor {
this.oauthClient = new OAuthClient( new OAuthFeignClient(client));
}
public class OAuthFeignClient implements HttpClient {
public static class OAuthFeignClient implements HttpClient {
private Client client;
@ -198,6 +193,5 @@ public class OAuth implements RequestInterceptor {
public void shutdown() {
// Nothing to do here
}
}
}

View File

@ -76,12 +76,12 @@ public class {{classname}} {
{{/formParams}}
final String[] {{localVariablePrefix}}localVarAccepts = {
{{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}}
{{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}}
};
final String {{localVariablePrefix}}localVarAccept = {{localVariablePrefix}}apiClient.selectHeaderAccept({{localVariablePrefix}}localVarAccepts);
final String[] {{localVariablePrefix}}localVarContentTypes = {
{{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}
{{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}
};
final String {{localVariablePrefix}}localVarContentType = {{localVariablePrefix}}apiClient.selectHeaderContentType({{localVariablePrefix}}localVarContentTypes);

View File

@ -76,13 +76,13 @@ public class {{classname}} {
{{localVariablePrefix}}localVarFormParams.put("{{baseName}}", {{paramName}});{{/formParams}}
final String[] {{localVariablePrefix}}localVarAccepts = {
{{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}}
{{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}}
};
final String {{localVariablePrefix}}localVarAccept = {{localVariablePrefix}}apiClient.selectHeaderAccept({{localVariablePrefix}}localVarAccepts);
if ({{localVariablePrefix}}localVarAccept != null) {{localVariablePrefix}}localVarHeaderParams.put("Accept", {{localVariablePrefix}}localVarAccept);
final String[] {{localVariablePrefix}}localVarContentTypes = {
{{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}
{{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}
};
final String {{localVariablePrefix}}localVarContentType = {{localVariablePrefix}}apiClient.selectHeaderContentType({{localVariablePrefix}}localVarContentTypes);
{{localVariablePrefix}}localVarHeaderParams.put("Content-Type", {{localVariablePrefix}}localVarContentType);

View File

@ -0,0 +1,44 @@
package {{package}};
import {{invokerPackage}}.ApiClient;
{{#imports}}import {{import}};
{{/imports}}
import org.junit.Before;
import org.junit.Test;
{{^fullJavaUtil}}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
{{/fullJavaUtil}}
/**
* API tests for {{classname}}
*/
public class {{classname}}Test {
private {{classname}} api;
@Before
public void setup() {
api = new ApiClient().createService({{classname}}.class);
}
{{#operations}}{{#operation}}
/**
* {{summary}}
*
* {{notes}}
*/
@Test
public void {{operationId}}Test() {
{{#allParams}}
{{{dataType}}} {{paramName}} = null;
{{/allParams}}
// {{#returnType}}{{{returnType}}} response = {{/returnType}}api.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
// TODO: test validations
}
{{/operation}}{{/operations}}
}

View File

@ -0,0 +1,44 @@
package {{package}};
import {{invokerPackage}}.ApiClient;
{{#imports}}import {{import}};
{{/imports}}
import org.junit.Before;
import org.junit.Test;
{{^fullJavaUtil}}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
{{/fullJavaUtil}}
/**
* API tests for {{classname}}
*/
public class {{classname}}Test {
private {{classname}} api;
@Before
public void setup() {
api = new ApiClient().createService({{classname}}.class);
}
{{#operations}}{{#operation}}
/**
* {{summary}}
*
* {{notes}}
*/
@Test
public void {{operationId}}Test() {
{{#allParams}}
{{{dataType}}} {{paramName}} = null;
{{/allParams}}
// {{#returnType}}{{{returnType}}} response = {{/returnType}}api.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
// TODO: test validations
}
{{/operation}}{{/operations}}
}

View File

@ -1,6 +1,7 @@
package {{invokerPackage}}.auth;
import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
import static java.net.HttpURLConnection.HTTP_FORBIDDEN;
import java.io.IOException;
import java.util.Map;
@ -85,6 +86,7 @@ public class OAuth implements Interceptor {
updateAccessToken(null);
}
if (getAccessToken() != null) {
// Build the request
Builder rb = request.newBuilder();
@ -107,27 +109,40 @@ public class OAuth implements Interceptor {
// 401 most likely indicates that access token has expired.
// Time to refresh and resend the request
if ( response.code() == HTTP_UNAUTHORIZED ) {
updateAccessToken(requestAccessToken);
if ( response != null && (response.code() == HTTP_UNAUTHORIZED | response.code() == HTTP_FORBIDDEN) ) {
if (updateAccessToken(requestAccessToken)) {
return intercept( chain );
}
}
return response;
} else {
return chain.proceed(chain.request());
}
}
public synchronized void updateAccessToken(String requestAccessToken) throws IOException {
/*
* Returns true if the access token has been updated
*/
public synchronized boolean updateAccessToken(String requestAccessToken) throws IOException {
if (getAccessToken() == null || getAccessToken().equals(requestAccessToken)) {
try {
OAuthJSONAccessTokenResponse accessTokenResponse = oauthClient.accessToken(this.tokenRequestBuilder.buildBodyMessage());
if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) {
setAccessToken(accessTokenResponse.getAccessToken());
if (accessTokenListener != null) {
accessTokenListener.notify((BasicOAuthToken) accessTokenResponse.getOAuthToken());
}
return getAccessToken().equals(requestAccessToken);
} else {
return false;
}
} catch (OAuthSystemException e) {
throw new IOException(e);
} catch (OAuthProblemException e) {
throw new IOException(e);
}
}
return true;
}
public void registerAccessTokenListener(AccessTokenListener accessTokenListener) {

View File

@ -18,8 +18,8 @@ public interface {{classname}} {
{{#operation}}
@{{httpMethod}}
{{#subresourceOperation}}@Path("{{path}}"){{/subresourceOperation}}
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
public Response {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{/allParams}});
{{/operation}}
}

View File

@ -25,8 +25,8 @@ import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.*;
@Path("/{{baseName}}")
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
@io.swagger.annotations.Api(description = "the {{baseName}} API")
{{>generatedAnnotation}}
{{#operations}}
@ -36,8 +36,8 @@ public class {{classname}} {
{{#operation}}
@{{httpMethod}}
{{#subresourceOperation}}@Path("{{path}}"){{/subresourceOperation}}
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
@io.swagger.annotations.ApiOperation(value = "{{{summary}}}", notes = "{{{notes}}}", response = {{{returnType}}}.class{{#returnContainer}}, responseContainer = "{{{returnContainer}}}"{{/returnContainer}}{{#hasAuthMethods}}, authorizations = {
{{#authMethods}}@io.swagger.annotations.Authorization(value = "{{name}}"{{#isOAuth}}, scopes = {
{{#scopes}}@io.swagger.annotations.AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{#hasMore}},

View File

@ -23,8 +23,8 @@ import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.*;
@Path("/{{baseName}}")
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
@io.swagger.annotations.Api(description = "the {{baseName}} API")
{{>generatedAnnotation}}
{{#operations}}
@ -34,8 +34,8 @@ public class {{classname}} {
{{#operation}}
@{{httpMethod}}
{{#subresourceOperation}}@Path("{{path}}"){{/subresourceOperation}}
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
@io.swagger.annotations.ApiOperation(value = "{{{summary}}}", notes = "{{{notes}}}", response = {{{returnType}}}.class{{#returnContainer}}, responseContainer = "{{{returnContainer}}}"{{/returnContainer}}{{#hasAuthMethods}}, authorizations = {
{{#authMethods}}@io.swagger.annotations.Authorization(value = "{{name}}"{{#isOAuth}}, scopes = {
{{#scopes}}@io.swagger.annotations.AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{#hasMore}},

View File

@ -19,8 +19,8 @@ import javax.ws.rs.*;
{{#operations}}{{#operation}}{{#isMultipart}}import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
{{/isMultipart}}{{/operation}}{{/operations}}
@Path("/{{baseName}}")
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
{{>generatedAnnotation}}
{{#operations}}
public class {{classname}} {
@ -29,8 +29,8 @@ public class {{classname}} {
{{#operation}}
@{{httpMethod}}
{{#subresourceOperation}}@Path("{{path}}"){{/subresourceOperation}}
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
public Response {{nickname}}({{#isMultipart}}MultipartFormDataInput input,{{/isMultipart}}{{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{^isMultipart}}{{>formParams}},{{/isMultipart}}{{#isMultipart}}{{^isFormParam}},{{/isFormParam}}{{/isMultipart}}{{/allParams}}@Context SecurityContext securityContext)
throws NotFoundException {
return delegate.{{nickname}}({{#isMultipart}}input,{{/isMultipart}}{{#allParams}}{{^isMultipart}}{{paramName}},{{/isMultipart}}{{#isMultipart}}{{^isFormParam}}{{paramName}},{{/isFormParam}}{{/isMultipart}}{{/allParams}}securityContext);

View File

@ -41,8 +41,8 @@ public class {{classname}} {
@ApiResponses(value = { {{#responses}}
@ApiResponse(code = {{{code}}}, message = "{{{message}}}", response = {{{returnType}}}.class){{#hasMore}},{{/hasMore}}{{/responses}} })
@RequestMapping(value = "{{{path}}}",
{{#hasProduces}}produces = { {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }, {{/hasProduces}}
{{#hasConsumes}}consumes = { {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} },{{/hasConsumes}}
{{#hasProduces}}produces = { {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }, {{/hasProduces}}
{{#hasConsumes}}consumes = { {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} },{{/hasConsumes}}
method = RequestMethod.{{httpMethod}})
public ResponseEntity<{{>returnTypes}}> {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},
{{/hasMore}}{{/allParams}})

View File

@ -49,8 +49,8 @@ public interface {{classname}} {
@ApiResponses(value = { {{#responses}}
@ApiResponse(code = {{{code}}}, message = "{{{message}}}"){{#hasMore}},{{/hasMore}}{{/responses}} })
@RequestMapping(value = "{{path}}",
{{#hasProduces}}produces = { {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }, {{/hasProduces}}
{{#hasConsumes}}consumes = { {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} },{{/hasConsumes}}
{{#hasProduces}}produces = { {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }, {{/hasProduces}}
{{#hasConsumes}}consumes = { {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} },{{/hasConsumes}}
method = RequestMethod.{{httpMethod}})
default Callable<ResponseEntity<{{>returnTypes}}>> {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},
{{/hasMore}}{{/allParams}})

View File

@ -46,8 +46,8 @@ public class {{classname}} {
@io.swagger.annotations.ApiResponses(value = { {{#responses}}
@io.swagger.annotations.ApiResponse(code = {{{code}}}, message = "{{{message}}}", response = {{{returnType}}}.class){{#hasMore}},{{/hasMore}}{{/responses}} })
@RequestMapping(value = "{{{path}}}",
{{#hasProduces}}produces = { {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }, {{/hasProduces}}
{{#hasConsumes}}consumes = { {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} },{{/hasConsumes}}
{{#hasProduces}}produces = { {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }, {{/hasProduces}}
{{#hasConsumes}}consumes = { {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} },{{/hasConsumes}}
method = RequestMethod.{{httpMethod}})
public ResponseEntity<{{>returnTypes}}> {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},
{{/hasMore}}{{/allParams}})

View File

@ -163,10 +163,9 @@
<jetty-version>9.2.9.v20150224</jetty-version>
<jersey-version>1.13</jersey-version>
<slf4j-version>1.6.3</slf4j-version>
<scala-test-version>1.6.1</scala-test-version>
<junit-version>4.8.1</junit-version>
<servlet-api-version>2.5</servlet-api-version>
<springfox-version>2.0.4-SNAPSHOT</springfox-version>
<spring-version>4.0.9.RELEASE</spring-version>
<springfox-version>2.4.0</springfox-version>
<spring-version>4.2.5.RELEASE</spring-version>
</properties>
</project>

View File

@ -74,8 +74,8 @@
};
var authNames = [<#authMethods>'<name>'<#hasMore>, </hasMore></authMethods>];
var contentTypes = [<#consumes>'<mediaType>'<#hasMore>, </hasMore></consumes>];
var accepts = [<#produces>'<mediaType>'<#hasMore>, </hasMore></produces>];
var contentTypes = [<#consumes>'<& mediaType>'<#hasMore>, </hasMore></consumes>];
var accepts = [<#produces>'<& mediaType>'<#hasMore>, </hasMore></produces>];
var returnType = <#returnType><&returnType></returnType><^returnType>null</returnType>;
return this.apiClient.callApi(

View File

@ -82,8 +82,8 @@ Name | Type | Description | Notes
### HTTP request headers
- **Content-Type**: {{#consumes}}{{mediaType}}{{#hasMore}}, {{/hasMore}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
- **Accept**: {{#produces}}{{mediaType}}{{#hasMore}}, {{/hasMore}}{{/produces}}{{^produces}}Not defined{{/produces}}
- **Content-Type**: {{#consumes}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
- **Accept**: {{#produces}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/produces}}{{^produces}}Not defined{{/produces}}
{{/operation}}
{{/operations}}

View File

@ -27,6 +27,7 @@ io.swagger.codegen.languages.ScalaClientCodegen
io.swagger.codegen.languages.ScalatraServerCodegen
io.swagger.codegen.languages.SilexServerCodegen
io.swagger.codegen.languages.SinatraServerCodegen
io.swagger.codegen.languages.Rails5ServerCodegen
io.swagger.codegen.languages.SlimFrameworkServerCodegen
io.swagger.codegen.languages.SpringBootServerCodegen
io.swagger.codegen.languages.SpringMVCServerCodegen

View File

@ -1,44 +1,54 @@
# TypeScript-Fetch
This generator creates TypeScript/JavaScript client that utilizes [Fetch API](https://fetch.spec.whatwg.org/). The codegen Node module can be used in the following environments:
This generator creates TypeScript/JavaScript client that utilizes [Fetch API](https://fetch.spec.whatwg.org/). The generated Node module can be used in the following environments:
* Node.JS
Environment
* Node.js
* Webpack
* Browserify
It is usable in both TypeScript and JavaScript. In TypeScript, the definition should be automatically resolved via `typings` in `package.json`. ([Reference](http://www.typescriptlang.org/docs/handbook/typings-for-npm-packages.html))
Language level
* ES5 - you must have a Promises/A+ library installed
* ES6
Module system
* CommonJS
* ES6 module system
It can be used in both TypeScript and JavaScript. In TypeScript, the definition should be automatically resolved via `package.json`. ([Reference](http://www.typescriptlang.org/docs/handbook/typings-for-npm-packages.html))
### Installation ###
`swagger-codegen` does not generate JavaScript directly. The codegen Node module comes with `package.json` that bundles `typescript` and `typings` so it can self-compile. The self-compile is normally run automatically via the `npm` `postinstall` script of `npm install`.
`swagger-codegen` does not generate JavaScript directly. The generated Node module comes with `package.json` that bundles `typescript` and `typings` so it can self-compile during `prepublish` stage. The should be run automatically during `npm install` or `npm publish`.
CAVEAT: Due to [privilege implications](https://docs.npmjs.com/misc/scripts#user), `npm` may skip `postinstall` script if the user is `root`. You would need to manually invoke `npm install` or `npm run postinstall` for the codegen module if that's the case.
CAVEAT: Due to [privilege implications](https://docs.npmjs.com/misc/scripts#user), `npm` would skip all scripts if the user is `root`. You would need to manually run it with `npm run prepublish` or run `npm install --unsafe-perm`.
#### NPM repository ###
If you remove `"private": true` from `package.json`, you may publish the module to NPM. In which case, you would be able to install the module as any other NPM module.
#### NPM ####
You may publish the module to NPM. In this case, you would be able to install the module as any other NPM module. It maybe useful to use [scoped packages](https://docs.npmjs.com/misc/scope).
It maybe useful to use [scoped packages](https://docs.npmjs.com/misc/scope).
You can also use `npm link` to link the module. However, this would not modify `package.json` of the installing project, as such you would need to relink everytime you deploy that project.
#### NPM install local file ###
You should be able to directly install the module using `npm install file:///codegen_path`.
You can also directly install the module using `npm install file_path`. If you do `npm install file_path --save`, NPM will save relative path to `package.json`. In this case, `npm install` and `npm shrinkwrap` may misbehave. You would need to manually edit `package.json` and replace it with absolute path.
NOTES: If you do `npm install file:///codegen_path --save` NPM might convert your path to relative path, maybe have adverse affect. `npm install` and `npm shrinkwrap` may misbehave if the installation path is not absolute.
#### direct copy/symlink ###
You may also simply copy or symlink the codegen into a directly under your project. The syntax of the usage would differ if you take this route. (See below)
### Usage ###
With ES6 module syntax, the following syntaxes are supported:
Regardless of which method you deployed your NPM module, the ES6 module syntaxes are as follows:
```
import * as localName from 'npmName';
import {operationId} from 'npmName';
```
The CommonJS syntax is as follows:
```
import localName = require('npmName');
```
#### Direct copy/symlink ####
You may also simply copy or symlink the generated module into a directory under your project. The syntax of this is as follows:
With ES6 module syntax, the following syntaxes are supported:
```
import * as localName from './symlinkDir';
import {operationId} from './symlinkDir';
```
With CommonJS, the following syntaxes are supported:
The CommonJS syntax is as follows:
```
import localName = require('npmName');
import localName = require('./symlinkDir')';
```

View File

@ -1,7 +1,30 @@
import * as querystring from 'querystring';
import * as fetch from 'isomorphic-fetch';
import {assign} from './assign';
import * as querystring from "querystring";
import * as url from "url";
import * as isomorphicFetch from "isomorphic-fetch";
{{^supportsES6}}
import * as assign from "core-js/library/fn/object/assign";
{{/supportsES6}}
interface Dictionary<T> { [index: string]: T; }
export interface FetchAPI { (url: string, init?: any): Promise<any>; }
const BASE_PATH = "{{basePath}}";
export interface FetchArgs {
url: string;
options: any;
}
export class BaseAPI {
basePath: string;
fetch: FetchAPI;
constructor(fetch: FetchAPI = isomorphicFetch, basePath: string = BASE_PATH) {
this.basePath = basePath;
this.fetch = fetch;
}
}
{{#models}}
{{#model}}
@ -13,24 +36,20 @@ import {assign} from './assign';
export interface {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{
{{#vars}}
{{#description}}
/**
* {{{description}}}
*/
{{/description}}
"{{name}}"{{^required}}?{{/required}}: {{#isEnum}}{{classname}}.{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}};
"{{name}}"{{^required}}?{{/required}}: {{#isEnum}}{{classname}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}};
{{/vars}}
}
{{#hasEnums}}
export namespace {{classname}} {
{{#vars}}
{{#isEnum}}
export type {{datatypeWithEnum}} = {{#allowableValues}}{{#values}}'{{.}}'{{^-last}} | {{/-last}}{{/values}}{{/allowableValues}};
export type {{classname}}{{datatypeWithEnum}} = {{#allowableValues}}{{#values}}"{{.}}"{{^-last}} | {{/-last}}{{/values}}{{/allowableValues}};
{{/isEnum}}
{{/vars}}
}
{{/hasEnums}}
{{/model}}
{{/models}}
@ -38,96 +57,111 @@ export type {{datatypeWithEnum}} = {{#allowableValues}}{{#values}}'{{.}}'{{^-las
{{#apiInfo}}
{{#apis}}
{{#operations}}
//export namespace {{package}} {
'use strict';
{{#description}}
/**
* {{&description}}
* {{classname}} - fetch parameter creator{{#description}}
* {{&description}}{{/description}}
*/
{{/description}}
export class {{classname}} {
protected basePath = '{{basePath}}';
public defaultHeaders : any = {};
constructor(basePath?: string) {
if (basePath) {
this.basePath = basePath;
}
}
export const {{classname}}FetchParamCreactor = {
{{#operation}}
/**
* {{summary}}
* {{notes}}
{{#allParams}}* @param {{paramName}} {{description}}
{{/allParams}}*/
public {{nickname}} (params: { {{#allParams}} {{paramName}}{{^required}}?{{/required}}: {{{dataType}}};{{/allParams}} }, extraQueryParams?: any, extraFetchParams?: any ) : Promise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}{}{{/returnType}}> {
const localVarPath = this.basePath + '{{path}}'{{#pathParams}}
.replace('{' + '{{baseName}}' + '}', String(params.{{paramName}})){{/pathParams}};
let queryParameters: any = assign({}, extraQueryParams);
let headerParams: any = assign({}, this.defaultHeaders);
{{#hasFormParams}}
let formParams: any = {};
headerParams['Content-Type'] = 'application/x-www-form-urlencoded';
{{/hasFormParams}}
{{#hasBodyParam}}
headerParams['Content-Type'] = 'application/json';
{{/hasBodyParam}}
/** {{#summary}}
* {{summary}}{{/summary}}{{#notes}}
* {{notes}}{{/notes}}{{#allParams}}
* @param {{paramName}} {{description}}{{/allParams}}
*/
{{nickname}}({{#hasParams}}params: { {{#allParams}} {{paramName}}{{^required}}?{{/required}}: {{{dataType}}};{{/allParams}} }{{/hasParams}}): FetchArgs {
{{#allParams}}
{{#required}}
// verify required parameter '{{paramName}}' is set
if (params.{{paramName}} == null) {
throw new Error('Missing required parameter {{paramName}} when calling {{nickname}}');
// verify required parameter "{{paramName}}" is set
if (params["{{paramName}}"] == null) {
throw new Error("Missing required parameter {{paramName}} when calling {{nickname}}");
}
{{/required}}
{{/allParams}}
{{#queryParams}}
if (params.{{paramName}} !== undefined) {
queryParameters['{{baseName}}'] = params.{{paramName}};
}
const baseUrl = `{{path}}`{{#pathParams}}
.replace(`{${"{{baseName}}"}}`, `${ params.{{paramName}} }`){{/pathParams}};
let urlObj = url.parse(baseUrl, true);
{{#hasQueryParams}}
urlObj.query = {{#supportsES6}}Object.{{/supportsES6}}assign({}, urlObj.query, { {{#queryParams}}
"{{baseName}}": params.{{paramName}},{{/queryParams}}
});
{{/hasQueryParams}}
let fetchOptions: RequestInit = { method: "{{httpMethod}}" };
{{/queryParams}}
{{#headerParams}}
headerParams['{{baseName}}'] = params.{{paramName}};
{{/headerParams}}
{{#formParams}}
formParams['{{baseName}}'] = params.{{paramName}};
{{/formParams}}
let fetchParams = {
method: '{{httpMethod}}',
headers: headerParams,
{{#bodyParam}}body: JSON.stringify(params.{{paramName}}),
{{/bodyParam}}
{{#hasFormParams}}body: querystring.stringify(formParams),
let contentTypeHeader: Dictionary<string>;
{{#hasFormParams}}
contentTypeHeader = { "Content-Type": "application/x-www-form-urlencoded" };
fetchOptions.body = querystring.stringify({ {{#formParams}}
"{{baseName}}": params.{{paramName}},{{/formParams}}
});
{{/hasFormParams}}
{{#hasBodyParam}}
contentTypeHeader = { "Content-Type": "application/json" };{{#bodyParam}}
if (params["{{paramName}}"]) {
fetchOptions.body = JSON.stringify(params["{{paramName}}"] || {});
}{{/bodyParam}}
{{/hasBodyParam}}
{{#hasHeaderParam}}
fetchOptions.headers = {{#supportsES6}}Object.{{/supportsES6}}assign({ {{#headerParams}}
"{{baseName}}": params.{{paramName}},{{/headerParams}}
}, contentTypeHeader);
{{/hasHeaderParam}}
{{^hasHeaderParam}}
if (contentTypeHeader) {
fetchOptions.headers = contentTypeHeader;
}
{{/hasHeaderParam}}
return {
url: url.format(urlObj),
options: fetchOptions,
};
if (extraFetchParams) {
fetchParams = assign(fetchParams, extraFetchParams);
},
{{/operation}}
}
let localVarPathWithQueryParameters = localVarPath + (localVarPath.indexOf('?') !== -1 ? '&' : '?') + querystring.stringify(queryParameters);
return fetch(localVarPathWithQueryParameters, fetchParams).then((response) => {
/**
* {{classname}} - functional programming interface{{#description}}
* {{&description}}{{/description}}
*/
export const {{classname}}Fp = {
{{#operation}}
/** {{#summary}}
* {{summary}}{{/summary}}{{#notes}}
* {{notes}}{{/notes}}{{#allParams}}
* @param {{paramName}} {{description}}{{/allParams}}
*/
{{nickname}}({{#hasParams}}params: { {{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}; {{/allParams}} }{{/hasParams}}): (fetch: FetchAPI, basePath?: string) => Promise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}any{{/returnType}}> {
const fetchArgs = {{classname}}FetchParamCreactor.{{nickname}}({{#hasParams}}params{{/hasParams}});
return (fetch: FetchAPI = isomorphicFetch, basePath: string = BASE_PATH) => {
return fetch(basePath + fetchArgs.url, fetchArgs.options).then((response) => {
if (response.status >= 200 && response.status < 300) {
return response.json();
return response{{#returnType}}.json(){{/returnType}};
} else {
let error = new Error(response.statusText);
(error as any).response = response;
throw error;
throw response;
}
});
};
},
{{/operation}}
};
/**
* {{classname}} - object-oriented interface{{#description}}
* {{&description}}{{/description}}
*/
export class {{classname}} extends BaseAPI {
{{#operation}}
/** {{#summary}}
* {{summary}}{{/summary}}{{#notes}}
* {{notes}}{{/notes}}{{#allParams}}
* @param {{paramName}} {{description}}{{/allParams}}
*/
{{nickname}}({{#hasParams}}params: { {{#allParams}} {{paramName}}{{^required}}?{{/required}}: {{{dataType}}};{{/allParams}} }{{/hasParams}}) {
return {{classname}}Fp.{{nickname}}({{#hasParams}}params{{/hasParams}})(this.fetch, this.basePath);
}
{{/operation}}
}
//}
{{/operations}}
{{/apis}}
{{/apiInfo}}

View File

@ -1,18 +0,0 @@
export function assign (target: any, ...args: any[]) {
'use strict';
if (target === undefined || target === null) {
throw new TypeError('Cannot convert undefined or null to object');
}
var output = Object(target);
for (let source of args) {
if (source !== undefined && source !== null) {
for (var nextKey in source) {
if (source.hasOwnProperty(nextKey)) {
output[nextKey] = source[nextKey];
}
}
}
}
return output;
};

View File

@ -1,15 +1,15 @@
{
"name": "{{#npmName}}{{{npmName}}}{{/npmName}}{{^npmName}}typescript-fetch-api{{/npmName}}",
"version": "{{#npmVersion}}{{{npmVersion}}}{{/npmVersion}}{{^npmVersion}}0.0.0{{/npmVersion}}",
"private": true,
"main": "./dist/api.js",
"browser": "./dist/api.js",
"typings": "./dist/api.d.ts",
"dependencies": {
"isomorphic-fetch": "^2.2.1"
{{^supportsES6}}"core-js": "^2.4.0",
{{/supportsES6}}"isomorphic-fetch": "^2.2.1"
},
"scripts" : {
"install" : "typings install && tsc"
"prepublish" : "typings install && tsc"
},
"devDependencies": {
"typescript": "^1.8.10",

View File

@ -4,7 +4,8 @@
"target": "{{#supportsES6}}es6{{/supportsES6}}{{^supportsES6}}es5{{/supportsES6}}",
"module": "commonjs",
"noImplicitAny": true,
"outDir": "dist"
"outDir": "dist",
"rootDir": "."
},
"exclude": [
"dist",

View File

@ -1,9 +1,9 @@
{
"version": false,
"dependencies": {},
"ambientDependencies": {
{{^supportsES6}} "es6-promise": "registry:dt/es6-promise#0.0.0+20160423074304",
{{/supportsES6}} "node": "registry:dt/node#4.0.0+20160423143914",
"ambientDependencies": { {{^supportsES6}}
"core-js": "registry:dt/core-js#0.0.0+20160317120654",{{/supportsES6}}
"node": "registry:dt/node#4.0.0+20160423143914",
"isomorphic-fetch": "registry:dt/isomorphic-fetch#0.0.0+20160505171433"
}
}

View File

@ -0,0 +1,23 @@
# Swagger Codegen Ignore
# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen
# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.
# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line:
#ApiClient.cs
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# Thsi matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md

View File

@ -20,7 +20,7 @@ object {{classname}} {
{{>javadoc}}
{{/javadocRenderer}}
def {{operationId}}({{>methodParameters}}): ApiRequest[{{>operationReturnType}}] =
ApiRequest[{{>operationReturnType}}](ApiMethods.{{httpMethod.toUpperCase}}, "{{basePath}}", "{{path}}", {{#consumes.0}}"{{mediaType}}"{{/consumes.0}}{{^consumes}}"application/json"{{/consumes}})
ApiRequest[{{>operationReturnType}}](ApiMethods.{{httpMethod.toUpperCase}}, "{{basePath}}", "{{path}}", {{#consumes.0}}"{{{mediaType}}}"{{/consumes.0}}{{^consumes}}"application/json"{{/consumes}})
{{#authMethods}}{{#isApiKey}}.withApiKey(apiKey, "{{keyParamName}}", {{#isKeyInQuery}}QUERY{{/isKeyInQuery}}{{#isKeyInHeader}}HEADER{{/isKeyInHeader}})
{{/isApiKey}}{{#isBasic}}.withCredentials(basicAuth)
{{/isBasic}}{{/authMethods}}{{#bodyParam}}.withBody({{paramName}})

View File

@ -73,7 +73,7 @@ public class {{classname}} {
{{/headerParams}}
String[] localVarContentTypes = {
{{#consumes}}"{{mediaType}}"{{#hasMore}},{{/hasMore}}{{/consumes}}
{{#consumes}}"{{{mediaType}}}"{{#hasMore}},{{/hasMore}}{{/consumes}}
};
String localVarContentType = localVarContentTypes.length > 0 ? localVarContentTypes[0] : "application/json";

View File

@ -53,8 +53,8 @@ Name | Type | Description | Notes
### HTTP request headers
- **Content-Type**: {{#consumes}}{{mediaType}}{{#hasMore}}, {{/hasMore}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
- **Accept**: {{#produces}}{{mediaType}}{{#hasMore}}, {{/hasMore}}{{/produces}}{{^produces}}Not defined{{/produces}}
- **Content-Type**: {{#consumes}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
- **Accept**: {{#produces}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/produces}}{{^produces}}Not defined{{/produces}}
{{/operation}}
{{/operations}}

View File

@ -0,0 +1,6 @@
#Mon May 16 21:00:11 CST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.6-bin.zip

View File

@ -0,0 +1,90 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -0,0 +1,160 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

View File

@ -81,7 +81,7 @@ public class {{classname}} {
{{/headerParams}}
String[] contentTypes = {
{{#consumes}}"{{mediaType}}"{{#hasMore}},{{/hasMore}}{{/consumes}}
{{#consumes}}"{{{mediaType}}}"{{#hasMore}},{{/hasMore}}{{/consumes}}
};
String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
@ -167,7 +167,7 @@ public class {{classname}} {
{{/headerParams}}
String[] contentTypes = {
{{#consumes}}"{{mediaType}}"{{#hasMore}},{{/hasMore}}{{/consumes}}
{{#consumes}}"{{{mediaType}}}"{{#hasMore}},{{/hasMore}}{{/consumes}}
};
String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";

View File

@ -0,0 +1,51 @@
#!/bin/sh
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
#
# Usage example: /bin/sh ./git_push.sh wing328 swagger-petstore-perl "minor update"
git_user_id=$1
git_repo_id=$2
release_note=$3
if [ "$git_user_id" = "" ]; then
git_user_id="{{{gitUserId}}}"
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
fi
if [ "$git_repo_id" = "" ]; then
git_repo_id="{{{gitRepoId}}}"
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
fi
if [ "$release_note" = "" ]; then
release_note="{{{releaseNote}}}"
echo "[INFO] No command line input provided. Set \$release_note to $release_note"
fi
# Initialize the local directory as a Git repository
git init
# Adds the files in the local repository and stages them for commit.
git add .
# Commits the tracked changes and prepares them to be pushed to a remote repository.
git commit -m "$release_note"
# Sets the new remote
git_remote=`git remote`
if [ "$git_remote" = "" ]; then # git remote not defined
if [ "$GIT_TOKEN" = "" ]; then
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git crediential in your environment."
git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
else
git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git
fi
fi
git pull origin master
# Pushes (Forces) the changes in the local repository up to the remote repository
echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git"
git push origin master 2>&1 | grep -v 'To https'

View File

@ -0,0 +1,39 @@
# Built application files
*.apk
*.ap_
# Files for the Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
out/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# Intellij
*.iml
# Keystore files
*.jks

View File

@ -37,11 +37,24 @@
<version>${android-platform-version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<swagger-annotations-version>1.5.0</swagger-annotations-version>
<swagger-annotations-version>1.5.8</swagger-annotations-version>
<httpcomponents-httpcore-version>4.4.4</httpcomponents-httpcore-version>
<httpcomponents-httpmime-version>4.5.2</httpcomponents-httpmime-version>
<google-code-gson-version>2.3.1</google-code-gson-version>
<google-code-gson-version>2.6.2</google-code-gson-version>
<volley-library-version>1.0.19</volley-library-version>
<android-platform-version>4.1.1.4</android-platform-version>
</properties>

View File

@ -14,8 +14,8 @@
<#hasOptionalParams> </hasOptionalParams> :query-params {<#queryParams>"<baseName>" <#collectionFormat>(with-collection-format <paramName> :<collectionFormat>)</collectionFormat><^collectionFormat><paramName></collectionFormat> </queryParams>}
<#hasOptionalParams> </hasOptionalParams> :form-params {<#formParams>"<baseName>" <#collectionFormat>(with-collection-format <paramName> :<collectionFormat>)</collectionFormat><^collectionFormat><paramName></collectionFormat> </formParams>}<#bodyParam>
<#hasOptionalParams> </hasOptionalParams> :body-param <paramName></bodyParam>
<#hasOptionalParams> </hasOptionalParams> :content-types [<#consumes>"<mediaType>"<#hasMore> </hasMore></consumes>]
<#hasOptionalParams> </hasOptionalParams> :accepts [<#produces>"<mediaType>"<#hasMore> </hasMore></produces>]
<#hasOptionalParams> </hasOptionalParams> :content-types [<#consumes>"<& mediaType>"<#hasMore> </hasMore></consumes>]
<#hasOptionalParams> </hasOptionalParams> :accepts [<#produces>"<& mediaType>"<#hasMore> </hasMore></produces>]
<#hasOptionalParams> </hasOptionalParams> :auth-names [<#authMethods>"<&name>"<#hasMore> </hasMore></authMethods>]})<#hasOptionalParams>)</hasOptionalParams>)
(defn <operationId>

Some files were not shown because too many files have changed in this diff Show More