Merge branches 'develop_2.0' and 'jaxrs-server-codegen-improvements' of https://github.com/swagger-api/swagger-codegen into jaxrs-server-codegen-improvements

Conflicts:
	modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java
This commit is contained in:
Ole Lensmar 2015-08-23 10:26:07 -04:00
commit e253fdea33
183 changed files with 5067 additions and 3004 deletions

47
.dockerignore Normal file
View File

@ -0,0 +1,47 @@
*.iml
out/
*.ipr
*.iws
classpath.txt
version.properties
.project
.classpath
lib/*
build/*
generated-files/*
generated-sources/*
generated-code/*
*.swp
*.swo
/target
/generated-files
/nbactions.xml
*.pyc
__pycache__
samples/server-generator/scalatra/output
samples/server-generator/node/output/node_modules
samples/server-generator/scalatra/target
samples/server-generator/scalatra/output/.history
samples/client/petstore/qt5cpp/PetStore/moc_*
samples/client/petstore/qt5cpp/PetStore/*.o
samples/client/petstore/objc/PetstoreClient.xcworkspace/xcuserdata
samples/client/petstore/qt5cpp/build-*
samples/client/petstore/qt5cpp/PetStore/PetStore
samples/client/petstore/qt5cpp/PetStore/Makefile
samples/client/petstore/java/hello.txt
samples/client/petstore/android-java/hello.txt
samples/client/petstore/objc/Build
samples/client/petstore/objc/Pods
samples/server/petstore/nodejs/node_modules
target
.idea
.lib
atlassian-ide-plugin.xml
.DS_Store
samples/client/petstore/php/SwaggerClient-php/composer.lock
samples/client/petstore/php/SwaggerClient-php/vendor/
samples/client/petstore/silex/SwaggerServer/composer.lock
samples/client/petstore/silex/SwaggerServer/venodr/

13
Dockerfile Normal file
View File

@ -0,0 +1,13 @@
FROM maven:3.3-jdk-7
WORKDIR /src
VOLUME /src
VOLUME /root/.m2/repository
ADD . /opt/swagger-codegen
RUN cd /opt/swagger-codegen && mvn package
ENTRYPOINT ["java", "-jar", "/opt/swagger-codegen/modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"]
CMD ["help"]

View File

@ -7,6 +7,24 @@ This is the swagger codegen project, which allows generation of client libraries
Check out [Swagger-Spec](https://github.com/swagger-api/swagger-spec) for additional information about the Swagger project, including additional libraries with support for other languages and more.
## Build and run using docker
```
git clone https://github.com/swagger-api/swagger-codegen
cd swagger-codegen
./run-in-docker.sh mvn package
```
Build a nodejs server stub:
```
./run-in-docker.sh generate \
-i http://petstore.swagger.io/v2/swagger.json \
-l nodejs \
-o samples/server/petstore/nodejs
```
## Compatibility
The Swagger Specification has undergone 3 revisions since initial creation in 2010. The swagger-codegen project has the following compatibilies with the swagger specification:
@ -170,6 +188,7 @@ AkkaScalaClientCodegen.java
AndroidClientCodegen.java
AsyncScalaClientCodegen.java
CSharpClientCodegen.java
FlashClientCodegen.java
JavaClientCodegen.java
JaxRSServerCodegen.java
NodeJSServerCodegen.java

31
bin/flash-petstore.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/flash -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l flash -o samples/client/petstore/flash"
java $JAVA_OPTS -jar $executable $ags

View File

@ -82,10 +82,8 @@
</goals>
</execution>
</executions>
<configuration>
<configuration>
<recompileMode>incremental</recompileMode>
</configuration>
<jvmArgs>
<jvmArg>-Xmx384m</jvmArg>
</jvmArgs>
@ -149,14 +147,6 @@
<artifactId>scala-maven-plugin</artifactId>
<version>${scala-maven-plugin-version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<configuration>
<releaseProfiles>release</releaseProfiles>
<goals>sign</goals>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
@ -180,7 +170,7 @@
</execution>
</executions>
<configuration>
<scala-version>${scala-version}</scala-version>
<scalaVersion>${scala-version}</scalaVersion>
</configuration>
</plugin>
<plugin>

View File

@ -30,6 +30,23 @@ public class CodegenOperation {
public List<Map<String, String>> examples;
public ExternalDocs externalDocs;
private boolean nonempty(List<CodegenParameter> params)
{
return params != null && params.size() > 0;
}
public boolean getHasBodyParam() {
return nonempty(bodyParams);
}
public boolean getHasQueryParams() {
return nonempty(bodyParams);
}
public boolean getHasHeaderParams() {
return nonempty(bodyParams);
}
public boolean getHasPathParams() {
return nonempty(bodyParams);
}
// legacy support
public String nickname;
}

View File

@ -34,4 +34,108 @@ public class CodegenProperty {
public boolean isEnum;
public List<String> _enum;
public Map<String, Object> allowableValues;
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final CodegenProperty other = (CodegenProperty) obj;
if ((this.baseName == null) ? (other.baseName != null) : !this.baseName.equals(other.baseName)) {
return false;
}
if ((this.complexType == null) ? (other.complexType != null) : !this.complexType.equals(other.complexType)) {
return false;
}
if ((this.getter == null) ? (other.getter != null) : !this.getter.equals(other.getter)) {
return false;
}
if ((this.setter == null) ? (other.setter != null) : !this.setter.equals(other.setter)) {
return false;
}
if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) {
return false;
}
if ((this.datatype == null) ? (other.datatype != null) : !this.datatype.equals(other.datatype)) {
return false;
}
if ((this.datatypeWithEnum == null) ? (other.datatypeWithEnum != null) : !this.datatypeWithEnum.equals(other.datatypeWithEnum)) {
return false;
}
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
return false;
}
if ((this.min == null) ? (other.min != null) : !this.min.equals(other.min)) {
return false;
}
if ((this.max == null) ? (other.max != null) : !this.max.equals(other.max)) {
return false;
}
if ((this.defaultValue == null) ? (other.defaultValue != null) : !this.defaultValue.equals(other.defaultValue)) {
return false;
}
if ((this.baseType == null) ? (other.baseType != null) : !this.baseType.equals(other.baseType)) {
return false;
}
if ((this.containerType == null) ? (other.containerType != null) : !this.containerType.equals(other.containerType)) {
return false;
}
if (this.maxLength != other.maxLength && (this.maxLength == null || !this.maxLength.equals(other.maxLength))) {
return false;
}
if (this.minLength != other.minLength && (this.minLength == null || !this.minLength.equals(other.minLength))) {
return false;
}
if ((this.pattern == null) ? (other.pattern != null) : !this.pattern.equals(other.pattern)) {
return false;
}
if ((this.example == null) ? (other.example != null) : !this.example.equals(other.example)) {
return false;
}
if ((this.jsonSchema == null) ? (other.jsonSchema != null) : !this.jsonSchema.equals(other.jsonSchema)) {
return false;
}
if (this.minimum != other.minimum && (this.minimum == null || !this.minimum.equals(other.minimum))) {
return false;
}
if (this.maximum != other.maximum && (this.maximum == null || !this.maximum.equals(other.maximum))) {
return false;
}
if (this.exclusiveMinimum != other.exclusiveMinimum && (this.exclusiveMinimum == null || !this.exclusiveMinimum.equals(other.exclusiveMinimum))) {
return false;
}
if (this.exclusiveMaximum != other.exclusiveMaximum && (this.exclusiveMaximum == null || !this.exclusiveMaximum.equals(other.exclusiveMaximum))) {
return false;
}
if (this.required != other.required && (this.required == null || !this.required.equals(other.required))) {
return false;
}
if (this.secondaryParam != other.secondaryParam && (this.secondaryParam == null || !this.secondaryParam.equals(other.secondaryParam))) {
return false;
}
if (this.isPrimitiveType != other.isPrimitiveType && (this.isPrimitiveType == null || !this.isPrimitiveType.equals(other.isPrimitiveType))) {
return false;
}
if (this.isContainer != other.isContainer && (this.isContainer == null || !this.isContainer.equals(other.isContainer))) {
return false;
}
if (this.isNotContainer != other.isNotContainer && (this.isNotContainer == null || !this.isNotContainer.equals(other.isNotContainer))) {
return false;
}
if (this.isEnum != other.isEnum) {
return false;
}
if (this._enum != other._enum && (this._enum == null || !this._enum.equals(other._enum))) {
return false;
}
if (this.allowableValues != other.allowableValues && (this.allowableValues == null || !this.allowableValues.equals(other.allowableValues))) {
return false;
}
return true;
}
}

View File

@ -63,7 +63,7 @@ import java.util.regex.Pattern;
public class DefaultCodegen {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);
protected static final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);
protected String outputFolder = "";
protected Set<String> defaultIncludes = new HashSet<String>();
@ -80,6 +80,7 @@ public class DefaultCodegen {
protected List<SupportingFile> supportingFiles = new ArrayList<SupportingFile>();
protected List<CliOption> cliOptions = new ArrayList<CliOption>();
protected boolean skipOverwrite;
protected boolean supportsInheritance = false;
public List<CliOption> cliOptions() {
return cliOptions;
@ -538,7 +539,7 @@ public class DefaultCodegen {
final String parentRef = toModelName(parent.getSimpleRef());
m.parent = parentRef;
addImport(m, parentRef);
if (allDefinitions != null) {
if (!supportsInheritance && allDefinitions != null) {
final Model parentModel = allDefinitions.get(parentRef);
if (parentModel instanceof ModelImpl) {
final ModelImpl _parent = (ModelImpl) parentModel;
@ -635,8 +636,10 @@ public class DefaultCodegen {
if (np.getMaximum() != null) {
allowableValues.put("max", np.getMaximum());
}
if(allowableValues.size() > 0) {
property.allowableValues = allowableValues;
}
}
if (p instanceof StringProperty) {
StringProperty sp = (StringProperty) p;

View File

@ -13,9 +13,11 @@ import io.swagger.models.Path;
import io.swagger.models.Swagger;
import io.swagger.models.auth.OAuth2Definition;
import io.swagger.models.auth.SecuritySchemeDefinition;
import io.swagger.models.parameters.Parameter;
import io.swagger.util.Json;
import org.apache.commons.io.IOUtils;
import org.joda.time.DateTime;
import java.io.File;
import java.io.FileInputStream;
@ -62,6 +64,10 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
List<File> files = new ArrayList<File>();
try {
config.processOpts();
config.additionalProperties().put("generatedDate", DateTime.now().toString());
config.additionalProperties().put("generatorClass", config.getClass().toString());
if (swagger.getInfo() != null) {
Info info = swagger.getInfo();
if (info.getTitle() != null) {
@ -111,10 +117,8 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
if (swagger.getBasePath() != null) {
hostBuilder.append(swagger.getBasePath());
} else {
hostBuilder.append("/");
}
String contextPath = swagger.getBasePath() == null ? "/" : swagger.getBasePath();
String contextPath = swagger.getBasePath() == null ? "" : swagger.getBasePath();
String basePath = hostBuilder.toString();
@ -385,12 +389,12 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
for (String resourcePath : paths.keySet()) {
Path path = paths.get(resourcePath);
processOperation(resourcePath, "get", path.getGet(), ops);
processOperation(resourcePath, "put", path.getPut(), ops);
processOperation(resourcePath, "post", path.getPost(), ops);
processOperation(resourcePath, "delete", path.getDelete(), ops);
processOperation(resourcePath, "patch", path.getPatch(), ops);
processOperation(resourcePath, "options", path.getOptions(), ops);
processOperation(resourcePath, "get", path.getGet(), ops, path);
processOperation(resourcePath, "put", path.getPut(), ops, path);
processOperation(resourcePath, "post", path.getPost(), ops, path);
processOperation(resourcePath, "delete", path.getDelete(), ops, path);
processOperation(resourcePath, "patch", path.getPatch(), ops, path);
processOperation(resourcePath, "options", path.getOptions(), ops, path);
}
return ops;
}
@ -403,8 +407,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
return map.get(name);
}
public void processOperation(String resourcePath, String httpMethod, Operation operation, Map<String, List<CodegenOperation>> operations) {
public void processOperation(String resourcePath, String httpMethod, Operation operation, Map<String, List<CodegenOperation>> operations, Path path) {
if (operation != null) {
List<String> tags = operation.getTags();
if (tags == null) {
@ -412,6 +415,28 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
tags.add("default");
}
/*
build up a set of parameter "ids" defined at the operation level
per the swagger 2.0 spec "A unique parameter is defined by a combination of a name and location"
i'm assuming "location" == "in"
*/
Set<String> operationParameters = new HashSet<String>();
if (operation.getParameters() != null) {
for (Parameter parameter : operation.getParameters()) {
operationParameters.add(generateParameterId(parameter));
}
}
//need to propagate path level down to the operation
if(path.getParameters() != null) {
for (Parameter parameter : path.getParameters()) {
//skip propagation if a parameter with the same name is already defined at the operation level
if (!operationParameters.contains(generateParameterId(parameter))) {
operation.addParameter(parameter);
}
}
}
for (String tag : tags) {
CodegenOperation co = config.fromOperation(resourcePath, httpMethod, operation, swagger.getDefinitions());
co.tags = new ArrayList<String>();
@ -456,6 +481,10 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
}
private String generateParameterId(Parameter parameter) {
return parameter.getName() + ":" + parameter.getIn();
}
protected String sanitizeTag(String tag) {
// remove spaces and make strong case
String[] parts = tag.split(" ");

View File

@ -14,6 +14,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
public AbstractTypeScriptClientCodegen() {
super();
supportsInheritance = true;
reservedWords = new HashSet<String>(Arrays.asList("abstract",
"continue", "for", "new", "switch", "assert", "default", "if",
"package", "synchronized", "do", "goto", "private",

View File

@ -0,0 +1,367 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.CliOption;
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.properties.AbstractNumericProperty;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.BooleanProperty;
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.RefProperty;
import io.swagger.models.properties.StringProperty;
import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import java.util.HashMap;
import org.apache.commons.lang.StringUtils;
public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String packageName = "io.swagger";
protected String packageVersion = null;
protected String invokerPackage = "io.swagger";
protected String sourceFolder = "src/main/flex";
public FlashClientCodegen() {
super();
modelPackage = "io.swagger.client.model";
apiPackage = "io.swagger.client.api";
outputFolder = "generated-code" + File.separatorChar + "flash";
modelTemplateFiles.put("model.mustache", ".as");
modelTemplateFiles.put("modelList.mustache", "List.as");
apiTemplateFiles.put("api.mustache", ".as");
templateDir = "flash";
languageSpecificPrimitives.clear();
languageSpecificPrimitives.add("Number");
languageSpecificPrimitives.add("Boolean");
languageSpecificPrimitives.add("String");
languageSpecificPrimitives.add("Date");
languageSpecificPrimitives.add("Array");
languageSpecificPrimitives.add("Dictionary");
typeMapping.clear();
typeMapping.put("integer", "Number");
typeMapping.put("float", "Number");
typeMapping.put("long", "Number");
typeMapping.put("double", "Number");
typeMapping.put("array", "Array");
typeMapping.put("map", "Dictionary");
typeMapping.put("boolean", "Boolean");
typeMapping.put("string", "String");
typeMapping.put("date", "Date");
typeMapping.put("DateTime", "Date");
typeMapping.put("object", "Object");
typeMapping.put("file", "File");
importMapping = new HashMap<String, String>();
importMapping.put("File", "flash.filesystem.File");
// from
reservedWords = new HashSet<String>(
Arrays.asList(
"add", "for", "lt", "tellTarget", "and", "function", "ne", "this", "break", "ge", "new", "typeof", "continue", "gt", "not", "var", "delete", "if", "on", "void", "do", "ifFrameLoaded", "onClipEvent", "while", "else", "in", "or", "with", "eq", "le", "return"));
cliOptions.clear();
cliOptions.add(new CliOption("packageName", "flash package name (convention: package.name), default: io.swagger"));
cliOptions.add(new CliOption("packageVersion", "flash package version, default: 1.0.0"));
cliOptions.add(new CliOption("invokerPackage", "root package for generated code"));
cliOptions.add(new CliOption("sourceFolder", "source folder for generated code. e.g. src/main/flex"));
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("invokerPackage")) {
this.setInvokerPackage((String) additionalProperties.get("invokerPackage"));
} else {
//not set, use default to be passed to template
additionalProperties.put("invokerPackage", invokerPackage);
}
if (additionalProperties.containsKey("sourceFolder")) {
this.setSourceFolder((String) additionalProperties.get("sourceFolder"));
}
if (additionalProperties.containsKey("packageName")) {
setPackageName((String) additionalProperties.get("packageName"));
apiPackage = packageName + ".client.api";
modelPackage = packageName + ".client.model";
}
else {
setPackageName("io.swagger");
}
if (additionalProperties.containsKey("packageVersion")) {
setPackageVersion((String) additionalProperties.get("packageVersion"));
}
else {
setPackageVersion("1.0.0");
}
additionalProperties.put("packageName", packageName);
additionalProperties.put("packageVersion", packageVersion);
//modelPackage = invokerPackage + File.separatorChar + "client" + File.separatorChar + "model";
//apiPackage = invokerPackage + File.separatorChar + "client" + File.separatorChar + "api";
final String invokerFolder = (sourceFolder + File.separator + invokerPackage + File.separator + "swagger" + File.separator).replace(".", File.separator).replace('.', File.separatorChar);
supportingFiles.add(new SupportingFile("ApiInvoker.as", invokerFolder + "common", "ApiInvoker.as"));
supportingFiles.add(new SupportingFile("ApiUrlHelper.as", invokerFolder + "common", "ApiUrlHelper.as"));
supportingFiles.add(new SupportingFile("ApiUserCredentials.as", invokerFolder + "common", "ApiUserCredentials.as"));
supportingFiles.add(new SupportingFile("ListWrapper.as", invokerFolder + "common", "ListWrapper.as"));
supportingFiles.add(new SupportingFile("SwaggerApi.as", invokerFolder + "common", "SwaggerApi.as"));
supportingFiles.add(new SupportingFile("XMLWriter.as", invokerFolder + "common", "XMLWriter.as"));
supportingFiles.add(new SupportingFile("ApiError.as", invokerFolder + "exception", "ApiErrors.as"));
supportingFiles.add(new SupportingFile("ApiErrorCodes.as", invokerFolder + "exception", "ApiErrorCodes.as"));
supportingFiles.add(new SupportingFile("ApiClientEvent.as", invokerFolder + "event", "ApiClientEvent.as"));
supportingFiles.add(new SupportingFile("Response.as", invokerFolder + "event", "Response.as"));
supportingFiles.add(new SupportingFile("build.properties", sourceFolder, "build.properties"));
supportingFiles.add(new SupportingFile("build.xml", sourceFolder, "build.xml"));
supportingFiles.add(new SupportingFile("AirExecutorApp-app.xml", sourceFolder + File.separatorChar + "bin", "AirExecutorApp-app.xml"));
supportingFiles.add(new SupportingFile("ASAXB-0.1.1.swc", sourceFolder + File.separatorChar + "lib", "ASAXB-0.1.1.swc"));
supportingFiles.add(new SupportingFile("as3corelib.swc", sourceFolder + File.separatorChar + "lib", "as3corelib.swc"));
supportingFiles.add(new SupportingFile("flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc", sourceFolder + File.separator + "lib" + File.separator + "ext", "flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc"));
supportingFiles.add(new SupportingFile("flexunit-aircilistener-4.1.0_RC2-28-3.5.0.12683.swc", sourceFolder + File.separator + "lib" + File.separator + "ext", "flexunit-aircilistener-4.1.0_RC2-28-3.5.0.12683.swc"));
supportingFiles.add(new SupportingFile("flexunit-cilistener-4.1.0_RC2-28-3.5.0.12683.swc", sourceFolder + File.separator + "lib" + File.separator + "ext", "flexunit-cilistener-4.1.0_RC2-28-3.5.0.12683.swc"));
supportingFiles.add(new SupportingFile("flexunit-core-flex-4.0.0.2-sdk3.5.0.12683.swc", sourceFolder + File.separator + "lib" + File.separator + "ext", "flexunit-core-flex-4.0.0.2-sdk3.5.0.12683.swc"));
}
private static String dropDots(String str) {
return str.replaceAll("\\.", "_");
}
public CodegenType getTag() {
return CodegenType.CLIENT;
}
public String getName() {
return "flash";
}
public String getHelp() {
return "Generates a Flash client library.";
}
@Override
public String escapeReservedWord(String name) {
return name + "_";
}
@Override
public String apiFileFolder() {
return (outputFolder + File.separatorChar + sourceFolder + File.separatorChar + apiPackage().replace('.', File.separatorChar)).replace('/', File.separatorChar);
}
public String modelFileFolder() {
return (outputFolder + File.separatorChar + sourceFolder + File.separatorChar + modelPackage().replace('.', File.separatorChar)).replace('/', File.separatorChar);
}
@Override
public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return getSwaggerType(p);
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return getSwaggerType(p);
}
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 = toModelName(swaggerType);
}
return type;
}
public String toDefaultValue(Property p) {
if (p instanceof StringProperty) {
return "null";
} else if (p instanceof BooleanProperty) {
return "false";
} else if (p instanceof DateProperty) {
return "null";
} else if (p instanceof DateTimeProperty) {
return "null";
} else if (p instanceof DoubleProperty) {
DoubleProperty dp = (DoubleProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
return "0.0";
} else if (p instanceof FloatProperty) {
FloatProperty dp = (FloatProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
return "0.0";
} else if (p instanceof IntegerProperty) {
IntegerProperty dp = (IntegerProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
return "0";
} else if (p instanceof LongProperty) {
LongProperty dp = (LongProperty) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
return "0";
} else if (p instanceof MapProperty) {
MapProperty ap = (MapProperty) p;
String inner = getSwaggerType(ap.getAdditionalProperties());
return "new Dictionary()";
} else if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
String inner = getSwaggerType(ap.getItems());
return "new Array()";
} else {
return "null";
}
}
@Override
public String toVarName(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_");
// if it's all uppper case, convert to lower case
if (name.matches("^[A-Z_]*$")) {
name = name.toLowerCase();
}
// underscore the variable name
// petId => pet_id
name = camelize(dropDots(name), true);
// for reserved word or word starting with number, append _
if (reservedWords.contains(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 (reservedWords.contains(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 (reservedWords.contains(name)) {
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
}
// underscore the model file name
// PhoneNumber => phone_number
return camelize(dropDots(name));
}
@Override
public String toApiFilename(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_");
// e.g. PhoneNumberApi.rb => phone_number_api.rb
return camelize(name) + "Api";
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "DefaultApi";
}
// e.g. phone_number_api => PhoneNumberApi
return camelize(name) + "Api";
}
@Override
public String toApiVarName(String name) {
if (name.length() == 0) {
return "DefaultApi";
}
return camelize(name) + "Api";
}
@Override
public String toOperationId(String operationId) {
// throw exception if method name is empty
if (StringUtils.isEmpty(operationId)) {
throw new RuntimeException("Empty method name (operationId) not allowed");
}
// method name cannot use reserved keyword, e.g. return
if (reservedWords.contains(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
}
return underscore(operationId);
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public void setPackageVersion(String packageVersion) {
this.packageVersion = packageVersion;
}
public void setInvokerPackage(String invokerPackage) {
this.invokerPackage = invokerPackage;
}
public void setSourceFolder(String sourceFolder) {
this.sourceFolder = sourceFolder;
}
}

View File

@ -1,17 +1,30 @@
package io.swagger.codegen.languages;
import com.google.common.base.Strings;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenModel;
import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile;
import io.swagger.models.ComposedModel;
import io.swagger.models.Model;
import io.swagger.models.ModelImpl;
import io.swagger.models.RefModel;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.StringProperty;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
@ -21,6 +34,8 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String artifactId = "swagger-java-client";
protected String artifactVersion = "1.0.0";
protected String sourceFolder = "src/main/java";
protected String localVariablePrefix = "";
protected Boolean serializableModel = false;
public JavaClientCodegen() {
super();
@ -61,6 +76,8 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
cliOptions.add(new CliOption("artifactId", "artifactId in generated pom.xml"));
cliOptions.add(new CliOption("artifactVersion", "artifact version in generated pom.xml"));
cliOptions.add(new CliOption("sourceFolder", "source folder for generated code"));
cliOptions.add(new CliOption("localVariablePrefix", "prefix for generated code members and local variables"));
cliOptions.add(new CliOption("serializableModel", "boolean - toggle \"implements Serializable\" for generated models"));
}
public CodegenType getTag() {
@ -111,6 +128,19 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
this.setSourceFolder((String) additionalProperties.get("sourceFolder"));
}
if (additionalProperties.containsKey("localVariablePrefix")) {
this.setLocalVariablePrefix((String) additionalProperties.get("localVariablePrefix"));
}
if (additionalProperties.containsKey("serializableModel")) {
this.setSerializableModel(Boolean.valueOf((String)additionalProperties.get("serializableModel")));
} else {
additionalProperties.put("serializableModel", serializableModel);
}
this.sanitizeConfig();
final String invokerFolder = (sourceFolder + File.separator + invokerPackage).replace(".", File.separator);
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("ApiClient.mustache", invokerFolder, "ApiClient.java"));
@ -127,6 +157,25 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
supportingFiles.add(new SupportingFile("auth/OAuth.mustache", authFolder, "OAuth.java"));
}
private void sanitizeConfig() {
// Sanitize any config options here. We also have to update the additionalProperties because
// the whole additionalProperties object is injected into the main object passed to the mustache layer
this.setApiPackage(sanitizePackageName(apiPackage));
if (additionalProperties.containsKey("apiPackage")) {
this.additionalProperties.put("apiPackage", apiPackage);
}
this.setModelPackage(sanitizePackageName(modelPackage));
if (additionalProperties.containsKey("modelPackage")) {
this.additionalProperties.put("modelPackage", modelPackage);
}
this.setInvokerPackage(sanitizePackageName(invokerPackage));
if (additionalProperties.containsKey("invokerPackage")) {
this.additionalProperties.put("invokerPackage", invokerPackage);
}
}
@Override
public String escapeReservedWord(String name) {
@ -249,6 +298,57 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
return camelize(operationId, true);
}
@Override
public CodegenModel fromModel(String name, Model model, Map<String, Model> allDefinitions) {
CodegenModel codegenModel = super.fromModel(name, model, allDefinitions);
if (allDefinitions != null && codegenModel != null && codegenModel.parent != null && codegenModel.hasEnums) {
final Model parentModel = allDefinitions.get(toModelName(codegenModel.parent));
final CodegenModel parentCodegenModel = super.fromModel(codegenModel.parent, parentModel);
codegenModel = this.reconcileInlineEnums(codegenModel, parentCodegenModel);
}
return codegenModel;
}
private CodegenModel reconcileInlineEnums(CodegenModel codegenModel, CodegenModel parentCodegenModel) {
// This generator uses inline classes to define enums, which breaks when
// dealing with models that have subTypes. To clean this up, we will analyze
// the parent and child models, look for enums that match, and remove
// them from the child models and leave them in the parent.
// Because the child models extend the parents, the enums will be available via the parent.
// Only bother with reconciliation if the parent model has enums.
if (parentCodegenModel.hasEnums) {
// Get the properties for the parent and child models
final List<CodegenProperty> parentModelCodegenProperties = parentCodegenModel.vars;
List<CodegenProperty> codegenProperties = codegenModel.vars;
// Iterate over all of the parent model properties
for (CodegenProperty parentModelCodegenPropery : parentModelCodegenProperties) {
// Look for enums
if (parentModelCodegenPropery.isEnum) {
// Now that we have found an enum in the parent class,
// and search the child class for the same enum.
Iterator<CodegenProperty> iterator = codegenProperties.iterator();
while (iterator.hasNext()) {
CodegenProperty codegenProperty = iterator.next();
if (codegenProperty.isEnum && codegenProperty.equals(parentModelCodegenPropery)) {
// We found an enum in the child class that is
// a duplicate of the one in the parent, so remove it.
iterator.remove();
}
}
}
}
codegenModel.vars = codegenProperties;
}
return codegenModel;
}
public void setInvokerPackage(String invokerPackage) {
this.invokerPackage = invokerPackage;
}
@ -268,4 +368,26 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
public void setSourceFolder(String sourceFolder) {
this.sourceFolder = sourceFolder;
}
public void setLocalVariablePrefix(String localVariablePrefix) {
this.localVariablePrefix = localVariablePrefix;
}
public Boolean getSerializableModel() {
return serializableModel;
}
public void setSerializableModel(Boolean serializableModel) {
this.serializableModel = serializableModel;
}
private String sanitizePackageName(String packageName) {
packageName = packageName.trim();
packageName = packageName.replaceAll("[^a-zA-Z0-9_\\.]", "_");
if(Strings.isNullOrEmpty(packageName)) {
return "invalidPackageName";
}
return packageName;
}
}

View File

@ -94,21 +94,6 @@ public class JaxRSServerCodegen extends JavaClientCodegen implements CodegenConf
}
@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 getTypeDeclaration(inner);
}
return super.getTypeDeclaration(p);
}
@Override
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
String basePath = resourcePath;

View File

@ -9,11 +9,19 @@ import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig {
protected String apiVersion = "1.0.0";
@ -197,4 +205,50 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
}
return objs;
}
@SuppressWarnings("unchecked")
private Map<String, Object> getOperations(Map<String, Object> objs) {
Map<String, Object> apiInfo = (Map<String, Object>) objs.get("apiInfo");
List<Map<String, Object>> apis = (List<Map<String, Object>>) apiInfo.get("apis");
Map<String, Object> api = apis.get(0);
return (Map<String, Object>) api.get("operations");
}
private List<Map<String, Object>> sortOperationsByPath(List<CodegenOperation> ops) {
Multimap<String, CodegenOperation> opsByPath = ArrayListMultimap.create();
for (CodegenOperation op : ops) {
opsByPath.put(op.path, op);
}
List<Map<String, Object>> opsByPathList = new ArrayList<Map<String, Object>>();
for (Entry<String, Collection<CodegenOperation>> entry : opsByPath.asMap().entrySet()) {
Map<String, Object> opsByPathEntry = new HashMap<String, Object>();
opsByPathList.add(opsByPathEntry);
opsByPathEntry.put("path", entry.getKey());
opsByPathEntry.put("operation", entry.getValue());
List<CodegenOperation> operationsForThisPath = Lists.newArrayList(entry.getValue());
operationsForThisPath.get(operationsForThisPath.size() - 1).hasMore = null;
if (opsByPathList.size() < opsByPath.asMap().size()) {
opsByPathEntry.put("hasMore", "true");
}
}
return opsByPathList;
}
@Override
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
Map<String, Object> operations = getOperations(objs);
if (operations != null) {
@SuppressWarnings("unchecked")
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
List<Map<String, Object>> opsByPathList = sortOperationsByPath(ops);
operations.put("operationsByPath", opsByPathList);
}
return super.postProcessSupportingFileData(objs);
}
}

View File

@ -215,21 +215,22 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
Property inner = ap.getItems();
String innerType = getSwaggerType(inner);
// In this codition, type of property p is array of primitive,
// return container type with pointer, e.g. `NSArray*'
if (languageSpecificPrimitives.contains(innerType)) {
return getSwaggerType(p) + "*";
}
// In this codition, type of property p is array of model,
// return container type combine inner type with pointer, e.g. `NSArray<SWGTag>*'
String innerTypeDeclaration = getTypeDeclaration(inner);
if (innerTypeDeclaration.endsWith("*")) {
innerTypeDeclaration = innerTypeDeclaration.substring(0, innerTypeDeclaration.length() - 1);
}
// In this codition, type of property p is array of primitive,
// return container type with pointer, e.g. `NSArray* /* NSString */'
if (languageSpecificPrimitives.contains(innerType)) {
return getSwaggerType(p) + "*" + " /* " + innerTypeDeclaration + " */";
}
// In this codition, type of property p is array of model,
// return container type combine inner type with pointer, e.g. `NSArray<SWGTag>*'
else {
return getSwaggerType(p) + "<" + innerTypeDeclaration + ">*";
}
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();

View File

@ -159,15 +159,17 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String toVarName(String name) {
// return the name in underscore style
// PhoneNumber => phone_number
name = underscore(name);
// parameter name starting with number won't compile
// need to escape it by appending _ at the beginning
if (name.matches("^[0-9]")) {
if (name.matches("^\\d.*")) {
name = "_" + name;
}
// return the name in underscore style
// PhoneNumber => phone_number
return underscore(name);
return name;
}
@Override

View File

@ -79,12 +79,12 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("object", "object");
typeMapping.put("DateTime", "\\DateTime");
cliOptions.add(new CliOption("invokerPackage", "The main namespace to use for all classes."));
cliOptions.add(new CliOption("packagePath", "The main package name for classes."));
cliOptions.add(new CliOption("invokerPackage", "The main namespace to use for all classes. e.g. Yay\\Pets"));
cliOptions.add(new CliOption("packagePath", "The main package name for classes. e.g. GeneratedPetstore"));
cliOptions.add(new CliOption("srcBasePath", "The directory under packagePath to serve as source root."));
cliOptions.add(new CliOption("composerVendorName", "The vendor name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name."));
cliOptions.add(new CliOption("composerProjectName", "The project name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name."));
cliOptions.add(new CliOption("artifactVersion", "The version to use in the composer package version field."));
cliOptions.add(new CliOption("composerVendorName", "The vendor name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. yaypets"));
cliOptions.add(new CliOption("composerProjectName", "The project name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. petstore-client"));
cliOptions.add(new CliOption("artifactVersion", "The version to use in the composer package version field. e.g. 1.2.3"));
}
public String getPackagePath() {
@ -284,15 +284,17 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String toVarName(String name) {
// return the name in underscore style
// PhoneNumber => phone_number
name = underscore(name);
// parameter name starting with number won't compile
// need to escape it by appending _ at the beginning
if (name.matches("^[0-9]")) {
if (name.matches("^\\d.*")) {
name = "_" + name;
}
// return the name in underscore style
// PhoneNumber => phone_number
return underscore(name);
return name;
}
@Override

View File

@ -119,7 +119,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
@Override
public String escapeReservedWord(String name) {
return name + "_";
return "_" + name;
}
@Override
@ -179,14 +179,14 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
// petId => pet_id
name = underscore(dropDots(name));
// remove leading underscore
name = name.replaceAll("^_*", "");
// for reserved word or word starting with number, append _
if (reservedWords.contains(name) || name.matches("^\\d.*")) {
name = escapeReservedWord(name);
}
// remove leading underscore
name = name.replaceAll("^_*", "");
return name;
}

View File

@ -88,11 +88,11 @@ public class SilexServerCodegen extends DefaultCodegen implements CodegenConfig
}
public CodegenType getTag() {
return CodegenType.CLIENT;
return CodegenType.SERVER;
}
public String getName() {
return "silex";
return "silex-PHP";
}
public String getHelp() {
@ -154,15 +154,17 @@ public class SilexServerCodegen extends DefaultCodegen implements CodegenConfig
@Override
public String toVarName(String name) {
// return the name in underscore style
// PhoneNumber => phone_number
name = underscore(name);
// parameter name starting with number won't compile
// need to escape it by appending _ at the beginning
if (name.matches("^[0-9]")) {
if (name.matches("^\\d.*")) {
name = "_" + name;
}
// return the name in underscore style
// PhoneNumber => phone_number
return underscore(name);
return name;
}
@Override

View File

@ -1,10 +1,6 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.CodegenResponse;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.SupportingFile;
import io.swagger.codegen.*;
import io.swagger.models.Operation;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
@ -28,7 +24,7 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
protected String configPackage = "";
public SpringMVCServerCodegen() {
super.processOpts();
super();
outputFolder = "generated-code/javaSpringMVC";
modelTemplateFiles.put("model.mustache", ".java");
apiTemplateFiles.put("api.mustache", ".java");
@ -56,6 +52,9 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
"Long",
"Float")
);
cliOptions.add(new CliOption("configPackage", "configuration package for generated code"));
}
public CodegenType getTag() {
@ -74,6 +73,10 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("configPackage")) {
this.setConfigPackage((String) additionalProperties.get("configPackage"));
}
supportingFiles.clear();
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
@ -183,5 +186,9 @@ public class SpringMVCServerCodegen extends JavaClientCodegen implements Codegen
}
return objs;
}
public void setConfigPackage(String configPackage) {
this.configPackage = configPackage;
}
}

View File

@ -40,6 +40,7 @@ import {{invokerPackage}}.auth.HttpBasicAuth;
import {{invokerPackage}}.auth.ApiKeyAuth;
import {{invokerPackage}}.auth.OAuth;
{{>generatedAnnotation}}
public class ApiClient {
private Map<String, Client> hostMap = new HashMap<String, Client>();
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
@ -356,7 +357,7 @@ public class ApiClient {
}
else if(String.class.equals(cls)) {
if(json != null && json.startsWith("\"") && json.endsWith("\"") && json.length() > 1)
return json.substring(1, json.length() - 2);
return json.substring(1, json.length() - 1);
else
return json;
}

View File

@ -1,5 +1,6 @@
package {{invokerPackage}};
{{>generatedAnnotation}}
public class Configuration {
private static ApiClient defaultApiClient = new ApiClient();

View File

@ -7,6 +7,7 @@ import com.fasterxml.jackson.core.JsonGenerator.Feature;
import com.fasterxml.jackson.datatype.joda.*;
{{>generatedAnnotation}}
public class JsonUtil {
public static ObjectMapper mapper;

View File

@ -1,5 +1,6 @@
package {{invokerPackage}};
{{>generatedAnnotation}}
public class Pair {
private String name = "";
private String value = "";

View File

@ -1,5 +1,6 @@
package {{invokerPackage}};
{{>generatedAnnotation}}
public class StringUtil {
/**
* Check if the given array contains the given value (with case-insensitive comparison).

View File

@ -21,24 +21,25 @@ import java.io.File;
import java.util.Map;
import java.util.HashMap;
{{>generatedAnnotation}}
{{#operations}}
public class {{classname}} {
private ApiClient apiClient;
private ApiClient {{localVariablePrefix}}apiClient;
public {{classname}}() {
this(Configuration.getDefaultApiClient());
}
public {{classname}}(ApiClient apiClient) {
this.apiClient = apiClient;
this.{{localVariablePrefix}}apiClient = apiClient;
}
public ApiClient getApiClient() {
return apiClient;
return {{localVariablePrefix}}apiClient;
}
public void setApiClient(ApiClient apiClient) {
this.apiClient = apiClient;
this.{{localVariablePrefix}}apiClient = apiClient;
}
{{#operation}}
@ -49,7 +50,7 @@ public class {{classname}} {
{{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
*/
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
Object postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
Object {{localVariablePrefix}}postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set
if ({{paramName}} == null) {
@ -58,61 +59,61 @@ public class {{classname}} {
{{/required}}{{/allParams}}
// create path and map variables
String path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}
.replaceAll("\\{" + "{{baseName}}" + "\\}", apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};
String {{localVariablePrefix}}path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}
.replaceAll("\\{" + "{{baseName}}" + "\\}", {{localVariablePrefix}}apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};
// query params
List<Pair> queryParams = new ArrayList<Pair>();
Map<String, String> headerParams = new HashMap<String, String>();
Map<String, String> formParams = new HashMap<String, String>();
List<Pair> {{localVariablePrefix}}queryParams = new ArrayList<Pair>();
Map<String, String> {{localVariablePrefix}}headerParams = new HashMap<String, String>();
Map<String, String> {{localVariablePrefix}}formParams = new HashMap<String, String>();
{{#queryParams}}
queryParams.addAll(apiClient.parameterToPairs("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));
{{localVariablePrefix}}queryParams.addAll({{localVariablePrefix}}apiClient.parameterToPairs("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));
{{/queryParams}}
{{#headerParams}}if ({{paramName}} != null)
headerParams.put("{{baseName}}", apiClient.parameterToString({{paramName}}));
{{localVariablePrefix}}headerParams.put("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}}));
{{/headerParams}}
final String[] accepts = {
final String[] {{localVariablePrefix}}accepts = {
{{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}}
};
final String accept = apiClient.selectHeaderAccept(accepts);
final String {{localVariablePrefix}}accept = {{localVariablePrefix}}apiClient.selectHeaderAccept({{localVariablePrefix}}accepts);
final String[] contentTypes = {
final String[] {{localVariablePrefix}}contentTypes = {
{{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}
};
final String contentType = apiClient.selectHeaderContentType(contentTypes);
final String {{localVariablePrefix}}contentType = {{localVariablePrefix}}apiClient.selectHeaderContentType({{localVariablePrefix}}contentTypes);
if(contentType.startsWith("multipart/form-data")) {
boolean hasFields = false;
FormDataMultiPart mp = new FormDataMultiPart();
if({{localVariablePrefix}}contentType.startsWith("multipart/form-data")) {
boolean {{localVariablePrefix}}hasFields = false;
FormDataMultiPart {{localVariablePrefix}}mp = new FormDataMultiPart();
{{#formParams}}{{#notFile}}
if ({{paramName}} != null) {
hasFields = true;
mp.field("{{baseName}}", apiClient.parameterToString({{paramName}}), MediaType.MULTIPART_FORM_DATA_TYPE);
{{localVariablePrefix}}hasFields = true;
{{localVariablePrefix}}mp.field("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}}), MediaType.MULTIPART_FORM_DATA_TYPE);
}
{{/notFile}}{{#isFile}}
if ({{paramName}} != null) {
hasFields = true;
mp.field("{{baseName}}", {{paramName}}.getName());
mp.bodyPart(new FileDataBodyPart("{{baseName}}", {{paramName}}, MediaType.MULTIPART_FORM_DATA_TYPE));
{{localVariablePrefix}}hasFields = true;
{{localVariablePrefix}}mp.field("{{baseName}}", {{paramName}}.getName());
{{localVariablePrefix}}mp.bodyPart(new FileDataBodyPart("{{baseName}}", {{paramName}}, MediaType.MULTIPART_FORM_DATA_TYPE));
}
{{/isFile}}{{/formParams}}
if(hasFields)
postBody = mp;
if({{localVariablePrefix}}hasFields)
{{localVariablePrefix}}postBody = {{localVariablePrefix}}mp;
}
else {
{{#formParams}}{{#notFile}}if ({{paramName}} != null)
formParams.put("{{baseName}}", apiClient.parameterToString({{paramName}}));{{/notFile}}
{{localVariablePrefix}}formParams.put("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}}));{{/notFile}}
{{/formParams}}
}
try {
String[] authNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
String response = apiClient.invokeAPI(path, "{{httpMethod}}", queryParams, postBody, headerParams, formParams, accept, contentType, authNames);
if(response != null){
return {{#returnType}}({{{returnType}}}) apiClient.deserialize(response, "{{returnContainer}}", {{returnBaseType}}.class){{/returnType}};
String[] {{localVariablePrefix}}authNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
String {{localVariablePrefix}}response = {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames);
if({{localVariablePrefix}}response != null){
return {{#returnType}}({{{returnType}}}) {{localVariablePrefix}}apiClient.deserialize({{localVariablePrefix}}response, "{{returnContainer}}", {{returnBaseType}}.class){{/returnType}};
}
else {
return {{#returnType}}null{{/returnType}};

View File

@ -3,6 +3,7 @@ package {{invokerPackage}};
import java.util.Map;
import java.util.List;
{{>generatedAnnotation}}
public class ApiException extends Exception {
private int code = 0;
private String message = null;

View File

@ -5,6 +5,7 @@ import {{invokerPackage}}.Pair;
import java.util.Map;
import java.util.List;
{{>generatedAnnotation}}
public class ApiKeyAuth implements Authentication {
private final String location;
private final String paramName;

View File

@ -5,6 +5,7 @@ import {{invokerPackage}}.Pair;
import java.util.Map;
import java.util.List;
{{>generatedAnnotation}}
public interface Authentication {
/** Apply authentication settings to header and query params. */
void applyToParams(List<Pair> queryParams, Map<String, String> headerParams);

View File

@ -8,6 +8,7 @@ import java.util.List;
import java.io.UnsupportedEncodingException;
import javax.xml.bind.DatatypeConverter;
{{>generatedAnnotation}}
public class HttpBasicAuth implements Authentication {
private String username;
private String password;

View File

@ -5,6 +5,7 @@ import {{invokerPackage}}.Pair;
import java.util.Map;
import java.util.List;
{{>generatedAnnotation}}
public class OAuth implements Authentication {
@Override
public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams) {

View File

@ -0,0 +1 @@
@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}")

View File

@ -3,6 +3,9 @@ package {{package}};
{{#imports}}import {{import}};
{{/imports}}
{{#serializableModel}}
import java.io.Serializable;{{/serializableModel}}
import io.swagger.annotations.*;
import com.fasterxml.jackson.annotation.JsonProperty;
{{#models}}
@ -12,7 +15,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
* {{description}}
**/{{/description}}
@ApiModel(description = "{{{description}}}")
public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {
{{>generatedAnnotation}}
public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#serializableModel}}implements Serializable{{/serializableModel}} {
{{#vars}}{{#isEnum}}
public enum {{datatypeWithEnum}} {
{{#allowableValues}}{{#values}} {{.}}, {{/values}}{{/allowableValues}}

View File

@ -13,6 +13,7 @@ import {{modelPackage}}.*;
{{#imports}}import {{import}};
{{/imports}}
{{>generatedAnnotation}}
{{#operations}}
public class {{classname}} {

View File

@ -0,0 +1 @@
@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}")

View File

@ -12,6 +12,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
* {{description}}
**/{{/description}}
@ApiModel(description = "{{{description}}}")
{{>generatedAnnotation}}
public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {
{{#vars}}{{#isEnum}}
public enum {{datatypeWithEnum}} {

View File

@ -1,5 +1,6 @@
package {{apiPackage}};
{{>generatedAnnotation}}
public class ApiException extends Exception{
private int code;
public ApiException (int code, String msg) {

View File

@ -5,6 +5,7 @@ import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
{{>generatedAnnotation}}
public class ApiOriginFilter implements javax.servlet.Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,

View File

@ -3,6 +3,7 @@ package {{apiPackage}};
import javax.xml.bind.annotation.XmlTransient;
@javax.xml.bind.annotation.XmlRootElement
{{>generatedAnnotation}}
public class ApiResponseMessage {
public static final int ERROR = 1;
public static final int WARNING = 2;

View File

@ -1,5 +1,6 @@
package {{apiPackage}};
{{>generatedAnnotation}}
public class NotFoundException extends ApiException {
private int code;
public NotFoundException (int code, String msg) {

View File

@ -26,6 +26,7 @@ import javax.ws.rs.*;
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
@io.swagger.annotations.Api(value = "/{{baseName}}", description = "the {{baseName}} API")
{{>generatedAnnotation}}
{{#operations}}
public class {{classname}} {

View File

@ -18,6 +18,7 @@ import com.sun.jersey.multipart.FormDataParam;
import javax.ws.rs.core.Response;
{{>generatedAnnotation}}
{{#operations}}
public abstract class {{classname}}Service {
{{#operation}}

View File

@ -3,6 +3,7 @@ package {{package}}.factories;
import {{package}}.{{classname}}Service;
import {{package}}.impl.{{classname}}ServiceImpl;
{{>generatedAnnotation}}
public class {{classname}}ServiceFactory {
private final static {{classname}}Service service = new {{classname}}ServiceImpl();

View File

@ -18,6 +18,7 @@ import com.sun.jersey.multipart.FormDataParam;
import javax.ws.rs.core.Response;
{{>generatedAnnotation}}
{{#operations}}
public class {{classname}}ServiceImpl extends {{classname}}Service {
{{#operation}}

View File

@ -0,0 +1 @@
@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}")

View File

@ -12,6 +12,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
* {{description}}
**/{{/description}}
@ApiModel(description = "{{{description}}}")
{{>generatedAnnotation}}
public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {
{{#vars}}{{#isEnum}}
public enum {{datatypeWithEnum}} {

View File

@ -30,6 +30,7 @@ import static org.springframework.http.MediaType.*;
@Controller
@RequestMapping(value = "/{{baseName}}", produces = {APPLICATION_JSON_VALUE})
@Api(value = "/{{baseName}}", description = "the {{baseName}} API")
{{>generatedAnnotation}}
{{#operations}}
public class {{classname}} {
{{#operation}}

View File

@ -1,5 +1,6 @@
package {{apiPackage}};
{{>generatedAnnotation}}
public class ApiException extends Exception{
private int code;
public ApiException (int code, String msg) {

View File

@ -5,6 +5,7 @@ import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
{{>generatedAnnotation}}
public class ApiOriginFilter implements javax.servlet.Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,

View File

@ -3,6 +3,7 @@ package {{apiPackage}};
import javax.xml.bind.annotation.XmlTransient;
@javax.xml.bind.annotation.XmlRootElement
{{>generatedAnnotation}}
public class ApiResponseMessage {
public static final int ERROR = 1;
public static final int WARNING = 2;

View File

@ -0,0 +1 @@
@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}")

View File

@ -12,6 +12,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
* {{description}}
**/{{/description}}
@ApiModel(description = "{{{description}}}")
{{>generatedAnnotation}}
public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {
{{#vars}}{{#isEnum}}
public enum {{datatypeWithEnum}} {

View File

@ -1,5 +1,6 @@
package {{apiPackage}};
{{>generatedAnnotation}}
public class NotFoundException extends ApiException {
private int code;
public NotFoundException (int code, String msg) {

View File

@ -18,6 +18,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
@EnableSwagger2 //Loads the spring beans required by the framework
@PropertySource("classpath:swagger.properties")
@Import(SwaggerUiConfiguration.class)
{{>generatedAnnotation}}
public class SwaggerConfig {
@Bean
ApiInfo apiInfo() {

View File

@ -8,6 +8,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
@Configuration
@EnableWebMvc
{{>generatedAnnotation}}
public class SwaggerUiConfiguration extends WebMvcConfigurerAdapter {
private static final String[] SERVLET_RESOURCE_LOCATIONS = { "/" };

View File

@ -2,6 +2,7 @@ package {{configPackage}};
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
{{>generatedAnnotation}}
public class WebApplication extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override

View File

@ -3,6 +3,7 @@ package {{configPackage}};
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
{{>generatedAnnotation}}
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {

View File

@ -1,6 +1,7 @@
io.swagger.codegen.languages.AndroidClientCodegen
io.swagger.codegen.languages.AsyncScalaClientCodegen
io.swagger.codegen.languages.CSharpClientCodegen
io.swagger.codegen.languages.FlashClientCodegen
io.swagger.codegen.languages.JavaClientCodegen
io.swagger.codegen.languages.JaxRSServerCodegen
io.swagger.codegen.languages.JavaInflectorServerCodegen

View File

@ -216,7 +216,7 @@ public class ApiInvoker {
}
else if(String.class.equals(cls)) {
if(json != null && json.startsWith("\"") && json.endsWith("\"") && json.length() > 1)
return json.substring(1, json.length() - 2);
return json.substring(1, json.length() - 1);
else
return json;
}

View File

@ -235,7 +235,7 @@ namespace {{packageName}}.Client
{
return JsonConvert.DeserializeObject(content, type);
}
catch (IOException e)
catch (Exception e)
{
throw new ApiException(500, e.Message);
}

View File

@ -56,7 +56,7 @@ public class {{classname}} extends SwaggerApi {
{{#headerParams}}headerParams["{{paramName}}"] = toPathValue({{paramName}});
{{/headerParams}}
var token:AsyncToken = getApiInvoker().invokeAPI(path, "{{httpMethod}}", queryParams, {{#bodyParam}}{{bodyParam}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}}, headerParams);
var token:AsyncToken = getApiInvoker().invokeAPI(path, "{{httpMethod}}", queryParams, {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}}, headerParams);
var requestId: String = getUniqueId();

View File

@ -8,20 +8,17 @@ package {{package}} {
[XmlRootNode(name="{{classname}}")]
public class {{classname}} {
{{#vars}}
{{#description}}/* {{description}} */
{{/description}}
{{#isList}}
{{#isContainer}}
// This declaration below of _{{name}}_obj_class is to force flash compiler to include this class
private var _{{name}}_obj_class: {{baseType}} = null;
[XmlElementWrapper(name="{{name}}")]
[XmlElements(name="{{nameSingular}}", type="{{baseType}}")]
{{/isList}}
{{#isNotContainer}}[XmlElement(name="{{name}}")]
{{/isNotContainer}}
[XmlElementWrapper(name="{{baseName}}")]
[XmlElements(name="{{name}}", type="{{baseType}}")]
{{/isContainer}}
{{^isContainer}}[XmlElement(name="{{baseName}}")]
{{/isContainer}}
public var {{name}}: {{{datatype}}} = {{{defaultValue}}};
{{/vars}}
public function toString(): String {
@ -32,9 +29,8 @@ package {{package}} {
return str;
}
}
{{/model}}
{{/models}}
{{/models}}
}

View File

@ -1,52 +1,158 @@
<html lang="en">
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>API Reference</title>
<title>{{{appName}}}</title>
<link rel="stylesheet" type="text/css" href="site.css" media="screen" />
<style type="text/css">
{{>style.css}}
</style>
</head>
<body>
<h1>{{{appName}}}</h1>
<div class="app-desc">{{{appDescription}}} for {{partner}}</div>
<div class="app-desc">{{{appDescription}}}</div>
{{#infoUrl}}<div class="app-desc">More information: <a href="{{{infoUrl}}}">{{{infoUrl}}}</a></div>{{/infoUrl}}
{{#infoEmail}}<div class="app-desc">Contact Info: <a href="{{{infoEmail}}}">{{{infoEmail}}}</a></div>{{/infoEmail}}
{{#version}}<div class="app-desc">Version: {{{version}}}</div>{{/version}}
<div class="license-info">{{{licenseInfo}}}</div>
<div class="license-url">{{{licenseUrl}}}</div>
<h2>Access</h2>
<div class="method-summary">Customize this message as you see fit!</div>
<h2>Methods</h2>
{{access}}
<h2><a name="__Methods">Methods</a></h2>
[ Jump to <a href="#__Models">Models</a> ]
{{! for the tables of content, I cheat and don't use CSS styles.... }}
<h2>Table of Contents </h2>
<div class="method-summary">{{access}}</div>
{{#apiInfo}}
<ol>
{{#apis}}
{{#operations}}
{{#operation}}
<li><a href="#{{nickname}}"><code><span class="http-method">{{httpMethod}}</span> {{path}}</code></a></li>
{{/operation}}
{{/operations}}
{{/apis}}
</ol>
{{/apiInfo}}
{{#apiInfo}}
{{#apis}}
{{#operations}}{{#operation}}
<div class="method">
<div class="method-path"><pre class="{{httpMethod}}"><code class="huge"><span>{{httpMethod}}</span>: {{path}}</code></pre></div>
<div class="method-tags"> {{#tags}}<span class="method-tag">{{this}}</span>{{/tags}}</div>
<div class="method-summary"><span class="nickname">{{nickname}}</span> {{summary}}</div>
{{#operations}}
{{#operation}}
<div class="method"><a name="{{nickname}}"/>
<div class="method-path">
<a class="up" href="#__Methods">Up</a>
<pre class="{{httpMethod}}"><code class="huge"><span class="http-method">{{httpMethod}}</span> {{path}}</code></pre></div>
<div class="method-summary">{{summary}} (<span class="nickname">{{nickname}}</span>)</div>
{{! notes is operation.description. So why rename it and make it super confusing???? }}
<div class="method-notes">{{notes}}</div>
<h3 class="field-label">Parameters</h3>
{{#hasPathParams}}
<h3 class="field-label">Path parameters</h3>
<div class="field-items">
{{#allParams}}{{>queryParam}}{{>pathParam}}{{>bodyParam}}{{>headerParam}}{{>formParam}}
{{/allParams}}
{{#pathParams}}{{>pathParam}}{{/pathParams}}
</div> <!-- field-items -->
{{/hasPathParams}}
{{#hasConsumes}}
<h3 class="field-label">Consumes</h3>
This API call consumes the following media types via the <span class="heaader">Content-Type</span> request header:
<ul>
{{#consumes}}
<li><code>{{mediaType}}</code></li>
{{/consumes}}
</ul>
{{/hasConsumes}}
{{#hasBodyParam}}
<h3 class="field-label">Request body</h3>
<div class="field-items">
{{#bodyParams}}{{>bodyParam}}{{/bodyParams}}
</div> <!-- field-items -->
{{/hasBodyParam}}
{{#hasHeaderParam}}
<h3 class="field-label">Request headers</h3>
<div class="field-items">
{{#headerParam}}{{>headerParam}}{{/headerParam}}
</div> <!-- field-items -->
{{/hasHeaderParam}}
{{#hasQueryParams}}
<h3 class="field-label">Query parameters</h3>
<div class="field-items">
{{#queryParams}}{{>queryParam}}{{/queryParams}}
</div> <!-- field-items -->
{{/hasQueryParams}}
<!-- Remove Return type... unclear where this comes from;
for our swagger.json files, it is always empty and there is no boolean guard or hasReturnType
do we end up with a heading but not content
{{#returnType}}
<h3 class="field-label">Return type</h3>
<div class="return-type"><a href="#{{returnContainer}}">{{{returnType}}}</a></div>
{{/returnType}}
Todo: process Response Object and its headers, schema, examples
-->
{{#hasExamples}}
{{#examples}}
<h3 class="field-label">Example data</h3>
<div class="example-data-content-type">Content-Type: {{{contentType}}}</div>
<pre class="example"><code>{{{example}}}</code></pre>
{{/examples}}
{{/hasExamples}}
{{#hasProduces}}
<h3 class="field-label">Produces</h3>
This API call produces the following media types according to the <span class="header">Accept</span> request header;
the media type will be conveyed by the <span class="heaader">Content-Type</span> response header.
<ul>
{{#produces}}
<li><code>{{mediaType}}</code></li>
{{/produces}}
</ul>
{{/hasProduces}}
<h3 class="field-label">Responses</h3>
{{#responses}}
<h4 class="field-label">{{code}}</h4>
{{message}}
{{#examples}}
<h3 class="field-label">Example data</h3>
<div class="example-data-content-type">Content-Type: {{{contentType}}}</div>
<pre class="example"><code>{{example}}</code></pre>
{{/examples}}
{{/responses}}
</div> <!-- method -->
<hr>
{{/operation}}{{/operations}}
{{/apis}}{{/apiInfo}}
<hr/>
{{/operation}}
{{/operations}}
{{/apis}}
{{/apiInfo}}
<div class="up"><a href="#__Models">Up</a></div>
<h2><a name="__Models">Models</a></h2>
[ Jump to <a href="#__Methods">Methods</a> ]
<h2>Table of Contents</h2>
<ol>
{{#models}}
{{#model}}
<li><a href="#{{classname}}"><code>{{classname}}</code></a></li>
{{/model}}
{{/models}}
</ol>
<h2>Models</h2>
{{#models}}
{{#model}}
<div class="model">
<h3 class="field-label"><a name="{{classname}}">{{classname}}</a></h3>
<h3 class="field-label"><a name="{{classname}}">{{classname}}</a> <a class="up" href="#__Models">Up</a></h3>
<div class="field-items">
{{#vars}}<div class="param">{{name}} {{#isNotRequired}}(optional){{/isNotRequired}}</div><div class="param-desc"><span class="param-type">{{datatype}}</span> {{description}}</div>
{{/vars}}
@ -54,8 +160,5 @@
</div>
{{/model}}
{{/models}}
<style>
{{>style.css}}
</style>
</body>
</html>

View File

@ -57,6 +57,10 @@ pre {
margin-bottom: 2px;
}
.http-method {
text-transform: uppercase;
}
pre.get {
background-color: #0f6ab4;
}
@ -96,6 +100,10 @@ code {
background-color: #0f6ab4;
}
.up {
float:right;
}
.parameter {
width: 500px;
}

View File

@ -12,8 +12,9 @@
"paths": {
{{#apis}}
{{#operations}}
{{#operation}}
{{#operationsByPath}}
"{{{path}}}": {
{{#operation}}
"{{httpMethod}}": {
"summary": "{{summary}}",
"description":"{{notes}}",
@ -29,9 +30,10 @@
{{#hasMore}},{{/hasMore}}
{{/responses}}
}
}
} {{#hasMore}},{{/hasMore}}
{{/operation}}
} {{#hasMore}},{{/hasMore}}
{{/operationsByPath}}
{{#hasMore}},{{/hasMore}}
{{/operations}}
{{/apis}}

View File

@ -1,7 +1,5 @@
#import "{{classPrefix}}ApiClient.h"
@implementation {{classPrefix}}ApiClient
NSString *const {{classPrefix}}ResponseObjectErrorKey = @"{{classPrefix}}ResponseObject";
static long requestId = 0;
@ -9,9 +7,49 @@ static bool offlineState = false;
static NSMutableSet * queuedRequests = nil;
static bool cacheEnabled = false;
static AFNetworkReachabilityStatus reachabilityStatus = AFNetworkReachabilityStatusNotReachable;
static NSOperationQueue* sharedQueue;
static void (^reachabilityChangeBlock)(int);
@implementation {{classPrefix}}ApiClient
- (instancetype)init {
NSString *baseUrl = [[{{classPrefix}}Configuration sharedConfig] host];
return [self initWithBaseURL:[NSURL URLWithString:baseUrl]];
}
- (instancetype)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if (self) {
self.requestSerializer = [AFJSONRequestSerializer serializer];
self.responseSerializer = [AFJSONResponseSerializer serializer];
// configure reachability
[self configureCacheReachibility];
}
return self;
}
+ (void)initialize {
if (self == [{{classPrefix}}ApiClient class]) {
queuedRequests = [[NSMutableSet alloc] init];
// initialize URL cache
[self configureCacheWithMemoryAndDiskCapacity:4*1024*1024 diskSize:32*1024*1024];
}
}
#pragma mark - Setter Methods
+ (void) setOfflineState:(BOOL) state {
offlineState = state;
}
+ (void) setCacheEnabled:(BOOL)enabled {
cacheEnabled = enabled;
}
- (void)setHeaderValue:(NSString*) value
forKey:(NSString*) forKey {
[self.requestSerializer setValue:value forHTTPHeaderField:forKey];
}
#pragma mark - Log Methods
- (void)logResponse:(AFHTTPRequestOperation *)operation
@ -34,16 +72,10 @@ static void (^reachabilityChangeBlock)(int);
#pragma mark - Cache Methods
+ (void) setCacheEnabled:(BOOL)enabled {
cacheEnabled = enabled;
}
+(void)clearCache {
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}
#pragma mark -
+(void)configureCacheWithMemoryAndDiskCapacity: (unsigned long) memorySize
diskSize: (unsigned long) diskSize {
NSAssert(memorySize > 0, @"invalid in-memory cache size");
@ -58,43 +90,7 @@ static void (^reachabilityChangeBlock)(int);
[NSURLCache setSharedURLCache:cache];
}
+(NSOperationQueue*) sharedQueue {
return sharedQueue;
}
+({{classPrefix}}ApiClient *)sharedClientFromPool:(NSString *)baseUrl {
static NSMutableDictionary *_pool = nil;
if (queuedRequests == nil) {
queuedRequests = [[NSMutableSet alloc]init];
}
if(_pool == nil) {
// setup static vars
// create queue
sharedQueue = [[NSOperationQueue alloc] init];
// create pool
_pool = [[NSMutableDictionary alloc] init];
// initialize URL cache
[{{classPrefix}}ApiClient configureCacheWithMemoryAndDiskCapacity:4*1024*1024 diskSize:32*1024*1024];
// configure reachability
[{{classPrefix}}ApiClient configureCacheReachibilityForHost:baseUrl];
}
@synchronized(self) {
{{classPrefix}}ApiClient * client = [_pool objectForKey:baseUrl];
if (client == nil) {
client = [[{{classPrefix}}ApiClient alloc] initWithBaseURL:[NSURL URLWithString:baseUrl]];
[_pool setValue:client forKey:baseUrl ];
if([[{{classPrefix}}Configuration sharedConfig] debug])
NSLog(@"new client for path %@", baseUrl);
}
if([[{{classPrefix}}Configuration sharedConfig] debug])
NSLog(@"returning client for path %@", baseUrl);
return client;
}
}
#pragma mark - Utility Methods
/*
* Detect `Accept` from accepts
@ -141,11 +137,23 @@ static void (^reachabilityChangeBlock)(int);
}
}
-(void)setHeaderValue:(NSString*) value
forKey:(NSString*) forKey {
[self.requestSerializer setValue:value forHTTPHeaderField:forKey];
+ (NSString*)escape:(id)unescaped {
if([unescaped isKindOfClass:[NSString class]]){
return (NSString *)CFBridgingRelease
(CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef) unescaped,
NULL,
(CFStringRef)@"!*'();:@&=+$,/?%#[]",
kCFStringEncodingUTF8));
}
else {
return [NSString stringWithFormat:@"%@", unescaped];
}
}
#pragma mark - Request Methods
+(unsigned long)requestQueueSize {
return [queuedRequests count];
}
@ -171,46 +179,28 @@ static void (^reachabilityChangeBlock)(int);
[queuedRequests removeObject:requestId];
}
+(NSString*) escape:(id)unescaped {
if([unescaped isKindOfClass:[NSString class]]){
return (NSString *)CFBridgingRelease
(CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef) unescaped,
NULL,
(CFStringRef)@"!*'();:@&=+$,/?%#[]",
kCFStringEncodingUTF8));
}
else {
return [NSString stringWithFormat:@"%@", unescaped];
}
}
-(Boolean) executeRequestWithId:(NSNumber*) requestId {
NSSet* matchingItems = [queuedRequests objectsPassingTest:^BOOL(id obj, BOOL *stop) {
if([obj intValue] == [requestId intValue])
return TRUE;
else return FALSE;
if([obj intValue] == [requestId intValue]) {
return YES;
}
else {
return NO;
}
}];
if(matchingItems.count == 1) {
if([[{{classPrefix}}Configuration sharedConfig] debug])
NSLog(@"removing request id %@", requestId);
[queuedRequests removeObject:requestId];
return true;
return YES;
}
else {
return NO;
}
else
return false;
}
-(id)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
self.requestSerializer = [AFJSONRequestSerializer serializer];
self.responseSerializer = [AFJSONResponseSerializer serializer];
if (!self)
return nil;
return self;
}
#pragma mark - Reachability Methods
+(AFNetworkReachabilityStatus) getReachabilityStatus {
return reachabilityStatus;
@ -220,12 +210,8 @@ static void (^reachabilityChangeBlock)(int);
reachabilityChangeBlock = changeBlock;
}
+(void) setOfflineState:(BOOL) state {
offlineState = state;
}
+(void) configureCacheReachibilityForHost:(NSString*)host {
[[{{classPrefix}}ApiClient sharedClientFromPool:host].reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
- (void) configureCacheReachibility {
[self.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
reachabilityStatus = status;
switch (status) {
case AFNetworkReachabilityStatusUnknown:
@ -254,99 +240,14 @@ static void (^reachabilityChangeBlock)(int);
default:
break;
}
// call the reachability block, if configured
if(reachabilityChangeBlock != nil) {
reachabilityChangeBlock(status);
}
}];
[[{{classPrefix}}ApiClient sharedClientFromPool:host].reachabilityManager startMonitoring];
}
-(NSString*) pathWithQueryParamsToString:(NSString*) path
queryParams:(NSDictionary*) queryParams {
NSString * separator = nil;
int counter = 0;
NSMutableString * requestUrl = [NSMutableString stringWithFormat:@"%@", path];
if(queryParams != nil){
for(NSString * key in [queryParams keyEnumerator]){
if(counter == 0) separator = @"?";
else separator = @"&";
id queryParam = [queryParams valueForKey:key];
if([queryParam isKindOfClass:[NSString class]]){
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator,
[{{classPrefix}}ApiClient escape:key], [{{classPrefix}}ApiClient escape:[queryParams valueForKey:key]]]];
}
else if([queryParam isKindOfClass:[{{classPrefix}}QueryParamCollection class]]){
{{classPrefix}}QueryParamCollection * coll = ({{classPrefix}}QueryParamCollection*) queryParam;
NSArray* values = [coll values];
NSString* format = [coll format];
if([format isEqualToString:@"csv"]) {
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator,
[{{classPrefix}}ApiClient escape:key], [NSString stringWithFormat:@"%@", [values componentsJoinedByString:@","]]]];
}
else if([format isEqualToString:@"tsv"]) {
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator,
[{{classPrefix}}ApiClient escape:key], [NSString stringWithFormat:@"%@", [values componentsJoinedByString:@"\t"]]]];
}
else if([format isEqualToString:@"pipes"]) {
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator,
[{{classPrefix}}ApiClient escape:key], [NSString stringWithFormat:@"%@", [values componentsJoinedByString:@"|"]]]];
}
else if([format isEqualToString:@"multi"]) {
for(id obj in values) {
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator,
[{{classPrefix}}ApiClient escape:key], [NSString stringWithFormat:@"%@", obj]]];
counter += 1;
}
}
}
else {
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator,
[{{classPrefix}}ApiClient escape:key], [NSString stringWithFormat:@"%@", [queryParams valueForKey:key]]]];
}
counter += 1;
}
}
return requestUrl;
}
/**
* Update header and query params based on authentication settings
*/
- (void) updateHeaderParams:(NSDictionary *__autoreleasing *)headers
queryParams:(NSDictionary *__autoreleasing *)querys
WithAuthSettings:(NSArray *)authSettings {
if (!authSettings || [authSettings count] == 0) {
return;
}
NSMutableDictionary *headersWithAuth = [NSMutableDictionary dictionaryWithDictionary:*headers];
NSMutableDictionary *querysWithAuth = [NSMutableDictionary dictionaryWithDictionary:*querys];
{{classPrefix}}Configuration *config = [{{classPrefix}}Configuration sharedConfig];
for (NSString *auth in authSettings) {
NSDictionary *authSetting = [[config authSettings] objectForKey:auth];
if (authSetting) {
if ([authSetting[@"in"] isEqualToString:@"header"]) {
[headersWithAuth setObject:authSetting[@"value"] forKey:authSetting[@"key"]];
}
else if ([authSetting[@"in"] isEqualToString:@"query"]) {
[querysWithAuth setObject:authSetting[@"value"] forKey:authSetting[@"key"]];
}
}
}
*headers = [NSDictionary dictionaryWithDictionary:headersWithAuth];
*querys = [NSDictionary dictionaryWithDictionary:querysWithAuth];
[self.reachabilityManager startMonitoring];
}
#pragma mark - Deserialize methods
@ -356,13 +257,14 @@ static void (^reachabilityChangeBlock)(int);
NSTextCheckingResult *match = nil;
NSMutableArray *resultArray = nil;
NSMutableDictionary *resultDict = nil;
NSString *innerType = nil;
// return nil if data is nil or class is nil
if (!data || !class) {
return nil;
}
// remove "*" from class, if ends with "*"
// remove "*" from class, if ends with "*"
if ([class hasSuffix:@"*"]) {
class = [class substringToIndex:[class length] - 1];
}
@ -383,7 +285,7 @@ static void (^reachabilityChangeBlock)(int);
range:NSMakeRange(0, [class length])];
if (match) {
NSString *innerType = [class substringWithRange:[match rangeAtIndex:1]];
innerType = [class substringWithRange:[match rangeAtIndex:1]];
resultArray = [NSMutableArray arrayWithCapacity:[data count]];
[data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
@ -395,8 +297,8 @@ static void (^reachabilityChangeBlock)(int);
}
// list of primitives
NSString *arrayOfPrimitivesPet = @"NSArray";
regexp = [NSRegularExpression regularExpressionWithPattern:arrayOfPrimitivesPet
NSString *arrayOfPrimitivesPat = @"NSArray\\* /\\* (.+) \\*/";
regexp = [NSRegularExpression regularExpressionWithPattern:arrayOfPrimitivesPat
options:NSRegularExpressionCaseInsensitive
error:nil];
match = [regexp firstMatchInString:class
@ -404,16 +306,18 @@ static void (^reachabilityChangeBlock)(int);
range:NSMakeRange(0, [class length])];
if (match) {
innerType = [class substringWithRange:[match rangeAtIndex:1]];
resultArray = [NSMutableArray arrayWithCapacity:[data count]];
[data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[resultArray addObject:[self deserialize:obj class:NSStringFromClass([obj class])]];
[resultArray addObject:[self deserialize:obj class:innerType]];
}];
return resultArray;
}
// map
NSString *dictPat = @"NSDictionary\\* /\\* (.+), (.+) \\*/";
NSString *dictPat = @"NSDictionary\\* /\\* (.+?), (.+) \\*/";
regexp = [NSRegularExpression regularExpressionWithPattern:dictPat
options:NSRegularExpressionCaseInsensitive
error:nil];
@ -433,7 +337,7 @@ static void (^reachabilityChangeBlock)(int);
}
// primitives
NSArray *primitiveTypes = @[@"NSString", @"NSDate", @"BOOL", @"NSNumber"];
NSArray *primitiveTypes = @[@"NSString", @"NSDate", @"NSNumber"];
if ([primitiveTypes containsObject:class]) {
if ([class isEqualToString:@"NSString"]) {
@ -442,25 +346,24 @@ static void (^reachabilityChangeBlock)(int);
else if ([class isEqualToString:@"NSDate"]) {
return [NSDate dateWithISO8601String:data];
}
else if ([class isEqualToString:@"BOOL"]) {
// Returns YES on encountering one of "Y", "y", "T", "t", or a
// digit 1-9—the method ignores any trailing characters
// NSString => BOOL => NSNumber
return [NSNumber numberWithBool:[data boolValue]];
}
else if ([class isEqualToString:@"NSNumber"]) {
// NSNumber from NSNumber
if ([data isKindOfClass:[NSNumber class]]) {
return data;
}
else if ([data isKindOfClass:[NSString class]]) {
// NSNumber (NSCFBoolean) from NSString
if ([[data lowercaseString] isEqualToString:@"true"] || [[data lowercaseString] isEqualToString:@"false"]) {
return [NSNumber numberWithBool:[data boolValue]];
// NSNumber from NSString
else {
} else {
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
return [formatter numberFromString:data];
}
}
}
}
// model
Class ModelClass = NSClassFromString(class);
@ -564,6 +467,7 @@ static void (^reachabilityChangeBlock)(int);
-(NSNumber*) requestWithCompletionBlock: (NSString*) path
method: (NSString*) method
pathParams: (NSDictionary *) pathParams
queryParams: (NSDictionary*) queryParams
formParams: (NSDictionary *) formParams
files: (NSDictionary *) files
@ -596,11 +500,29 @@ static void (^reachabilityChangeBlock)(int);
self.responseSerializer = [AFHTTPResponseSerializer serializer];
}
// sanitize parameters
pathParams = [self sanitizeForSerialization:pathParams];
queryParams = [self sanitizeForSerialization:queryParams];
headerParams = [self sanitizeForSerialization:headerParams];
formParams = [self sanitizeForSerialization:formParams];
body = [self sanitizeForSerialization:body];
// auth setting
[self updateHeaderParams:&headerParams queryParams:&queryParams WithAuthSettings:authSettings];
NSMutableString *resourcePath = [NSMutableString stringWithString:path];
[pathParams enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[resourcePath replaceCharactersInRange:[resourcePath rangeOfString:[NSString stringWithFormat:@"%@%@%@", @"{", key, @"}"]]
withString:[SWGApiClient escape:obj]];
}];
NSMutableURLRequest * request = nil;
NSString* pathWithQueryParams = [self pathWithQueryParamsToString:path queryParams:queryParams];
NSString* pathWithQueryParams = [self pathWithQueryParamsToString:resourcePath queryParams:queryParams];
if ([pathWithQueryParams hasPrefix:@"/"]) {
pathWithQueryParams = [pathWithQueryParams substringFromIndex:1];
}
NSString* urlString = [[NSURL URLWithString:pathWithQueryParams relativeToURL:self.baseURL] absoluteString];
if (files.count > 0) {
request = [self.requestSerializer multipartFormRequestWithMethod:@"POST"
@ -632,20 +554,21 @@ static void (^reachabilityChangeBlock)(int);
}
}
// request cache
BOOL hasHeaderParams = false;
if(headerParams != nil && [headerParams count] > 0) {
hasHeaderParams = true;
}
if(offlineState) {
NSLog(@"%@ cache forced", path);
NSLog(@"%@ cache forced", resourcePath);
[request setCachePolicy:NSURLRequestReturnCacheDataDontLoad];
}
else if(!hasHeaderParams && [method isEqualToString:@"GET"] && cacheEnabled) {
NSLog(@"%@ cache enabled", path);
NSLog(@"%@ cache enabled", resourcePath);
[request setCachePolicy:NSURLRequestUseProtocolCachePolicy];
}
else {
NSLog(@"%@ cache disabled", path);
NSLog(@"%@ cache disabled", resourcePath);
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
}
@ -674,8 +597,133 @@ static void (^reachabilityChangeBlock)(int);
return requestId;
}
#pragma mark -
- (NSString*) pathWithQueryParamsToString:(NSString*) path
queryParams:(NSDictionary*) queryParams {
NSString * separator = nil;
int counter = 0;
NSMutableString * requestUrl = [NSMutableString stringWithFormat:@"%@", path];
if(queryParams != nil){
for(NSString * key in [queryParams keyEnumerator]){
if(counter == 0) separator = @"?";
else separator = @"&";
id queryParam = [queryParams valueForKey:key];
if([queryParam isKindOfClass:[NSString class]]){
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator,
[{{classPrefix}}ApiClient escape:key], [{{classPrefix}}ApiClient escape:[queryParams valueForKey:key]]]];
}
else if([queryParam isKindOfClass:[{{classPrefix}}QueryParamCollection class]]){
{{classPrefix}}QueryParamCollection * coll = ({{classPrefix}}QueryParamCollection*) queryParam;
NSArray* values = [coll values];
NSString* format = [coll format];
if([format isEqualToString:@"csv"]) {
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator,
[{{classPrefix}}ApiClient escape:key], [NSString stringWithFormat:@"%@", [values componentsJoinedByString:@","]]]];
}
else if([format isEqualToString:@"tsv"]) {
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator,
[{{classPrefix}}ApiClient escape:key], [NSString stringWithFormat:@"%@", [values componentsJoinedByString:@"\t"]]]];
}
else if([format isEqualToString:@"pipes"]) {
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator,
[{{classPrefix}}ApiClient escape:key], [NSString stringWithFormat:@"%@", [values componentsJoinedByString:@"|"]]]];
}
else if([format isEqualToString:@"multi"]) {
for(id obj in values) {
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator,
[{{classPrefix}}ApiClient escape:key], [NSString stringWithFormat:@"%@", obj]]];
counter += 1;
}
}
}
else {
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator,
[{{classPrefix}}ApiClient escape:key], [NSString stringWithFormat:@"%@", [queryParams valueForKey:key]]]];
}
counter += 1;
}
}
return requestUrl;
}
/**
* Update header and query params based on authentication settings
*/
- (void) updateHeaderParams:(NSDictionary *__autoreleasing *)headers
queryParams:(NSDictionary *__autoreleasing *)querys
WithAuthSettings:(NSArray *)authSettings {
if (!authSettings || [authSettings count] == 0) {
return;
}
NSMutableDictionary *headersWithAuth = [NSMutableDictionary dictionaryWithDictionary:*headers];
NSMutableDictionary *querysWithAuth = [NSMutableDictionary dictionaryWithDictionary:*querys];
{{classPrefix}}Configuration *config = [{{classPrefix}}Configuration sharedConfig];
for (NSString *auth in authSettings) {
NSDictionary *authSetting = [[config authSettings] objectForKey:auth];
if (authSetting) {
if ([authSetting[@"in"] isEqualToString:@"header"]) {
[headersWithAuth setObject:authSetting[@"value"] forKey:authSetting[@"key"]];
}
else if ([authSetting[@"in"] isEqualToString:@"query"]) {
[querysWithAuth setObject:authSetting[@"value"] forKey:authSetting[@"key"]];
}
}
}
*headers = [NSDictionary dictionaryWithDictionary:headersWithAuth];
*querys = [NSDictionary dictionaryWithDictionary:querysWithAuth];
}
- (id) sanitizeForSerialization:(id) object {
if (object == nil) {
return nil;
}
else if ([object isKindOfClass:[NSString class]] || [object isKindOfClass:[NSNumber class]] || [object isKindOfClass:[SWGQueryParamCollection class]]) {
return object;
}
else if ([object isKindOfClass:[NSDate class]]) {
return [object ISO8601String];
}
else if ([object isKindOfClass:[NSArray class]]) {
NSMutableArray *sanitizedObjs = [NSMutableArray arrayWithCapacity:[object count]];
[object enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (obj) {
[sanitizedObjs addObject:[self sanitizeForSerialization:obj]];
}
}];
return sanitizedObjs;
}
else if ([object isKindOfClass:[NSDictionary class]]) {
NSMutableDictionary *sanitizedObjs = [NSMutableDictionary dictionaryWithCapacity:[object count]];
[object enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
if (obj) {
[sanitizedObjs setValue:[self sanitizeForSerialization:obj] forKey:key];
}
}];
return sanitizedObjs;
}
else if ([object isKindOfClass:[SWGObject class]]) {
return [object toDictionary];
}
else {
NSException *e = [NSException
exceptionWithName:@"InvalidObjectArgumentException"
reason:[NSString stringWithFormat:@"*** The argument object: %@ is invalid", object]
userInfo:nil];
@throw e;
}
}
@end

View File

@ -15,6 +15,8 @@
{{#models}}{{#model}}#import "{{classname}}.h"
{{/model}}{{/models}}
@class {{classPrefix}}Configuration;
/**
* A key for `NSError` user info dictionaries.
*
@ -29,22 +31,6 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
@property(nonatomic, assign) NSTimeInterval timeoutInterval;
@property(nonatomic, readonly) NSOperationQueue* queue;
/**
* Gets the Api Client instance from pool
*
* @param baseUrl The base url of api client.
*
* @return The {{classPrefix}}ApiClient instance.
*/
+({{classPrefix}}ApiClient *)sharedClientFromPool:(NSString *)baseUrl;
/**
* Gets the operations queue
*
* @return The `shardQueue` static variable.
*/
+(NSOperationQueue*) sharedQueue;
/**
* Clears Cache
*/
@ -116,11 +102,9 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
+(void) setReachabilityChangeBlock:(void(^)(int))changeBlock;
/**
* Sets the client reachability strategy
*
* @param host The host of {{classPrefix}}ApiClient.
* Sets the api client reachability strategy
*/
+(void) configureCacheReachibilityForHost:(NSString*)host;
- (void)configureCacheReachibility;
/**
* Detects Accept header from accepts NSArray
@ -184,6 +168,7 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
*
* @param path Request url.
* @param method Request method.
* @param pathParams Request path parameters.
* @param queryParams Request query parameters.
* @param body Request body.
* @param headerParams Request header parameters.
@ -196,6 +181,7 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
*/
-(NSNumber*) requestWithCompletionBlock:(NSString*) path
method:(NSString*) method
pathParams:(NSDictionary *) pathParams
queryParams:(NSDictionary*) queryParams
formParams:(NSDictionary *) formParams
files:(NSDictionary *) files
@ -207,4 +193,11 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
responseType:(NSString *) responseType
completionBlock:(void (^)(id, NSError *))completionBlock;
/**
* Sanitize object for request
*
* @param object The query/path/header/form/body param to be sanitized.
*/
- (id) sanitizeForSerialization:(id) object;
@end

View File

@ -25,6 +25,8 @@
- (instancetype) init {
self = [super init];
if (self) {
self.apiClient = nil;
self.host = @"{{basePath}}";
self.username = @"";
self.password = @"";
self.tempFolderPath = nil;
@ -104,13 +106,26 @@
- (NSDictionary *) authSettings {
return @{
@"api_key": @{
{{#authMethods}}
{{#isApiKey}}
@"{{name}}":
@{
@"type": @"api_key",
@"in": @"header",
@"key": @"api_key",
@"value": [self getApiKeyWithPrefix:@"api_key"]
@"in": {{#isKeyInHeader}}@"header"{{/isKeyInHeader}}{{#isKeyInQuery}}@"query"{{/isKeyInQuery}},
@"key": @"{{keyParamName}}",
@"value": [self getApiKeyWithPrefix:@"{{keyParamName}}"]
},
{{/isApiKey}}
{{#isBasic}}
@"{{name}}":
@{
@"type": @"basic",
@"in": @"header",
@"key": @"Authorization",
@"value": [self getBasicAuthToken]
},
{{/isBasic}}
{{/authMethods}}
};
}

View File

@ -1,4 +1,5 @@
#import <Foundation/Foundation.h>
#import "{{classPrefix}}ApiClient.h"
/** The `{{classPrefix}}Configuration` class manages the configurations for the sdk.
*
@ -6,8 +7,20 @@
* https://github.com/swagger-api/swagger-codegen
* Do not edit the class manually.
*/
@class {{classPrefix}}ApiClient;
@interface {{classPrefix}}Configuration : NSObject
/**
* Default api client
*/
@property (nonatomic) {{classPrefix}}ApiClient *apiClient;
/**
* Default base url
*/
@property (nonatomic) NSString *host;
/**
* Api key values for Api Key type Authentication

View File

@ -12,6 +12,10 @@ To install it, put the API client library in your project and then simply add th
pod "{{podName}}", :path => "/path/to/lib"
```
## Recommendation
It's recommended to create an instance of ApiClient per thread in a multithreaded environment to avoid any potential issue.
## Author
{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}}

View File

@ -11,14 +11,16 @@
@implementation {{classname}}
static NSString * basePath = @"{{basePath}}";
#pragma mark - Initialize methods
- (id) init {
self = [super init];
if (self) {
self.apiClient = [{{classPrefix}}ApiClient sharedClientFromPool:basePath];
{{classPrefix}}Configuration *config = [{{classPrefix}}Configuration sharedConfig];
if (config.apiClient == nil) {
config.apiClient = [[{{classPrefix}}ApiClient alloc] init];
}
self.apiClient = config.apiClient;
self.defaultHeaders = [NSMutableDictionary dictionary];
}
return self;
@ -27,12 +29,7 @@ static NSString * basePath = @"{{basePath}}";
- (id) initWithApiClient:({{classPrefix}}ApiClient *)apiClient {
self = [super init];
if (self) {
if (apiClient) {
self.apiClient = apiClient;
}
else {
self.apiClient = [{{classPrefix}}ApiClient sharedClientFromPool:basePath];
}
self.defaultHeaders = [NSMutableDictionary dictionary];
}
return self;
@ -50,14 +47,6 @@ static NSString * basePath = @"{{basePath}}";
return singletonAPI;
}
+(void) setBasePath:(NSString*)path {
basePath = path;
}
+(NSString*) getBasePath {
return basePath;
}
-(void) addHeader:(NSString*)value forKey:(NSString*)key {
[self.defaultHeaders setValue:value forKey:key];
}
@ -93,13 +82,17 @@ static NSString * basePath = @"{{basePath}}";
}
{{/required}}{{/allParams}}
NSMutableString* requestUrl = [NSMutableString stringWithFormat:@"%@{{path}}", basePath];
NSMutableString* resourcePath = [NSMutableString stringWithFormat:@"{{path}}"];
// remove format in URL if needed
if ([requestUrl rangeOfString:@".{format}"].location != NSNotFound)
[requestUrl replaceCharactersInRange: [requestUrl rangeOfString:@".{format}"] withString:@".json"];
if ([resourcePath rangeOfString:@".{format}"].location != NSNotFound) {
[resourcePath replaceCharactersInRange: [resourcePath rangeOfString:@".{format}"] withString:@".json"];
}
{{#pathParams}}[requestUrl replaceCharactersInRange: [requestUrl rangeOfString:[NSString stringWithFormat:@"%@%@%@", @"{", @"{{baseName}}", @"}"]] withString: [{{classPrefix}}ApiClient escape:{{paramName}}]];
NSMutableDictionary *pathParams = [[NSMutableDictionary alloc] init];
{{#pathParams}}if ({{paramName}} != nil) {
pathParams[@"{{baseName}}"] = {{paramName}};
}
{{/pathParams}}
NSMutableDictionary* queryParams = [[NSMutableDictionary alloc] init];
@ -142,26 +135,12 @@ static NSString * basePath = @"{{basePath}}";
NSMutableDictionary *files = [[NSMutableDictionary alloc] init];
{{#bodyParam}}
bodyParam = {{paramName}};
if(bodyParam != nil && [bodyParam isKindOfClass:[NSArray class]]){
NSMutableArray *objs = [[NSMutableArray alloc] init];
for (id dict in (NSArray*)bodyParam) {
if([dict respondsToSelector:@selector(toDictionary)]) {
[objs addObject:[({{classPrefix}}Object*)dict toDictionary]];
}
else{
[objs addObject:dict];
}
}
bodyParam = objs;
}
else if([bodyParam respondsToSelector:@selector(toDictionary)]) {
bodyParam = [({{classPrefix}}Object*)bodyParam toDictionary];
}
{{/bodyParam}}{{^bodyParam}}
{{#formParams}}
{{#notFile}}
formParams[@"{{paramName}}"] = {{paramName}};
if ({{paramName}}) {
formParams[@"{{baseName}}"] = {{paramName}};
}
{{/notFile}}{{#isFile}}
files[@"{{paramName}}"] = {{paramName}};
{{/isFile}}
@ -175,8 +154,9 @@ static NSString * basePath = @"{{basePath}}";
}
{{/requiredParams}}
{{/requiredParamCount}}
return [self.apiClient requestWithCompletionBlock: requestUrl
return [self.apiClient requestWithCompletionBlock: resourcePath
method: @"{{httpMethod}}"
pathParams: pathParams
queryParams: queryParams
formParams: formParams
files: files

View File

@ -20,8 +20,6 @@
-(void) addHeader:(NSString*)value forKey:(NSString*)key;
-(unsigned long) requestQueueSize;
+({{classname}}*) apiWithHeader:(NSString*)headerValue key:(NSString*)key;
+(void) setBasePath:(NSString*)basePath;
+(NSString*) getBasePath;
{{#operation}}
///
///

View File

@ -191,7 +191,7 @@ class ObjectSerializer
$values[] = $this->deserialize($value, $subClass);
}
$deserialized = $values;
} elseif ($class === 'DateTime') {
} elseif ($class === '\DateTime') {
$deserialized = new \DateTime($data);
} elseif (in_array($class, array('string', 'int', 'float', 'double', 'bool', 'object'))) {
settype($data, $class);

View File

@ -89,7 +89,7 @@ class Configuration
*
* @var string
*/
protected $host = 'http://localhost';
protected $host = '{{basePath}}';
/**
* Timeout (second) of the HTTP request, by default set to 0, no timeout
@ -103,7 +103,7 @@ class Configuration
*
* @var string
*/
protected $userAgent = "PHP-Swagger";
protected $userAgent = "PHP-Swagger/{{artifactVersion}}";
/**
* Debug switch (default set to false)

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# coding: utf-8
"""
@ -16,10 +15,8 @@ Copyright 2015 SmartBear Software
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
from __future__ import absolute_import
import sys
@ -34,6 +31,10 @@ from ..api_client import ApiClient
{{#operations}}
class {{classname}}(object):
"""
NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, api_client=None):
config = Configuration()

View File

@ -1,10 +1,20 @@
#!/usr/bin/env python
# coding: utf-8
"""Swagger generic API client. This client handles the client-
server communication, and is invariant across implementations. Specifics of
the methods and models for each application are generated from the Swagger
templates."""
"""
Copyright 2015 SmartBear Software
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from __future__ import absolute_import
from . import models
@ -38,15 +48,27 @@ from .configuration import Configuration
class ApiClient(object):
"""
Generic API client for Swagger client library builds
Generic API client for Swagger client library builds.
:param host: The base path for the server to call
:param header_name: a header to pass when making calls to the API
:param header_value: a header value to pass when making calls to the API
Swagger generic API client. This client handles the client-
server communication, and is invariant across implementations. Specifics of
the methods and models for each application are generated from the Swagger
templates.
NOTE: This class is auto generated by the swagger code generator program.
https://github.com/swagger-api/swagger-codegen
Do not edit the class manually.
:param host: The base path for the server to call.
:param header_name: a header to pass when making calls to the API.
:param header_value: a header value to pass when making calls to the API.
"""
def __init__(self, host=Configuration().host,
header_name=None, header_value=None, cookie=None):
"""
Constructor of the class.
"""
self.default_headers = {}
if header_name is not None:
self.default_headers[header_name] = header_value
@ -57,10 +79,16 @@ class ApiClient(object):
@property
def user_agent(self):
"""
Gets user agent.
"""
return self.default_headers['User-Agent']
@user_agent.setter
def user_agent(self, value):
"""
Sets user agent.
"""
self.default_headers['User-Agent'] = value
def set_default_header(self, header_name, header_value):
@ -129,11 +157,12 @@ class ApiClient(object):
def to_path_value(self, obj):
"""
Convert a string or object to a path-friendly value
Takes value and turn it into a string suitable for inclusion in
the path, by url-encoding.
:param obj: object or string value
:param obj: object or string value.
:return string: quoted value
:return string: quoted value.
"""
if type(obj) == list:
return ','.join(obj)
@ -142,7 +171,7 @@ class ApiClient(object):
def sanitize_for_serialization(self, obj):
"""
Sanitize an object for Request.
Builds a JSON POST object.
If obj is None, return None.
If obj is str, int, float, bool, return directly.
@ -151,6 +180,9 @@ class ApiClient(object):
If obj is list, santize each element in the list.
If obj is dict, return the dict.
If obj is swagger model, return the properties dict.
:param obj: The data to serialize.
:return: The serialized form of data.
"""
if isinstance(obj, type(None)):
return None
@ -170,24 +202,22 @@ class ApiClient(object):
# and attributes which value is not None.
# Convert attribute name to json key in
# model definition for request.
obj_dict = {obj.attribute_map[key[1:]]: val
for key, val in iteritems(obj.__dict__)
if key != 'swagger_types'
and key != 'attribute_map'
and val is not None}
obj_dict = {obj.attribute_map[attr]: getattr(obj, attr)
for attr, _ in iteritems(obj.swagger_types)
if getattr(obj, attr) is not None}
return {key: self.sanitize_for_serialization(val)
for key, val in iteritems(obj_dict)}
def deserialize(self, response, response_type):
"""
Derialize response into an object.
Deserializes response into an object.
:param response: RESTResponse object to be deserialized
:param response: RESTResponse object to be deserialized.
:param response_type: class literal for
deserialzied object, or string of class name
deserialzied object, or string of class name.
:return: deserialized object
:return: deserialized object.
"""
# handle file downloading
# save response body into a tmp file and return the instance
@ -204,21 +234,23 @@ class ApiClient(object):
def __deserialize(self, data, klass):
"""
:param data: dict, list or str
:param klass: class literal, or string of class name
Deserializes dict, list, str into an object.
:return: object
:param data: dict, list or str.
:param klass: class literal, or string of class name.
:return: object.
"""
if data is None:
return None
if type(klass) == str:
if 'list[' in klass:
if klass.startswith('list['):
sub_kls = re.match('list\[(.*)\]', klass).group(1)
return [self.__deserialize(sub_data, sub_kls)
for sub_data in data]
if 'dict(' in klass:
if klass.startswith('dict('):
sub_kls = re.match('dict\(([^,]*), (.*)\)', klass).group(2)
return {k: self.__deserialize(v, sub_kls)
for k, v in iteritems(data)}
@ -248,8 +280,7 @@ class ApiClient(object):
body=None, post_params=None, files=None,
response_type=None, auth_settings=None, callback=None):
"""
Perform http request and return deserialized data
Makes the HTTP request and return the deserialized data.
:param resource_path: Path to method endpoint.
:param method: Method to call.
@ -293,7 +324,7 @@ class ApiClient(object):
def request(self, method, url, query_params=None, headers=None,
post_params=None, body=None):
"""
Perform http request using RESTClient.
Makes the HTTP request using RESTClient.
"""
if method == "GET":
return RESTClient.GET(url,
@ -305,16 +336,19 @@ class ApiClient(object):
headers=headers)
elif method == "POST":
return RESTClient.POST(url,
query_params=query_params,
headers=headers,
post_params=post_params,
body=body)
elif method == "PUT":
return RESTClient.PUT(url,
query_params=query_params,
headers=headers,
post_params=post_params,
body=body)
elif method == "PATCH":
return RESTClient.PATCH(url,
query_params=query_params,
headers=headers,
post_params=post_params,
body=body)
@ -329,6 +363,13 @@ class ApiClient(object):
)
def prepare_post_parameters(self, post_params=None, files=None):
"""
Builds form parameters.
:param post_params: Normal form parameters.
:param files: File parameters.
:return: Form parameters with files.
"""
params = {}
if post_params:
@ -350,7 +391,10 @@ class ApiClient(object):
def select_header_accept(self, accepts):
"""
Return `Accept` based on an array of accepts provided
Returns `Accept` based on an array of accepts provided.
:param accepts: List of headers.
:return: Accept (e.g. application/json).
"""
if not accepts:
return
@ -364,7 +408,10 @@ class ApiClient(object):
def select_header_content_type(self, content_types):
"""
Return `Content-Type` baseed on an array of content_types provided
Returns `Content-Type` based on an array of content_types provided.
:param content_types: List of content-types.
:return: Content-Type (e.g. application/json).
"""
if not content_types:
return 'application/json'
@ -378,7 +425,11 @@ class ApiClient(object):
def update_params_for_auth(self, headers, querys, auth_settings):
"""
Update header and query params based on authentication setting
Updates header and query params based on authentication setting.
:param headers: Header parameters dict to be updated.
:param querys: Query parameters dict to be updated.
:param auth_settings: Authentication setting identifiers list.
"""
config = Configuration()
@ -399,12 +450,12 @@ class ApiClient(object):
def __deserialize_file(self, response):
"""
Save response body into a file in (the defined) temporary folder,
Saves response body into a file in (the defined) temporary folder,
using the filename from the `Content-Disposition` header if provided,
otherwise a random filename.
:param response: RESTResponse
:return: file path
:param response: RESTResponse.
:return: file path.
"""
config = Configuration()
@ -426,12 +477,12 @@ class ApiClient(object):
def __deserialize_primitive(self, data, klass):
"""
Deserialize string to primitive type
Deserializes string to primitive type.
:param data: str
:param klass: class literal
:param data: str.
:param klass: class literal.
:return: int, float, str, bool
:return: int, float, str, bool.
"""
try:
value = klass(data)
@ -443,16 +494,18 @@ class ApiClient(object):
def __deserialize_object(self):
"""
Deserialize empty object
Deserializes empty object.
:return: object.
"""
return object()
def __deserialize_date(self, string):
"""
Deserialize string to date
Deserializes string to date.
:param string: str
:return: date
:param string: str.
:return: date.
"""
try:
from dateutil.parser import parse
@ -468,12 +521,12 @@ class ApiClient(object):
def __deserialize_datatime(self, string):
"""
Deserialize string to datetime.
Deserializes string to datetime.
The string should be in iso8601 datetime format.
:param string: str
:return: datetime
:param string: str.
:return: datetime.
"""
try:
from dateutil.parser import parse
@ -489,10 +542,11 @@ class ApiClient(object):
def __deserialize_model(self, data, klass):
"""
Deserialize list or dict to model
Deserializes list or dict to model.
:param data: dict, list
:param klass: class literal
:param data: dict, list.
:param klass: class literal.
:return: model object.
"""
instance = klass()

View File

@ -1,7 +1,31 @@
# coding: utf-8
"""
Copyright 2015 SmartBear Software
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from __future__ import absolute_import
import base64
import urllib3
import httplib
try:
import httplib
except ImportError:
# for python3
import http.client as httplib
import sys
import logging
@ -18,26 +42,45 @@ def singleton(cls, *args, **kw):
@singleton
class Configuration(object):
"""
NOTE: This class is auto generated by the swagger code generator program.
https://github.com/swagger-api/swagger-codegen
Do not edit the class manually.
"""
def __init__(self):
"""
Constructor
"""
# Default Base url
self.host = "{{basePath}}"
# Default api client
self.api_client = None
# Temp file folder
# Temp file folder for download
self.temp_folder_path = None
# Authentication Settings
# dict to store API key(s)
self.api_key = {}
# dict to store API prefix (e.g. Bearer)
self.api_key_prefix = {}
# Username for HTTP basic authentication
self.username = ""
# Password for HTTP basic authentication
self.password = ""
# Logging Settings
self.logging_format = '%(asctime)s %(levelname)s %(message)s'
# Debug file location
self.__logging_file = None
# Debug switch
self.__debug = False
self.init_logger()
def init_logger(self):
"""
Initializes logger settings.
"""
self.logger = logging.getLogger()
formatter = logging.Formatter(self.logging_format)
stream_handler = logging.StreamHandler()
@ -82,20 +125,33 @@ class Configuration(object):
# setting log level to default `logging.WARNING`
self.logger.setLevel(logging.WARNING)
def get_api_key_with_prefix(self, key):
""" Return api key prepend prefix for key """
if self.api_key.get(key) and self.api_key_prefix.get(key):
return self.api_key_prefix[key] + ' ' + self.api_key[key]
elif self.api_key.get(key):
return self.api_key[key]
def get_api_key_with_prefix(self, identifier):
"""
Gets API key (with prefix if set).
:param identifier: The identifier of apiKey.
:return: The token for api key authentication.
"""
if self.api_key.get(identifier) and self.api_key_prefix.get(identifier):
return self.api_key_prefix[identifier] + ' ' + self.api_key[identifier]
elif self.api_key.get(identifier):
return self.api_key[identifier]
def get_basic_auth_token(self):
""" Return basic auth header string """
"""
Gets basic auth header string.
:return: The token for basic HTTP authentication.
"""
return urllib3.util.make_headers(basic_auth=self.username + ':' + self.password)\
.get('authorization')
def auth_settings(self):
""" Return Auth Settings for api client """
"""
Gets Auth Settings dict for api client.
:return: The Auth Settings information dict.
"""
return {
{{#authMethods}}
{{#isApiKey}}
@ -120,6 +176,11 @@ class Configuration(object):
}
def to_debug_report(self):
"""
Gets the essential information for debugging.
:return: The report for debugging.
"""
return "Python SDK Debug Report:\n"\
"OS: {env}\n"\
"Python Version: {pyversion}\n"\

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# coding: utf-8
"""
@ -16,6 +15,7 @@ Copyright 2015 SmartBear Software
See the License for the specific language governing permissions and
limitations under the License.
"""
{{#models}}
{{#model}}
from pprint import pformat
@ -47,16 +47,30 @@ class {{classname}}(object):
}
{{#vars}}
self._{{name}} = None{{#description}} # {{description}}{{/description}}
self._{{name}} = None
{{/vars}}
{{#vars}}
@property
def {{name}}(self):
"""
Gets the {{name}} of this {{classname}}.
{{#description}} {{{description}}}{{/description}}
:return: The {{name}} of this {{classname}}.
:rtype: {{datatype}}
"""
return self._{{name}}
@{{name}}.setter
def {{name}}(self, {{name}}):
"""
Sets the {{name}} of this {{classname}}.
{{#description}} {{{description}}}{{/description}}
:param {{name}}: The {{name}} of this {{classname}}.
:type: {{datatype}}
"""
{{#isEnum}}allowed_values = [{{#allowableValues}}{{#values}}"{{{this}}}"{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}]
if {{name}} not in allowed_values:
raise ValueError(
@ -72,18 +86,17 @@ class {{classname}}(object):
"""
result = {}
for name, prop in iteritems(self.__dict__):
if name == "attribute_map" or name == "swagger_types":
continue
if isinstance(prop, list):
result[name[1:]] = list(map(
for attr, _ in iteritems(self.swagger_types):
value = getattr(self, attr)
if isinstance(value, list):
result[attr] = list(map(
lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
prop
value
))
elif hasattr(prop, "to_dict"):
result[name[1:]] = prop.to_dict()
elif hasattr(value, "to_dict"):
result[attr] = value.to_dict()
else:
result[name[1:]] = prop
result[attr] = value
return result

View File

@ -1,6 +1,20 @@
# coding: utf-8
"""
Copyright 2015 SmartBear Software
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Credit: this file (rest.py) is modified based on rest.py in Dropbox Python SDK:
https://www.dropbox.com/developers/core/sdks/python
"""
@ -162,21 +176,24 @@ class RESTClientObject(object):
headers=headers,
query_params=query_params)
def POST(self, url, headers=None, post_params=None, body=None):
def POST(self, url, headers=None, query_params=None, post_params=None, body=None):
return self.request("POST", url,
headers=headers,
query_params=query_params,
post_params=post_params,
body=body)
def PUT(self, url, headers=None, post_params=None, body=None):
def PUT(self, url, headers=None, query_params=None, post_params=None, body=None):
return self.request("PUT", url,
headers=headers,
query_params=query_params,
post_params=post_params,
body=body)
def PATCH(self, url, headers=None, post_params=None, body=None):
def PATCH(self, url, headers=None, query_params=None, post_params=None, body=None):
return self.request("PATCH", url,
headers=headers,
query_params=query_params,
post_params=post_params,
body=body)
@ -202,10 +219,10 @@ class ApiException(Exception):
error_message = "({0})\n"\
"Reason: {1}\n".format(self.status, self.reason)
if self.headers:
error_message += "HTTP response headers: {0}".format(self.headers)
error_message += "HTTP response headers: {0}\n".format(self.headers)
if self.body:
error_message += "HTTP response body: {0}".format(self.body)
error_message += "HTTP response body: {0}\n".format(self.body)
return error_message

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# coding: utf-8
import sys
from setuptools import setup, find_packages
@ -34,11 +35,3 @@ setup(
)
{{/hasMore}}{{/apis}}{{/apiInfo}}

View File

@ -22,7 +22,7 @@ public interface {{classname}} {
{{#isMultipart}}@Multipart{{/isMultipart}}{{^isMultipart}}@FormUrlEncoded{{/isMultipart}}{{/-first}}{{/formParams}}
@{{httpMethod}}("{{path}}")
{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}} {{nickname}}({{^allParams}});{{/allParams}}
{{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{^hasMore}}
{{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}}, {{/hasMore}}{{^hasMore}}
);{{/hasMore}}{{/allParams}}
{{/operation}}
}

View File

@ -1 +1 @@
{{#isFormParam}}{{#notFile}}{{#isMultipart}}@Part{{/isMultipart}}{{^isMultipart}}@Field{{/isMultipart}}("{{paramName}}") {{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}{{#isMultipart}}@Part{{/isMultipart}}{{^isMultipart}}@Field{{/isMultipart}}("{{paramName}}") TypedFile {{paramName}}{{/isFile}}{{/isFormParam}}
{{#isFormParam}}{{#notFile}}{{#isMultipart}}@Part{{/isMultipart}}{{^isMultipart}}@Field{{/isMultipart}}("{{baseName}}") {{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}{{#isMultipart}}@Part{{/isMultipart}}{{^isMultipart}}@Field{{/isMultipart}}("{{baseName}}") TypedFile {{paramName}}{{/isFile}}{{/isFormParam}}

View File

@ -2,8 +2,20 @@ package {{invokerPackage}};
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import retrofit.RestAdapter;
import retrofit.converter.ConversionException;
import retrofit.converter.Converter;
import retrofit.converter.GsonConverter;
import retrofit.mime.TypedByteArray;
import retrofit.mime.TypedInput;
import retrofit.mime.TypedOutput;
public class ServiceGenerator {
// No need to instantiate this class.
@ -15,9 +27,63 @@ public class ServiceGenerator {
.create();
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint("{{basePath}}")
.setConverter(new GsonConverter(gson))
.setConverter(new GsonConverterWrapper(gson))
.build();
return adapter.create(serviceClass);
}
}
/**
* This wrapper is to take care of this case:
* when the deserialization fails due to JsonParseException and the
* expected type is String, then just return the body string.
*/
class GsonConverterWrapper implements Converter {
private GsonConverter converter;
public GsonConverterWrapper(Gson gson) {
converter = new GsonConverter(gson);
}
@Override public Object fromBody(TypedInput body, Type type) throws ConversionException {
byte[] bodyBytes = readInBytes(body);
TypedByteArray newBody = new TypedByteArray(body.mimeType(), bodyBytes);
try {
return converter.fromBody(newBody, type);
} catch (ConversionException e) {
if (e.getCause() instanceof JsonParseException && type.equals(String.class)) {
return new String(bodyBytes);
} else {
throw e;
}
}
}
@Override public TypedOutput toBody(Object object) {
return converter.toBody(object);
}
private byte[] readInBytes(TypedInput body) throws ConversionException {
InputStream in = null;
try {
in = body.in();
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] buffer = new byte[0xFFFF];
for (int len; (len = in.read(buffer)) != -1;)
os.write(buffer, 0, len);
os.flush();
return os.toByteArray();
} catch (IOException e) {
throw new ConversionException(e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ignored) {
}
}
}
}
}

View File

@ -59,7 +59,7 @@ class ApiInvoker(val mapper: ObjectMapper = ScalaJsonUtil.getJsonMapper,
if (cls == classOf[String]) {
json match {
case s: String => {
if (s.startsWith("\"") && s.endsWith("\"") && s.length > 1) s.substring(1, s.length - 2)
if (s.startsWith("\"") && s.endsWith("\"") && s.length > 1) s.substring(1, s.length - 1)
else s
}
case _ => null

View File

@ -31,4 +31,55 @@ class JavaModelEnumTest extends FlatSpec with Matchers {
enumVar.baseType should be("String")
enumVar.isEnum should equal(true)
}
it should "not override identical parent enums" in {
val identicalEnumProperty = new StringProperty()
identicalEnumProperty.setEnum(List("VALUE1", "VALUE2", "VALUE3").asJava)
val subEnumProperty = new StringProperty()
subEnumProperty.setEnum(List("SUB1", "SUB2", "SUB3").asJava)
// Add one enum ptoperty to the parent
val parentProperties = new java.util.HashMap[String, Property]()
parentProperties.put("sharedThing", identicalEnumProperty)
// Add TWO enums to the subType model; one of which is identical to the one in parent class
val subProperties = new java.util.HashMap[String, Property]()
subProperties.put("sharedThing", identicalEnumProperty)
subProperties.put("unsharedThing", identicalEnumProperty)
val parentModel = new ModelImpl();
parentModel.setProperties(parentProperties);
parentModel.name("parentModel");
val subModel = new ModelImpl();
subModel.setProperties(subProperties);
subModel.name("subModel");
val model = new ComposedModel()
.parent(new RefModel(parentModel.getName()))
.child(subModel)
.interfaces(new java.util.ArrayList[RefModel]())
val codegen = new JavaClientCodegen()
val allModels = new java.util.HashMap[String, Model]()
allModels.put(codegen.toModelName(parentModel.getName()), parentModel)
allModels.put(codegen.toModelName(subModel.getName()), subModel)
val cm = codegen.fromModel("sample", model, allModels)
cm.name should be("sample")
cm.classname should be("Sample")
cm.parent should be("ParentModel")
cm.imports.asScala should be(Set("ParentModel"))
// Assert that only the unshared/uninherited enum remains
cm.vars.size should be (1)
val enumVar = cm.vars.get(0)
enumVar.baseName should be("unsharedThing")
enumVar.datatype should be("String")
enumVar.datatypeWithEnum should be("UnsharedThingEnum")
enumVar.isEnum should equal(true)
}
}

View File

@ -2,6 +2,7 @@ package Java
import io.swagger.codegen.languages.JavaClientCodegen
import io.swagger.models._
import io.swagger.models.parameters._
import io.swagger.models.properties._
import io.swagger.util.Json
import org.junit.runner.RunWith
@ -382,7 +383,6 @@ class JavaModelTest2 extends FlatSpec with Matchers {
cm.vars.size should be(1)
val vars = cm.vars
Json.prettyPrint(vars.get(0))
vars.get(0).baseName should be("_")
vars.get(0).getter should be("getU")
vars.get(0).setter should be("setU")
@ -393,4 +393,17 @@ class JavaModelTest2 extends FlatSpec with Matchers {
vars.get(0).hasMore should equal(null)
vars.get(0).isNotContainer should equal(true)
}
it should "convert a parameter" in {
val parameter = new QueryParameter()
.property(
new IntegerProperty())
.name("limit")
.required(true)
val codegen = new JavaClientCodegen()
val cp = codegen.fromParameter(parameter, null)
cp.allowableValues should be (null)
}
}

View File

@ -90,7 +90,7 @@ class ObjcModelTest extends FlatSpec with Matchers {
vars.get(0).isNotContainer should equal(true)
vars.get(1).baseName should be("urls")
vars.get(1).datatype should be("NSArray*")
vars.get(1).datatype should be("NSArray* /* NSString */")
vars.get(1).name should be("urls")
// vars.get(1).defaultValue should be ("null")
vars.get(1).baseType should be("NSArray")

14
pom.xml
View File

@ -161,14 +161,6 @@
<artifactId>scala-maven-plugin</artifactId>
<version>${scala-maven-plugin-version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<configuration>
<releaseProfiles>release</releaseProfiles>
<goals>sign</goals>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
@ -464,10 +456,10 @@
</repository>
</repositories>
<properties>
<swagger-parser-version>1.0.9-SNAPSHOT</swagger-parser-version>
<swagger-parser-version>1.0.10</swagger-parser-version>
<scala-version>2.11.1</scala-version>
<felix-version>2.3.4</felix-version>
<swagger-core-version>1.5.0</swagger-core-version>
<swagger-core-version>1.5.4-SNAPSHOT</swagger-core-version>
<scala-test-version>2.1.4</scala-test-version>
<commons-io-version>2.3</commons-io-version>
<commons-cli-version>1.2</commons-cli-version>
@ -475,7 +467,7 @@
<maven-plugin-version>1.0.0</maven-plugin-version>
<commons-lang-version>2.4</commons-lang-version>
<slf4j-version>1.6.3</slf4j-version>
<scala-maven-plugin-version>3.1.5</scala-maven-plugin-version>
<scala-maven-plugin-version>3.2.1</scala-maven-plugin-version>
<jmustache-version>1.9</jmustache-version>
</properties>
</project>

34
run-in-docker.sh Executable file
View File

@ -0,0 +1,34 @@
#!/bin/bash
set -e
cd "$(dirname $BASH_SOURCE)"
maven_cache_repo="$HOME/.m2/repository"
myname="$(basename $BASH_SOURCE)"
if [ "$1" = "mvn" ]; then
cmd="$1"
shift
args="$@"
else
jar="modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
# Check if project is built
if [ ! -f "$jar" ]; then
echo "ERROR File not found: $jar"
echo "ERROR Did you forget to './$myname mvn package'?"
exit 1
fi
cmd="java -jar /gen/$jar"
args="$@"
fi
mkdir -p "$maven_cache_repo"
set -x
docker run -it \
-w /gen \
-v "${PWD}:/gen" \
-v "${maven_cache_repo}:/root/.m2/repository" \
maven:3-jdk-7 $cmd $args

View File

@ -216,7 +216,7 @@ public class ApiInvoker {
}
else if(String.class.equals(cls)) {
if(json != null && json.startsWith("\"") && json.endsWith("\"") && json.length() > 1)
return json.substring(1, json.length() - 2);
return json.substring(1, json.length() - 1);
else
return json;
}

View File

@ -2,6 +2,9 @@
This generator creates C# code targeting the .Net 2.0 framework. The resulting DLLs can be used in places where .Net 2.0 is the maximum supported version, such as in the Unity3d.
## Compilation dependencies
## Dependencies
- Mono compiler
- Note: NuGet is downloaded by the mono compilation script and packages are installed with it. No dependency DLLs are bundled with this generator.

View File

@ -235,7 +235,7 @@ namespace IO.Swagger.Client
{
return JsonConvert.DeserializeObject(content, type);
}
catch (IOException e)
catch (Exception e)
{
throw new ApiException(500, e.Message);
}

View File

@ -1,35 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
object FlashPetstoreCodegen extends BasicFlashCodegen {
def main(args: Array[String]) = generateClient(args)
override def packageName = "io.swagger.client"
// where to write generated code
override def destinationDir = destinationRoot + "/src/main/flex"
override def destinationRoot = "samples/client/petstore/flash"
// package for models
override def modelPackage = Some("com.wordnik.client.model")
// package for api classes
override def apiPackage = Some("com.wordnik.client.api")
// supporting classes
override def supportingFiles = baseSupportingFiles ++ List()
}

View File

@ -1,146 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<application xmlns="http://ns.adobe.com/air/application/2.0">
<!-- Adobe AIR Application Descriptor File Template.
Specifies parameters for identifying, installing, and launching AIR applications.
xmlns - The Adobe AIR namespace: http://ns.adobe.com/air/application/2.0
The last segment of the namespace specifies the version
of the AIR runtime required for this application to run.
minimumPatchLevel - The minimum patch level of the AIR runtime required to run
the application. Optional.
-->
<!-- A universally unique application identifier. Must be unique across all AIR applications.
Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. -->
<id>AirExecutorApp</id>
<!-- Used as the filename for the application. Required. -->
<filename>AirExecutorApp</filename>
<!-- The name that is displayed in the AIR application installer.
May have multiple values for each language. See samples or xsd schema file. Optional. -->
<name>AirExecutorApp</name>
<!-- An application version designator (such as "v1", "2.5", or "Alpha 1"). Required. -->
<version>v1</version>
<!-- Description, displayed in the AIR application installer.
May have multiple values for each language. See samples or xsd schema file. Optional. -->
<!-- <description></description> -->
<!-- Copyright information. Optional -->
<!-- <copyright></copyright> -->
<!-- Publisher ID. Used if you're updating an application created prior to 1.5.3 -->
<!-- <publisherID></publisherID> -->
<!-- Settings for the application's initial window. Required. -->
<initialWindow>
<!-- The main SWF or HTML file of the application. Required. -->
<!-- Note: In Flash Builder, the SWF reference is set automatically. -->
<content>AirExecutorApp.swf</content>
<!-- The title of the main window. Optional. -->
<!-- <title></title> -->
<!-- The type of system chrome to use (either "standard" or "none"). Optional. Default standard. -->
<!-- <systemChrome></systemChrome> -->
<!-- Whether the window is transparent. Only applicable when systemChrome is none. Optional. Default false. -->
<!-- <transparent></transparent> -->
<!-- Whether the window is initially visible. Optional. Default false. -->
<!-- <visible></visible> -->
<!-- Whether the user can minimize the window. Optional. Default true. -->
<!-- <minimizable></minimizable> -->
<!-- Whether the user can maximize the window. Optional. Default true. -->
<!-- <maximizable></maximizable> -->
<!-- Whether the user can resize the window. Optional. Default true. -->
<!-- <resizable></resizable> -->
<!-- The window's initial width in pixels. Optional. -->
<!-- <width></width> -->
<!-- The window's initial height in pixels. Optional. -->
<!-- <height></height> -->
<!-- The window's initial x position. Optional. -->
<!-- <x></x> -->
<!-- The window's initial y position. Optional. -->
<!-- <y></y> -->
<!-- The window's minimum size, specified as a width/height pair in pixels, such as "400 200". Optional. -->
<!-- <minSize></minSize> -->
<!-- The window's initial maximum size, specified as a width/height pair in pixels, such as "1600 1200". Optional. -->
<!-- <maxSize></maxSize> -->
</initialWindow>
<!-- We recommend omitting the supportedProfiles element, -->
<!-- which in turn permits your application to be deployed to all -->
<!-- devices supported by AIR. If you wish to restrict deployment -->
<!-- (i.e., to only mobile devices) then add this element and list -->
<!-- only the profiles which your application does support. -->
<!-- <supportedProfiles>desktop extendedDesktop mobileDevice extendedMobileDevice</supportedProfiles> -->
<!-- The subpath of the standard default installation location to use. Optional. -->
<!-- <installFolder></installFolder> -->
<!-- The subpath of the Programs menu to use. (Ignored on operating systems without a Programs menu.) Optional. -->
<!-- <programMenuFolder></programMenuFolder> -->
<!-- The icon the system uses for the application. For at least one resolution,
specify the path to a PNG file included in the AIR package. Optional. -->
<!-- <icon>
<image16x16></image16x16>
<image32x32></image32x32>
<image48x48></image48x48>
<image128x128></image128x128>
</icon> -->
<!-- Whether the application handles the update when a user double-clicks an update version
of the AIR file (true), or the default AIR application installer handles the update (false).
Optional. Default false. -->
<!-- <customUpdateUI></customUpdateUI> -->
<!-- Whether the application can be launched when the user clicks a link in a web browser.
Optional. Default false. -->
<!-- <allowBrowserInvocation></allowBrowserInvocation> -->
<!-- Listing of file types for which the application can register. Optional. -->
<!-- <fileTypes> -->
<!-- Defines one file type. Optional. -->
<!-- <fileType> -->
<!-- The name that the system displays for the registered file type. Required. -->
<!-- <name></name> -->
<!-- The extension to register. Required. -->
<!-- <extension></extension> -->
<!-- The description of the file type. Optional. -->
<!-- <description></description> -->
<!-- The MIME content type. -->
<!-- <contentType></contentType> -->
<!-- The icon to display for the file type. Optional. -->
<!-- <icon>
<image16x16></image16x16>
<image32x32></image32x32>
<image48x48></image48x48>
<image128x128></image128x128>
</icon> -->
<!-- </fileType> -->
<!-- </fileTypes> -->
</application>

View File

@ -0,0 +1,146 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<application xmlns="http://ns.adobe.com/air/application/2.0">
<!-- Adobe AIR Application Descriptor File Template.
Specifies parameters for identifying, installing, and launching AIR applications.
xmlns - The Adobe AIR namespace: http://ns.adobe.com/air/application/2.0
The last segment of the namespace specifies the version
of the AIR runtime required for this application to run.
minimumPatchLevel - The minimum patch level of the AIR runtime required to run
the application. Optional.
-->
<!-- A universally unique application identifier. Must be unique across all AIR applications.
Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. -->
<id>AirExecutorApp</id>
<!-- Used as the filename for the application. Required. -->
<filename>AirExecutorApp</filename>
<!-- The name that is displayed in the AIR application installer.
May have multiple values for each language. See samples or xsd schema file. Optional. -->
<name>AirExecutorApp</name>
<!-- An application version designator (such as "v1", "2.5", or "Alpha 1"). Required. -->
<version>v1</version>
<!-- Description, displayed in the AIR application installer.
May have multiple values for each language. See samples or xsd schema file. Optional. -->
<!-- <description></description> -->
<!-- Copyright information. Optional -->
<!-- <copyright></copyright> -->
<!-- Publisher ID. Used if you're updating an application created prior to 1.5.3 -->
<!-- <publisherID></publisherID> -->
<!-- Settings for the application's initial window. Required. -->
<initialWindow>
<!-- The main SWF or HTML file of the application. Required. -->
<!-- Note: In Flash Builder, the SWF reference is set automatically. -->
<content>AirExecutorApp.swf</content>
<!-- The title of the main window. Optional. -->
<!-- <title></title> -->
<!-- The type of system chrome to use (either "standard" or "none"). Optional. Default standard. -->
<!-- <systemChrome></systemChrome> -->
<!-- Whether the window is transparent. Only applicable when systemChrome is none. Optional. Default false. -->
<!-- <transparent></transparent> -->
<!-- Whether the window is initially visible. Optional. Default false. -->
<!-- <visible></visible> -->
<!-- Whether the user can minimize the window. Optional. Default true. -->
<!-- <minimizable></minimizable> -->
<!-- Whether the user can maximize the window. Optional. Default true. -->
<!-- <maximizable></maximizable> -->
<!-- Whether the user can resize the window. Optional. Default true. -->
<!-- <resizable></resizable> -->
<!-- The window's initial width in pixels. Optional. -->
<!-- <width></width> -->
<!-- The window's initial height in pixels. Optional. -->
<!-- <height></height> -->
<!-- The window's initial x position. Optional. -->
<!-- <x></x> -->
<!-- The window's initial y position. Optional. -->
<!-- <y></y> -->
<!-- The window's minimum size, specified as a width/height pair in pixels, such as "400 200". Optional. -->
<!-- <minSize></minSize> -->
<!-- The window's initial maximum size, specified as a width/height pair in pixels, such as "1600 1200". Optional. -->
<!-- <maxSize></maxSize> -->
</initialWindow>
<!-- We recommend omitting the supportedProfiles element, -->
<!-- which in turn permits your application to be deployed to all -->
<!-- devices supported by AIR. If you wish to restrict deployment -->
<!-- (i.e., to only mobile devices) then add this element and list -->
<!-- only the profiles which your application does support. -->
<!-- <supportedProfiles>desktop extendedDesktop mobileDevice extendedMobileDevice</supportedProfiles> -->
<!-- The subpath of the standard default installation location to use. Optional. -->
<!-- <installFolder></installFolder> -->
<!-- The subpath of the Programs menu to use. (Ignored on operating systems without a Programs menu.) Optional. -->
<!-- <programMenuFolder></programMenuFolder> -->
<!-- The icon the system uses for the application. For at least one resolution,
specify the path to a PNG file included in the AIR package. Optional. -->
<!-- <icon>
<image16x16></image16x16>
<image32x32></image32x32>
<image48x48></image48x48>
<image128x128></image128x128>
</icon> -->
<!-- Whether the application handles the update when a user double-clicks an update version
of the AIR file (true), or the default AIR application installer handles the update (false).
Optional. Default false. -->
<!-- <customUpdateUI></customUpdateUI> -->
<!-- Whether the application can be launched when the user clicks a link in a web browser.
Optional. Default false. -->
<!-- <allowBrowserInvocation></allowBrowserInvocation> -->
<!-- Listing of file types for which the application can register. Optional. -->
<!-- <fileTypes> -->
<!-- Defines one file type. Optional. -->
<!-- <fileType> -->
<!-- The name that the system displays for the registered file type. Required. -->
<!-- <name></name> -->
<!-- The extension to register. Required. -->
<!-- <extension></extension> -->
<!-- The description of the file type. Optional. -->
<!-- <description></description> -->
<!-- The MIME content type. -->
<!-- <contentType></contentType> -->
<!-- The icon to display for the file type. Optional. -->
<!-- <icon>
<image16x16></image16x16>
<image32x32></image32x32>
<image48x48></image48x48>
<image128x128></image128x128>
</icon> -->
<!-- </fileType> -->
<!-- </fileTypes> -->
</application>

View File

@ -62,11 +62,11 @@
<arg line="-doc-sources ${sourcepath}"/>
<arg line="-source-path ${sourcepath}"/>
<arg line="-footer 'Copyright Wordnik'"/>
<arg line="-package com.wordnik.swagger.api 'Contains the apis which are used by clients to make calls to the services deployed'"/>
<arg line="-package com.wordnik.swagger.codegen.model 'Contains common classes which encapsulate data elements required'"/>
<arg line="-package com.wordnik.swagger.common 'Contains classes which are used by the api classes to invoke the deployed api like SwaggerApi - a base class, ApiUserCredentials, etc.'"/>
<arg line="-package com.wordnik.swagger.event 'Results of calls made to Wordnik are returned via dispatched events. This package contains such event classes. Right now thats just ApiClientEvent and Response.'"/>
<arg line="-package com.wordnik.swagger.exception 'Contains classes that encapsulate the errors generated'"/>
<arg line="-package io.swagger.api 'Contains the apis which are used by clients to make calls to the services deployed'"/>
<arg line="-package io.swagger.codegen.model 'Contains common classes which encapsulate data elements required'"/>
<arg line="-package io.swagger.common 'Contains classes which are used by the api classes to invoke the deployed api like SwaggerApi - a base class, ApiUserCredentials, etc.'"/>
<arg line="-package io.swagger.event 'Results of calls made to Wordnik are returned via dispatched events. This package contains such event classes. Right now thats just ApiClientEvent and Response.'"/>
<arg line="-package io.swagger.exception 'Contains classes that encapsulate the errors generated'"/>
<arg value="-window-title"/>
<arg value="${title}"/>

View File

@ -1,272 +0,0 @@
package com.wordnik.client.api {
import com.wordnik.swagger.common.ApiInvoker;
import com.wordnik.swagger.exception.ApiErrorCodes;
import com.wordnik.swagger.exception.ApiError;
import com.wordnik.swagger.common.ApiUserCredentials;
import com.wordnik.swagger.event.Response;
import com.wordnik.swagger.common.SwaggerApi;
import com.wordnik.client.model.Pet;
import com.wordnik.client.model.File;
import mx.rpc.AsyncToken;
import mx.utils.UIDUtil;
import flash.utils.Dictionary;
import flash.events.EventDispatcher;
public class PetApi extends SwaggerApi {
public static const event_getPetById:String = "getPetById";
public static const event_deletePet:String = "deletePet";
public static const event_partialUpdate:String = "partialUpdate";
public static const event_updatePetWithForm:String = "updatePetWithForm";
public static const event_uploadFile:String = "uploadFile";
public static const event_addPet:String = "addPet";
public static const event_updatePet:String = "updatePet";
public static const event_findPetsByStatus:String = "findPetsByStatus";
public static const event_findPetsByTags:String = "findPetsByTags";
/**
* Constructor for the PetApi api client
* @param apiCredentials Wrapper object for tokens and hostName required towards authentication
* @param eventDispatcher Optional event dispatcher that when provided is used by the SDK to dispatch any Response
*/
public function PetApi(apiCredentials:ApiUserCredentials, eventDispatcher:EventDispatcher = null) {
super(apiCredentials, eventDispatcher);
}
/*
* Returns Pet */
public function getPetById(petId:Number):String {
// create path and map variables
var path:String = "/pet/{petId}".replace(/{format}/g, "xml").replace("{" + "petId" + "}", getApiInvoker().escapeString(petId));
// query params
var queryParams:Dictionary = new Dictionary();
var headerParams:Dictionary = new Dictionary();
// verify required params are set
if (petId == null) {
throw new ApiError(400, "missing required params");
}
var token:AsyncToken = getApiInvoker().invokeAPI(path, "GET", queryParams, null, headerParams);
var requestId:String = getUniqueId();
token.requestId = requestId;
token.completionEventType = "getPetById";
token.returnType = Pet;
return requestId;
}
/*
* Returns void */
public function deletePet(petId:String):String {
// create path and map variables
var path:String = "/pet/{petId}".replace(/{format}/g, "xml").replace("{" + "petId" + "}", getApiInvoker().escapeString(petId));
// query params
var queryParams:Dictionary = new Dictionary();
var headerParams:Dictionary = new Dictionary();
// verify required params are set
if (petId == null) {
throw new ApiError(400, "missing required params");
}
var token:AsyncToken = getApiInvoker().invokeAPI(path, "DELETE", queryParams, null, headerParams);
var requestId:String = getUniqueId();
token.requestId = requestId;
token.completionEventType = "deletePet";
token.returnType = null;
return requestId;
}
/*
* Returns Array[Pet] */
public function partialUpdate(petId:String, body:Pet):String {
// create path and map variables
var path:String = "/pet/{petId}".replace(/{format}/g, "xml").replace("{" + "petId" + "}", getApiInvoker().escapeString(petId));
// query params
var queryParams:Dictionary = new Dictionary();
var headerParams:Dictionary = new Dictionary();
// verify required params are set
if (petId == null || body == null) {
throw new ApiError(400, "missing required params");
}
var token:AsyncToken = getApiInvoker().invokeAPI(path, "PATCH", queryParams, body, headerParams);
var requestId:String = getUniqueId();
token.requestId = requestId;
token.completionEventType = "partialUpdate";
token.returnType = Array[Pet];
return requestId;
}
/*
* Returns void */
public function updatePetWithForm(petId:String, name:String, status:String):String {
// create path and map variables
var path:String = "/pet/{petId}".replace(/{format}/g, "xml").replace("{" + "petId" + "}", getApiInvoker().escapeString(petId));
// query params
var queryParams:Dictionary = new Dictionary();
var headerParams:Dictionary = new Dictionary();
// verify required params are set
if (petId == null) {
throw new ApiError(400, "missing required params");
}
var token:AsyncToken = getApiInvoker().invokeAPI(path, "POST", queryParams, null, headerParams);
var requestId:String = getUniqueId();
token.requestId = requestId;
token.completionEventType = "updatePetWithForm";
token.returnType = null;
return requestId;
}
/*
* Returns void */
public function uploadFile(additionalMetadata:String, body:File):String {
// create path and map variables
var path:String = "/pet/uploadImage".replace(/{format}/g, "xml");
// query params
var queryParams:Dictionary = new Dictionary();
var headerParams:Dictionary = new Dictionary();
var token:AsyncToken = getApiInvoker().invokeAPI(path, "POST", queryParams, body, headerParams);
var requestId:String = getUniqueId();
token.requestId = requestId;
token.completionEventType = "uploadFile";
token.returnType = null;
return requestId;
}
/*
* Returns void */
public function addPet(body:Pet):String {
// create path and map variables
var path:String = "/pet".replace(/{format}/g, "xml");
// query params
var queryParams:Dictionary = new Dictionary();
var headerParams:Dictionary = new Dictionary();
// verify required params are set
if (body == null) {
throw new ApiError(400, "missing required params");
}
var token:AsyncToken = getApiInvoker().invokeAPI(path, "POST", queryParams, body, headerParams);
var requestId:String = getUniqueId();
token.requestId = requestId;
token.completionEventType = "addPet";
token.returnType = null;
return requestId;
}
/*
* Returns void */
public function updatePet(body:Pet):String {
// create path and map variables
var path:String = "/pet".replace(/{format}/g, "xml");
// query params
var queryParams:Dictionary = new Dictionary();
var headerParams:Dictionary = new Dictionary();
// verify required params are set
if (body == null) {
throw new ApiError(400, "missing required params");
}
var token:AsyncToken = getApiInvoker().invokeAPI(path, "PUT", queryParams, body, headerParams);
var requestId:String = getUniqueId();
token.requestId = requestId;
token.completionEventType = "updatePet";
token.returnType = null;
return requestId;
}
/*
* Returns Array[Pet] */
public function findPetsByStatus(status:String = "available"):String {
// create path and map variables
var path:String = "/pet/findByStatus".replace(/{format}/g, "xml");
// query params
var queryParams:Dictionary = new Dictionary();
var headerParams:Dictionary = new Dictionary();
// verify required params are set
if (status == null) {
throw new ApiError(400, "missing required params");
}
if ("null" != String(status))
queryParams["status"] = toPathValue(status);
var token:AsyncToken = getApiInvoker().invokeAPI(path, "GET", queryParams, null, headerParams);
var requestId:String = getUniqueId();
token.requestId = requestId;
token.completionEventType = "findPetsByStatus";
token.returnType = Array[Pet];
return requestId;
}
/*
* Returns Array[Pet] */
public function findPetsByTags(tags:String):String {
// create path and map variables
var path:String = "/pet/findByTags".replace(/{format}/g, "xml");
// query params
var queryParams:Dictionary = new Dictionary();
var headerParams:Dictionary = new Dictionary();
// verify required params are set
if (tags == null) {
throw new ApiError(400, "missing required params");
}
if ("null" != String(tags))
queryParams["tags"] = toPathValue(tags);
var token:AsyncToken = getApiInvoker().invokeAPI(path, "GET", queryParams, null, headerParams);
var requestId:String = getUniqueId();
token.requestId = requestId;
token.completionEventType = "findPetsByTags";
token.returnType = Array[Pet];
return requestId;
}
}
}

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