Merge branch 'develop_2.0' into ruby-api-client

This commit is contained in:
xhh 2015-08-20 11:10:25 +08:00
commit e02a9f1797
262 changed files with 13256 additions and 6099 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. 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 ## 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: 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 AndroidClientCodegen.java
AsyncScalaClientCodegen.java AsyncScalaClientCodegen.java
CSharpClientCodegen.java CSharpClientCodegen.java
FlashClientCodegen.java
JavaClientCodegen.java JavaClientCodegen.java
JaxRSServerCodegen.java JaxRSServerCodegen.java
NodeJSServerCodegen.java NodeJSServerCodegen.java

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

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

@ -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/JavaInflector -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l inflector -o samples/server/petstore/java-inflector"
java $JAVA_OPTS -jar $executable $ags

View File

@ -16,12 +16,14 @@ package io.swagger.codegen.plugin;
* limitations under the License. * limitations under the License.
*/ */
import io.swagger.codegen.CliOption;
import io.swagger.codegen.ClientOptInput; import io.swagger.codegen.ClientOptInput;
import io.swagger.codegen.ClientOpts; import io.swagger.codegen.ClientOpts;
import io.swagger.codegen.CodegenConfig; import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.DefaultGenerator; import io.swagger.codegen.DefaultGenerator;
import io.swagger.models.Swagger; import io.swagger.models.Swagger;
import io.swagger.parser.SwaggerParser; import io.swagger.parser.SwaggerParser;
import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.LifecyclePhase;
@ -29,6 +31,9 @@ import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
import config.Config;
import config.ConfigParser;
import java.io.File; import java.io.File;
import java.util.ServiceLoader; import java.util.ServiceLoader;
@ -66,6 +71,12 @@ public class CodeGenMojo extends AbstractMojo {
@Parameter(name = "language", required = true) @Parameter(name = "language", required = true)
private String language; private String language;
/**
* Path to json configuration file.
*/
@Parameter(name = "configurationFile", required = false)
private String configurationFile;
/** /**
* Add the output directory to the project as a source root, so that the * Add the output directory to the project as a source root, so that the
@ -91,6 +102,19 @@ public class CodeGenMojo extends AbstractMojo {
config.additionalProperties().put(TEMPLATE_DIR_PARAM, templateDirectory.getAbsolutePath()); config.additionalProperties().put(TEMPLATE_DIR_PARAM, templateDirectory.getAbsolutePath());
} }
if (null != configurationFile) {
Config genConfig = ConfigParser.read(configurationFile);
if (null != genConfig) {
for (CliOption langCliOption : config.cliOptions()) {
if (genConfig.hasOption(langCliOption.getOpt())) {
config.additionalProperties().put(langCliOption.getOpt(), genConfig.getOption(langCliOption.getOpt()));
}
}
} else {
throw new RuntimeException("Unable to read configuration file");
}
}
ClientOptInput input = new ClientOptInput().opts(new ClientOpts()).swagger(swagger); ClientOptInput input = new ClientOptInput().opts(new ClientOpts()).swagger(swagger);
input.setConfig(config); input.setConfig(config);
new DefaultGenerator().opts(input).generate(); new DefaultGenerator().opts(input).generate();

View File

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

View File

@ -65,6 +65,8 @@ public interface CodegenConfig {
CodegenModel fromModel(String name, Model model); CodegenModel fromModel(String name, Model model);
CodegenModel fromModel(String name, Model model, Map<String, Model> allDefinitions);
CodegenOperation fromOperation(String resourcePath, String httpMethod, Operation operation, Map<String, Model> definitions); CodegenOperation fromOperation(String resourcePath, String httpMethod, Operation operation, Map<String, Model> definitions);
List<CodegenSecurity> fromSecurity(Map<String, SecuritySchemeDefinition> schemes); List<CodegenSecurity> fromSecurity(Map<String, SecuritySchemeDefinition> schemes);

View File

@ -63,7 +63,7 @@ import java.util.regex.Pattern;
public class DefaultCodegen { 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 String outputFolder = "";
protected Set<String> defaultIncludes = new HashSet<String>(); protected Set<String> defaultIncludes = new HashSet<String>();
@ -80,6 +80,7 @@ public class DefaultCodegen {
protected List<SupportingFile> supportingFiles = new ArrayList<SupportingFile>(); protected List<SupportingFile> supportingFiles = new ArrayList<SupportingFile>();
protected List<CliOption> cliOptions = new ArrayList<CliOption>(); protected List<CliOption> cliOptions = new ArrayList<CliOption>();
protected boolean skipOverwrite; protected boolean skipOverwrite;
protected boolean supportsInheritance = false;
public List<CliOption> cliOptions() { public List<CliOption> cliOptions() {
return cliOptions; return cliOptions;
@ -229,6 +230,11 @@ public class DefaultCodegen {
} }
public String toOperationId(String operationId) { 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");
}
return operationId; return operationId;
} }
@ -426,14 +432,6 @@ public class DefaultCodegen {
return dp.getDefault().toString(); return dp.getDefault().toString();
} }
return "null"; return "null";
} else if (p instanceof MapProperty) {
MapProperty ap = (MapProperty) p;
String inner = getSwaggerType(ap.getAdditionalProperties());
return "new HashMap<String, " + inner + ">() ";
} else if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
String inner = getSwaggerType(ap.getItems());
return "new ArrayList<" + inner + ">() ";
} else { } else {
return "null"; return "null";
} }
@ -510,6 +508,10 @@ public class DefaultCodegen {
} }
public CodegenModel fromModel(String name, Model model) { public CodegenModel fromModel(String name, Model model) {
return fromModel(name, model, null);
}
public CodegenModel fromModel(String name, Model model, Map<String, Model> allDefinitions) {
CodegenModel m = CodegenModelFactory.newInstance(CodegenModelType.MODEL); CodegenModel m = CodegenModelFactory.newInstance(CodegenModelType.MODEL);
if (reservedWords.contains(name)) { if (reservedWords.contains(name)) {
m.name = escapeReservedWord(name); m.name = escapeReservedWord(name);
@ -529,12 +531,59 @@ public class DefaultCodegen {
// TODO // TODO
} else if (model instanceof ComposedModel) { } else if (model instanceof ComposedModel) {
final ComposedModel composed = (ComposedModel) model; final ComposedModel composed = (ComposedModel) model;
Map<String, Property> properties = new HashMap<String, Property>();
List<String> required = new ArrayList<String>();
// parent model
final RefModel parent = (RefModel) composed.getParent(); final RefModel parent = (RefModel) composed.getParent();
final String parentModel = toModelName(parent.getSimpleRef()); if (parent != null) {
m.parent = parentModel; final String parentRef = toModelName(parent.getSimpleRef());
addImport(m, parentModel); m.parent = parentRef;
final ModelImpl child = (ModelImpl) composed.getChild(); addImport(m, parentRef);
addVars(m, child.getProperties(), child.getRequired()); if (!supportsInheritance && allDefinitions != null) {
final Model parentModel = allDefinitions.get(parentRef);
if (parentModel instanceof ModelImpl) {
final ModelImpl _parent = (ModelImpl) parentModel;
if (_parent.getProperties() != null) {
properties.putAll(_parent.getProperties());
}
if (_parent.getRequired() != null) {
required.addAll(_parent.getRequired());
}
}
}
}
// interfaces (intermediate models)
if (allDefinitions != null) {
for (RefModel _interface : composed.getInterfaces()) {
final String interfaceRef = toModelName(_interface.getSimpleRef());
final Model interfaceModel = allDefinitions.get(interfaceRef);
if (interfaceModel instanceof ModelImpl) {
final ModelImpl _interfaceModel = (ModelImpl) interfaceModel;
if (_interfaceModel.getProperties() != null) {
properties.putAll(_interfaceModel.getProperties());
}
if (_interfaceModel.getRequired() != null) {
required.addAll(_interfaceModel.getRequired());
}
}
}
}
// child model (properties owned by the model itself)
Model child = composed.getChild();
if (child != null && child instanceof RefModel && allDefinitions != null) {
final String childRef = ((RefModel) child).getSimpleRef();
child = allDefinitions.get(childRef);
}
if (child != null && child instanceof ModelImpl) {
final ModelImpl _child = (ModelImpl) child;
if (_child.getProperties() != null) {
properties.putAll(_child.getProperties());
}
if (_child.getRequired() != null) {
required.addAll(_child.getRequired());
}
}
addVars(m, properties, required);
} else { } else {
ModelImpl impl = (ModelImpl) model; ModelImpl impl = (ModelImpl) model;
if (impl.getAdditionalProperties() != null) { if (impl.getAdditionalProperties() != null) {
@ -557,7 +606,7 @@ public class DefaultCodegen {
public CodegenProperty fromProperty(String name, Property p) { public CodegenProperty fromProperty(String name, Property p) {
if (p == null) { if (p == null) {
LOGGER.error("unexpected missing property for name " + null); LOGGER.error("unexpected missing property for name " + name);
return null; return null;
} }
CodegenProperty property = CodegenModelFactory.newInstance(CodegenModelType.PROPERTY); CodegenProperty property = CodegenModelFactory.newInstance(CodegenModelType.PROPERTY);
@ -1173,7 +1222,9 @@ public class DefaultCodegen {
if (mappedType != null) { if (mappedType != null) {
addImport(m, mappedType); addImport(m, mappedType);
} }
} /** }
/**
* Underscore the given word. * Underscore the given word.
* *
* @param word The word * @param word The word
@ -1235,10 +1286,9 @@ public class DefaultCodegen {
} else { } else {
m.emptyVars = true; m.emptyVars = true;
} }
} public static String camelize(String word) {
return camelize(word, false);
} }
/** /**
* Remove characters not suitable for variable or method name from the input and camelize it * Remove characters not suitable for variable or method name from the input and camelize it
* *
@ -1258,7 +1308,13 @@ public class DefaultCodegen {
name = name.substring(0, 1).toLowerCase() + name.substring(1); name = name.substring(0, 1).toLowerCase() + name.substring(1);
} }
return name; return name;
} public static String camelize(String word, boolean lowercaseFirstLetter) { }
public static String camelize(String word) {
return camelize(word, false);
}
public static String camelize(String word, boolean lowercaseFirstLetter) {
// Replace all slashes with dots (package separator) // Replace all slashes with dots (package separator)
Pattern p = Pattern.compile("\\/(.?)"); Pattern p = Pattern.compile("\\/(.?)");
Matcher m = p.matcher(word); Matcher m = p.matcher(word);

View File

@ -2,6 +2,8 @@ package io.swagger.codegen;
import com.samskivert.mustache.Mustache; import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Template; import com.samskivert.mustache.Template;
import io.swagger.models.ComposedModel;
import io.swagger.models.Contact; import io.swagger.models.Contact;
import io.swagger.models.Info; import io.swagger.models.Info;
import io.swagger.models.License; import io.swagger.models.License;
@ -11,7 +13,9 @@ import io.swagger.models.Path;
import io.swagger.models.Swagger; import io.swagger.models.Swagger;
import io.swagger.models.auth.OAuth2Definition; import io.swagger.models.auth.OAuth2Definition;
import io.swagger.models.auth.SecuritySchemeDefinition; import io.swagger.models.auth.SecuritySchemeDefinition;
import io.swagger.models.parameters.Parameter;
import io.swagger.util.Json; import io.swagger.util.Json;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import java.io.File; import java.io.File;
@ -21,6 +25,8 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.Reader; import java.io.Reader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -106,10 +112,8 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
} }
if (swagger.getBasePath() != null) { if (swagger.getBasePath() != null) {
hostBuilder.append(swagger.getBasePath()); 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(); String basePath = hostBuilder.toString();
@ -119,11 +123,13 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
// models // models
Map<String, Model> definitions = swagger.getDefinitions(); Map<String, Model> definitions = swagger.getDefinitions();
if (definitions != null) { if (definitions != null) {
for (String name : definitions.keySet()) { List<String> sortedModelKeys = sortModelsByInheritance(definitions);
for (String name : sortedModelKeys) {
Model model = definitions.get(name); Model model = definitions.get(name);
Map<String, Model> modelMap = new HashMap<String, Model>(); Map<String, Model> modelMap = new HashMap<String, Model>();
modelMap.put(name, model); modelMap.put(name, model);
Map<String, Object> models = processModels(config, modelMap); Map<String, Object> models = processModels(config, modelMap, definitions);
models.putAll(config.additionalProperties()); models.putAll(config.additionalProperties());
allModels.add(((List<Object>) models.get("models")).get(0)); allModels.add(((List<Object>) models.get("models")).get(0));
@ -327,17 +333,63 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
} }
} }
private List<String> sortModelsByInheritance(final Map<String, Model> definitions) {
List<String> sortedModelKeys = new ArrayList<String>(definitions.keySet());
Comparator<String> cmp = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
Model model1 = definitions.get(o1);
Model model2 = definitions.get(o2);
int model1InheritanceDepth = getInheritanceDepth(model1);
int model2InheritanceDepth = getInheritanceDepth(model2);
if (model1InheritanceDepth == model2InheritanceDepth) {
return 0;
} else if (model1InheritanceDepth > model2InheritanceDepth) {
return 1;
} else {
return -1;
}
}
private int getInheritanceDepth(Model model) {
int inheritanceDepth = 0;
Model parent = getParent(model);
while (parent != null) {
inheritanceDepth++;
parent = getParent(parent);
}
return inheritanceDepth;
}
private Model getParent(Model model) {
if (model instanceof ComposedModel) {
return definitions.get(((ComposedModel) model).getParent().getReference());
}
return null;
}
};
Collections.sort(sortedModelKeys, cmp);
return sortedModelKeys;
}
public Map<String, List<CodegenOperation>> processPaths(Map<String, Path> paths) { public Map<String, List<CodegenOperation>> processPaths(Map<String, Path> paths) {
Map<String, List<CodegenOperation>> ops = new HashMap<String, List<CodegenOperation>>(); Map<String, List<CodegenOperation>> ops = new HashMap<String, List<CodegenOperation>>();
for (String resourcePath : paths.keySet()) { for (String resourcePath : paths.keySet()) {
Path path = paths.get(resourcePath); Path path = paths.get(resourcePath);
processOperation(resourcePath, "get", path.getGet(), ops); processOperation(resourcePath, "get", path.getGet(), ops, path);
processOperation(resourcePath, "put", path.getPut(), ops); processOperation(resourcePath, "put", path.getPut(), ops, path);
processOperation(resourcePath, "post", path.getPost(), ops); processOperation(resourcePath, "post", path.getPost(), ops, path);
processOperation(resourcePath, "delete", path.getDelete(), ops); processOperation(resourcePath, "delete", path.getDelete(), ops, path);
processOperation(resourcePath, "patch", path.getPatch(), ops); processOperation(resourcePath, "patch", path.getPatch(), ops, path);
processOperation(resourcePath, "options", path.getOptions(), ops); processOperation(resourcePath, "options", path.getOptions(), ops, path);
} }
return ops; return ops;
} }
@ -350,8 +402,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
return map.get(name); return map.get(name);
} }
public void processOperation(String resourcePath, String httpMethod, Operation operation, Map<String, List<CodegenOperation>> operations, Path path) {
public void processOperation(String resourcePath, String httpMethod, Operation operation, Map<String, List<CodegenOperation>> operations) {
if (operation != null) { if (operation != null) {
List<String> tags = operation.getTags(); List<String> tags = operation.getTags();
if (tags == null) { if (tags == null) {
@ -359,6 +410,28 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
tags.add("default"); 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) { for (String tag : tags) {
CodegenOperation co = config.fromOperation(resourcePath, httpMethod, operation, swagger.getDefinitions()); CodegenOperation co = config.fromOperation(resourcePath, httpMethod, operation, swagger.getDefinitions());
co.tags = new ArrayList<String>(); co.tags = new ArrayList<String>();
@ -403,6 +476,10 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
} }
} }
private String generateParameterId(Parameter parameter) {
return parameter.getName() + ":" + parameter.getIn();
}
protected String sanitizeTag(String tag) { protected String sanitizeTag(String tag) {
// remove spaces and make strong case // remove spaces and make strong case
String[] parts = tag.split(" "); String[] parts = tag.split(" ");
@ -475,14 +552,14 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
return operations; return operations;
} }
public Map<String, Object> processModels(CodegenConfig config, Map<String, Model> definitions) { public Map<String, Object> processModels(CodegenConfig config, Map<String, Model> definitions, Map<String, Model> allDefinitions) {
Map<String, Object> objs = new HashMap<String, Object>(); Map<String, Object> objs = new HashMap<String, Object>();
objs.put("package", config.modelPackage()); objs.put("package", config.modelPackage());
List<Object> models = new ArrayList<Object>(); List<Object> models = new ArrayList<Object>();
Set<String> allImports = new LinkedHashSet<String>(); Set<String> allImports = new LinkedHashSet<String>();
for (String key : definitions.keySet()) { for (String key : definitions.keySet()) {
Model mm = definitions.get(key); Model mm = definitions.get(key);
CodegenModel cm = config.fromModel(key, mm); CodegenModel cm = config.fromModel(key, mm, allDefinitions);
Map<String, Object> mo = new HashMap<String, Object>(); Map<String, Object> mo = new HashMap<String, Object>();
mo.put("model", cm); mo.put("model", cm);
mo.put("importPath", config.toModelImport(key)); mo.put("importPath", config.toModelImport(key));

View File

@ -0,0 +1,144 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.models.properties.*;
import java.util.*;
import java.io.File;
public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}
public AbstractTypeScriptClientCodegen() {
super();
supportsInheritance = true;
reservedWords = new HashSet<String>(Arrays.asList("abstract",
"continue", "for", "new", "switch", "assert", "default", "if",
"package", "synchronized", "do", "goto", "private",
"this", "break", "double", "implements", "protected", "throw",
"byte", "else", "import", "public", "throws", "case", "enum",
"instanceof", "return", "transient", "catch", "extends", "int",
"short", "try", "char", "final", "interface", "static", "void",
"class", "finally", "const", "super", "while"));
languageSpecificPrimitives = new HashSet<String>(Arrays.asList(
"String",
"boolean",
"Boolean",
"Double",
"Integer",
"Long",
"Float",
"Object"));
instantiationTypes.put("array", "Array");
typeMapping = new HashMap<String, String>();
typeMapping.put("Array", "Array");
typeMapping.put("array", "Array");
typeMapping.put("List", "Array");
typeMapping.put("boolean", "boolean");
typeMapping.put("string", "string");
typeMapping.put("int", "number");
typeMapping.put("float", "number");
typeMapping.put("number", "number");
typeMapping.put("long", "number");
typeMapping.put("short", "number");
typeMapping.put("char", "string");
typeMapping.put("double", "number");
typeMapping.put("object", "any");
typeMapping.put("integer", "number");
typeMapping.put("Map", "any");
typeMapping.put("DateTime", "Date");
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
}
@Override
public String apiFileFolder() {
return outputFolder + "/" + apiPackage().replace('.', File.separatorChar);
}
public String modelFileFolder() {
return outputFolder + "/" + modelPackage().replace('.', File.separatorChar);
}
@Override
public String toVarName(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_");
// if it's all uppper case, do nothing
if (name.matches("^[A-Z_]*$"))
return name;
// camelize the variable name
// pet_id => PetId
name = camelize(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) {
// should be the same as the model name
return toModelName(name);
}
@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 "{ [key: string]: "+ getTypeDeclaration(inner) + "; }";
} else if (p instanceof FileProperty) {
return "any";
}
return super.getTypeDeclaration(p);
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
String type = null;
if (typeMapping.containsKey(swaggerType)) {
type = typeMapping.get(swaggerType);
if (languageSpecificPrimitives.contains(type))
return type;
} else
type = swaggerType;
return type;
}
}

View File

@ -251,6 +251,11 @@ public class AkkaScalaClientCodegen extends DefaultCodegen implements CodegenCon
@Override @Override
public String toOperationId(String operationId) { 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");
}
return super.toOperationId(CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, operationId)); return super.toOperationId(CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, operationId));
} }

View File

@ -13,6 +13,8 @@ import java.io.File;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfig { public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client"; protected String invokerPackage = "io.swagger.client";
protected String groupId = "io.swagger"; protected String groupId = "io.swagger";
@ -168,6 +170,11 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
@Override @Override
public String toOperationId(String operationId) { 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 // method name cannot use reserved keyword, e.g. return
if (reservedWords.contains(operationId)) { if (reservedWords.contains(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name"); throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");

View File

@ -21,6 +21,8 @@ import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class AsyncScalaClientCodegen extends DefaultCodegen implements CodegenConfig { public class AsyncScalaClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client"; protected String invokerPackage = "io.swagger.client";
protected String groupId = "io.swagger"; protected String groupId = "io.swagger";

View File

@ -14,6 +14,8 @@ import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig { public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String packageName = "IO.Swagger"; protected String packageName = "IO.Swagger";
protected String packageVersion = "1.0.0"; protected String packageVersion = "1.0.0";
@ -237,6 +239,11 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
@Override @Override
public String toOperationId(String operationId) { 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 // method name cannot use reserved keyword, e.g. return
if (reservedWords.contains(operationId)) { if (reservedWords.contains(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name"); throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");

View File

@ -0,0 +1,255 @@
package io.swagger.codegen.languages;
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.codegen.CliOption;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
public class CsharpDotNet2ClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String packageName = "IO.Swagger";
protected String packageVersion = "1.0.0";
protected String clientPackage = "IO.Swagger.Client";
protected String sourceFolder = "src" + File.separator + "main" + File.separator + "CsharpDotNet2";
public CsharpDotNet2ClientCodegen() {
super();
outputFolder = "generated-code" + File.separator + "CsharpDotNet2";
modelTemplateFiles.put("model.mustache", ".cs");
apiTemplateFiles.put("api.mustache", ".cs");
templateDir = "CsharpDotNet2";
apiPackage = "IO.Swagger.Api";
modelPackage = "IO.Swagger.Model";
reservedWords = new HashSet<String>(
Arrays.asList(
"abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock", "long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void", "volatile", "while")
);
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"String",
"string",
"bool?",
"double?",
"int?",
"long?",
"float?",
"byte[]",
"List",
"Dictionary",
"DateTime?",
"String",
"Boolean",
"Double",
"Integer",
"Long",
"Float",
"Stream", // not really a primitive, we include it to avoid model import
"Object")
);
instantiationTypes.put("array", "List");
instantiationTypes.put("map", "Dictionary");
typeMapping = new HashMap<String, String>();
typeMapping.put("string", "string");
typeMapping.put("boolean", "bool?");
typeMapping.put("integer", "int?");
typeMapping.put("float", "float?");
typeMapping.put("long", "long?");
typeMapping.put("double", "double?");
typeMapping.put("number", "double?");
typeMapping.put("datetime", "DateTime?");
typeMapping.put("date", "DateTime?");
typeMapping.put("file", "Stream");
typeMapping.put("array", "List");
typeMapping.put("list", "List");
typeMapping.put("map", "Dictionary");
typeMapping.put("object", "Object");
cliOptions.clear();
cliOptions.add(new CliOption("packageName", "C# package name (convention: Camel.Case), default: IO.Swagger"));
cliOptions.add(new CliOption("packageVersion", "C# package version, default: 1.0.0"));
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey("packageVersion")) {
packageVersion = (String) additionalProperties.get("packageVersion");
} else {
additionalProperties.put("packageVersion", packageVersion);
}
if (additionalProperties.containsKey("packageName")) {
packageName = (String) additionalProperties.get("packageName");
apiPackage = packageName + ".Api";
modelPackage = packageName + ".Model";
clientPackage = packageName + ".Client";
} else {
additionalProperties.put("packageName", packageName);
}
if (additionalProperties.containsKey("clientPackage")) {
this.setClientPackage((String) additionalProperties.get("clientPackage"));
} else {
additionalProperties.put("clientPackage", clientPackage);
}
supportingFiles.add(new SupportingFile("Configuration.mustache",
(sourceFolder + File.separator + clientPackage).replace(".", java.io.File.separator), "Configuration.cs"));
supportingFiles.add(new SupportingFile("ApiClient.mustache",
(sourceFolder + File.separator + clientPackage).replace(".", java.io.File.separator), "ApiClient.cs"));
supportingFiles.add(new SupportingFile("ApiException.mustache",
(sourceFolder + File.separator + clientPackage).replace(".", java.io.File.separator), "ApiException.cs"));
supportingFiles.add(new SupportingFile("packages.config.mustache", "vendor", "packages.config"));
supportingFiles.add(new SupportingFile("compile-mono.sh.mustache", "", "compile-mono.sh"));
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
}
public void setClientPackage(String clientPackage) {
this.clientPackage = clientPackage;
}
public CodegenType getTag() {
return CodegenType.CLIENT;
}
public String getName() {
return "CsharpDotNet2";
}
public String getHelp() {
return "Generates a C# .Net 2.0 client library.";
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
}
@Override
public String apiFileFolder() {
return (outputFolder + File.separator + sourceFolder + File.separator + apiPackage()).replace('.', File.separatorChar);
}
public String modelFileFolder() {
return (outputFolder + File.separator + sourceFolder + File.separator + modelPackage()).replace('.', File.separatorChar);
}
@Override
public String toVarName(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_");
// if it's all uppper case, do nothing
if (name.matches("^[A-Z_]*$")) {
return name;
}
// camelize the variable name
// pet_id => PetId
name = camelize(name);
// 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) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_");
// if it's all uppper case, do nothing
if (name.matches("^[A-Z_]*$")) {
return name;
}
// camelize(lower) the variable name
// pet_id => petId
name = camelize(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 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) {
// should be the same as the model name
return toModelName(name);
}
@Override
public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return getSwaggerType(p) + "<" + getTypeDeclaration(inner) + ">";
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return getSwaggerType(p) + "<String, " + getTypeDeclaration(inner) + ">";
}
return super.getTypeDeclaration(p);
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
String type = null;
if (typeMapping.containsKey(swaggerType.toLowerCase())) {
type = typeMapping.get(swaggerType.toLowerCase());
if (languageSpecificPrimitives.contains(type)) {
return type;
}
} else {
type = swaggerType;
}
return toModelName(type);
}
@Override
public String toOperationId(String operationId) {
// 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 camelize(operationId);
}
}

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

@ -13,13 +13,15 @@ import java.io.File;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig { public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client"; protected String invokerPackage = "io.swagger.client";
protected String groupId = "io.swagger"; protected String groupId = "io.swagger";
protected String artifactId = "swagger-java-client"; protected String artifactId = "swagger-java-client";
protected String artifactVersion = "1.0.0"; protected String artifactVersion = "1.0.0";
protected String sourceFolder = "src/main/java"; protected String sourceFolder = "src/main/java";
protected String localVariablePrefix = "";
public JavaClientCodegen() { public JavaClientCodegen() {
super(); super();
outputFolder = "generated-code/java"; outputFolder = "generated-code/java";
@ -59,6 +61,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
cliOptions.add(new CliOption("artifactId", "artifactId in generated pom.xml")); 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("artifactVersion", "artifact version in generated pom.xml"));
cliOptions.add(new CliOption("sourceFolder", "source folder for generated code")); cliOptions.add(new CliOption("sourceFolder", "source folder for generated code"));
cliOptions.add(new CliOption("localVariablePrefix", "prefix for generated code members and local variables"));
} }
public CodegenType getTag() { public CodegenType getTag() {
@ -109,6 +112,11 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
this.setSourceFolder((String) additionalProperties.get("sourceFolder")); this.setSourceFolder((String) additionalProperties.get("sourceFolder"));
} }
if (additionalProperties.containsKey("localVariablePrefix")) {
this.setLocalVariablePrefix((String) additionalProperties.get("localVariablePrefix"));
}
final String invokerFolder = (sourceFolder + File.separator + invokerPackage).replace(".", File.separator); final String invokerFolder = (sourceFolder + File.separator + invokerPackage).replace(".", File.separator);
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml")); supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("ApiClient.mustache", invokerFolder, "ApiClient.java")); supportingFiles.add(new SupportingFile("ApiClient.mustache", invokerFolder, "ApiClient.java"));
@ -205,6 +213,18 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
return super.getTypeDeclaration(p); return super.getTypeDeclaration(p);
} }
@Override
public String toDefaultValue(Property p) {
if (p instanceof ArrayProperty) {
final ArrayProperty ap = (ArrayProperty) p;
return String.format("new ArrayList<%s>()", getTypeDeclaration(ap.getItems()));
} else if (p instanceof MapProperty) {
final MapProperty ap = (MapProperty) p;
return String.format("new HashMap<String, %s>()", getTypeDeclaration(ap.getAdditionalProperties()));
}
return super.toDefaultValue(p);
}
@Override @Override
public String getSwaggerType(Property p) { public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p); String swaggerType = super.getSwaggerType(p);
@ -222,6 +242,11 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public String toOperationId(String operationId) { 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 // method name cannot use reserved keyword, e.g. return
if (reservedWords.contains(operationId)) { if (reservedWords.contains(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name"); throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
@ -249,4 +274,8 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
public void setSourceFolder(String sourceFolder) { public void setSourceFolder(String sourceFolder) {
this.sourceFolder = sourceFolder; this.sourceFolder = sourceFolder;
} }
public void setLocalVariablePrefix(String localVariablePrefix) {
this.localVariablePrefix = localVariablePrefix;
}
} }

View File

@ -0,0 +1,188 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.SupportingFile;
import io.swagger.models.Operation;
import io.swagger.models.Swagger;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import io.swagger.util.Json;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
public class JavaInflectorServerCodegen extends JavaClientCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.handler";
protected String groupId = "io.swagger";
protected String artifactId = "swagger-inflector-server";
protected String artifactVersion = "1.0.0";
protected String title = "Swagger Inflector";
public JavaInflectorServerCodegen() {
super();
sourceFolder = "src/main/java";
modelTemplateFiles.put("model.mustache", ".java");
apiTemplateFiles.put("api.mustache", ".java");
templateDir = "JavaInflector";
apiPackage = System.getProperty("swagger.codegen.inflector.apipackage", "io.swagger.handler");
modelPackage = System.getProperty("swagger.codegen.inflector.modelpackage", "io.swagger.model");
additionalProperties.put("invokerPackage", invokerPackage);
additionalProperties.put("groupId", groupId);
additionalProperties.put("artifactId", artifactId);
additionalProperties.put("artifactVersion", artifactVersion);
additionalProperties.put("title", title);
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"String",
"boolean",
"Boolean",
"Double",
"Integer",
"Long",
"Float")
);
}
public CodegenType getTag() {
return CodegenType.SERVER;
}
public String getName() {
return "inflector";
}
public String getHelp() {
return "Generates a Java Inflector Server application.";
}
@Override
public void processOpts() {
super.processOpts();
supportingFiles.clear();
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("web.mustache", "src/main/webapp/WEB-INF", "web.xml"));
supportingFiles.add(new SupportingFile("inflector.mustache", "", "inflector.yaml"));
}
@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;
if (basePath.startsWith("/")) {
basePath = basePath.substring(1);
}
int pos = basePath.indexOf("/");
if (pos > 0) {
basePath = basePath.substring(0, pos);
}
if (basePath == "") {
basePath = "default";
} else {
if (co.path.startsWith("/" + basePath)) {
co.path = co.path.substring(("/" + basePath).length());
}
co.subresourceOperation = !co.path.isEmpty();
}
List<CodegenOperation> opList = operations.get(basePath);
if (opList == null) {
opList = new ArrayList<CodegenOperation>();
operations.put(basePath, opList);
}
opList.add(co);
co.baseName = basePath;
}
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation operation : ops) {
if (operation.returnType == null) {
operation.returnType = "Void";
} else if (operation.returnType.startsWith("List")) {
String rt = operation.returnType;
int end = rt.lastIndexOf(">");
if (end > 0) {
operation.returnType = rt.substring("List<".length(), end);
operation.returnContainer = "List";
}
} else if (operation.returnType.startsWith("Map")) {
String rt = operation.returnType;
int end = rt.lastIndexOf(">");
if (end > 0) {
operation.returnType = rt.substring("Map<".length(), end);
operation.returnContainer = "Map";
}
} else if (operation.returnType.startsWith("Set")) {
String rt = operation.returnType;
int end = rt.lastIndexOf(">");
if (end > 0) {
operation.returnType = rt.substring("Set<".length(), end);
operation.returnContainer = "Set";
}
}
}
}
return objs;
}
@Override
public void processSwagger(Swagger swagger) {
super.processSwagger(swagger);
try {
File file = new File( outputFolder + "/src/main/swagger/swagger.json" );
file.getParentFile().mkdirs();
FileWriter swaggerFile = new FileWriter(file);
swaggerFile.write( Json.pretty( swagger ));
swaggerFile.flush();
swaggerFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "DefaultController";
}
name = name.replaceAll("[^a-zA-Z0-9]+", "_");
return camelize(name)+ "Controller";
}
public boolean shouldOverwrite(String filename) {
return super.shouldOverwrite(filename);
}
}

View File

@ -89,21 +89,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 @Override
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) { public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
String basePath = resourcePath; String basePath = resourcePath;

View File

@ -9,11 +9,19 @@ import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile; import io.swagger.codegen.SupportingFile;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; 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 { public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig {
protected String apiVersion = "1.0.0"; protected String apiVersion = "1.0.0";
@ -197,4 +205,50 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
} }
return objs; 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

@ -16,6 +16,8 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang.StringUtils;
public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
protected Set<String> foundationClasses = new HashSet<String>(); protected Set<String> foundationClasses = new HashSet<String>();
protected String podName = "SwaggerClient"; protected String podName = "SwaggerClient";
@ -57,7 +59,7 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.clear(); typeMapping.clear();
typeMapping.put("enum", "NSString"); typeMapping.put("enum", "NSString");
typeMapping.put("Date", "NSDate"); typeMapping.put("date", "NSDate");
typeMapping.put("DateTime", "NSDate"); typeMapping.put("DateTime", "NSDate");
typeMapping.put("boolean", "NSNumber"); typeMapping.put("boolean", "NSNumber");
typeMapping.put("string", "NSString"); typeMapping.put("string", "NSString");
@ -213,21 +215,22 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
Property inner = ap.getItems(); Property inner = ap.getItems();
String innerType = getSwaggerType(inner); 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); String innerTypeDeclaration = getTypeDeclaration(inner);
if (innerTypeDeclaration.endsWith("*")) { if (innerTypeDeclaration.endsWith("*")) {
innerTypeDeclaration = innerTypeDeclaration.substring(0, innerTypeDeclaration.length() - 1); 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 + ">*"; return getSwaggerType(p) + "<" + innerTypeDeclaration + ">*";
}
} else if (p instanceof MapProperty) { } else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p; MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties(); Property inner = mp.getAdditionalProperties();
@ -358,6 +361,11 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public String toOperationId(String operationId) { 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 // method name cannot use reserved keyword, e.g. return
if (reservedWords.contains(operationId)) { if (reservedWords.contains(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name"); throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");

View File

@ -9,11 +9,12 @@ import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property; import io.swagger.models.properties.Property;
import io.swagger.codegen.CliOption; import io.swagger.codegen.CliOption;
import java.io.File; import java.io.File;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig { public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String moduleName = "SwaggerClient"; protected String moduleName = "SwaggerClient";
protected String moduleVersion = "1.0.0"; protected String moduleVersion = "1.0.0";
@ -158,15 +159,17 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public String toVarName(String name) { 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 // parameter name starting with number won't compile
// need to escape it by appending _ at the beginning // need to escape it by appending _ at the beginning
if (name.matches("^[0-9]")) { if (name.matches("^\\d.*")) {
name = "_" + name; name = "_" + name;
} }
// return the name in underscore style return name;
// PhoneNumber => phone_number
return underscore(name);
} }
@Override @Override
@ -213,6 +216,11 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public String toOperationId(String operationId) { 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 // method name cannot use reserved keyword, e.g. return
if (reservedWords.contains(operationId)) { if (reservedWords.contains(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name"); throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");

View File

@ -15,6 +15,8 @@ import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "Swagger\\Client"; protected String invokerPackage = "Swagger\\Client";
protected String composerVendorName = "swagger"; protected String composerVendorName = "swagger";
@ -77,12 +79,12 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("object", "object"); typeMapping.put("object", "object");
typeMapping.put("DateTime", "\\DateTime"); typeMapping.put("DateTime", "\\DateTime");
cliOptions.add(new CliOption("invokerPackage", "The main namespace to use for all 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.")); 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("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("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.")); 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.")); cliOptions.add(new CliOption("artifactVersion", "The version to use in the composer package version field. e.g. 1.2.3"));
} }
public String getPackagePath() { public String getPackagePath() {
@ -282,15 +284,17 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public String toVarName(String name) { 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 // parameter name starting with number won't compile
// need to escape it by appending _ at the beginning // need to escape it by appending _ at the beginning
if (name.matches("^[0-9]")) { if (name.matches("^\\d.*")) {
name = "_" + name; name = "_" + name;
} }
// return the name in underscore style return name;
// PhoneNumber => phone_number
return underscore(name);
} }
@Override @Override

View File

@ -12,6 +12,8 @@ import java.io.File;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class Python3ClientCodegen extends DefaultCodegen implements CodegenConfig { public class Python3ClientCodegen extends DefaultCodegen implements CodegenConfig {
String module = "client"; String module = "client";
@ -201,6 +203,11 @@ public class Python3ClientCodegen extends DefaultCodegen implements CodegenConfi
@Override @Override
public String toOperationId(String operationId) { 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 // method name cannot use reserved keyword, e.g. return
if (reservedWords.contains(operationId)) { if (reservedWords.contains(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name"); throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");

View File

@ -13,6 +13,8 @@ import java.io.File;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig { public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String packageName = null; protected String packageName = null;
protected String packageVersion = null; protected String packageVersion = null;
@ -117,7 +119,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
@Override @Override
public String escapeReservedWord(String name) { public String escapeReservedWord(String name) {
return "_" + name; return name + "_";
} }
@Override @Override
@ -160,8 +162,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
} }
public String toDefaultValue(Property p) { public String toDefaultValue(Property p) {
// TODO: Support Python def value return "None";
return "null";
} }
@Override @Override
@ -183,6 +184,9 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
name = escapeReservedWord(name); name = escapeReservedWord(name);
} }
// remove leading underscore
name = name.replaceAll("^_*", "");
return name; return name;
} }
@ -244,6 +248,11 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
@Override @Override
public String toOperationId(String operationId) { 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 // method name cannot use reserved keyword, e.g. return
if (reservedWords.contains(operationId)) { if (reservedWords.contains(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name"); throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");

View File

@ -15,6 +15,8 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.lang.StringUtils;
public class RetrofitClientCodegen extends DefaultCodegen implements CodegenConfig { public class RetrofitClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client"; protected String invokerPackage = "io.swagger.client";
protected String groupId = "io.swagger"; protected String groupId = "io.swagger";
@ -171,6 +173,11 @@ public class RetrofitClientCodegen extends DefaultCodegen implements CodegenConf
@Override @Override
public String toOperationId(String operationId) { 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 // method name cannot use reserved keyword, e.g. return
if (reservedWords.contains(operationId)) { if (reservedWords.contains(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name"); throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");

View File

@ -13,6 +13,8 @@ import java.io.File;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String gemName = null; protected String gemName = null;
protected String moduleName = null; protected String moduleName = null;
@ -263,6 +265,11 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public String toOperationId(String operationId) { 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 // method name cannot use reserved keyword, e.g. return
if (reservedWords.contains(operationId)) { if (reservedWords.contains(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name"); throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");

View File

@ -24,6 +24,8 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.lang.StringUtils;
public class ScalaClientCodegen extends DefaultCodegen implements CodegenConfig { public class ScalaClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client"; protected String invokerPackage = "io.swagger.client";
protected String groupId = "io.swagger"; protected String groupId = "io.swagger";
@ -209,6 +211,11 @@ public class ScalaClientCodegen extends DefaultCodegen implements CodegenConfig
@Override @Override
public String toOperationId(String operationId) { 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 // method name cannot use reserved keyword, e.g. return
if (reservedWords.contains(operationId)) { if (reservedWords.contains(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name"); throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");

View File

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

View File

@ -13,6 +13,8 @@ import java.io.File;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class SinatraServerCodegen extends DefaultCodegen implements CodegenConfig { public class SinatraServerCodegen extends DefaultCodegen implements CodegenConfig {
protected String gemName = null; protected String gemName = null;
protected String moduleName = null; protected String moduleName = null;

View File

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

View File

@ -100,7 +100,7 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("number", "Double"); typeMapping.put("number", "Double");
typeMapping.put("double", "Double"); typeMapping.put("double", "Double");
typeMapping.put("object", "String"); typeMapping.put("object", "String");
typeMapping.put("file", "NSData"); typeMapping.put("file", "NSURL");
importMapping = new HashMap<String, String>(); importMapping = new HashMap<String, String>();
@ -109,6 +109,17 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
StringUtils.join(RESPONSE_LIBRARIES, ", ") + " are available.")); StringUtils.join(RESPONSE_LIBRARIES, ", ") + " are available."));
cliOptions.add(new CliOption("unwrapRequired", "Treat 'required' properties in response as non-optional " + cliOptions.add(new CliOption("unwrapRequired", "Treat 'required' properties in response as non-optional " +
"(which would crash the app if api returns null as opposed to required option specified in json schema")); "(which would crash the app if api returns null as opposed to required option specified in json schema"));
cliOptions.add(new CliOption("podSource", "Source information used for Podspec"));
cliOptions.add(new CliOption("podVersion", "Version used for Podspec"));
cliOptions.add(new CliOption("podAuthors", "Authors used for Podspec"));
cliOptions.add(new CliOption("podSocialMediaURL", "Social Media URL used for Podspec"));
cliOptions.add(new CliOption("podDocsetURL", "Docset URL used for Podspec"));
cliOptions.add(new CliOption("podLicense", "License used for Podspec"));
cliOptions.add(new CliOption("podHomepage", "Homepage used for Podspec"));
cliOptions.add(new CliOption("podSummary", "Summary used for Podspec"));
cliOptions.add(new CliOption("podDescription", "Description used for Podspec"));
cliOptions.add(new CliOption("podScreenshots", "Screenshots used for Podspec"));
cliOptions.add(new CliOption("podDocumentationURL", "Documentation URL used for Podspec"));
} }
@Override @Override
@ -143,6 +154,7 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
additionalProperties.put("usePromiseKit", true); additionalProperties.put("usePromiseKit", true);
} }
supportingFiles.add(new SupportingFile("Podspec.mustache", "", projectName + ".podspec"));
supportingFiles.add(new SupportingFile("Cartfile.mustache", "", "Cartfile")); supportingFiles.add(new SupportingFile("Cartfile.mustache", "", "Cartfile"));
supportingFiles.add(new SupportingFile("APIHelper.mustache", sourceFolder, "APIHelper.swift")); supportingFiles.add(new SupportingFile("APIHelper.mustache", sourceFolder, "APIHelper.swift"));
supportingFiles.add(new SupportingFile("AlamofireImplementations.mustache", sourceFolder, supportingFiles.add(new SupportingFile("AlamofireImplementations.mustache", sourceFolder,

View File

@ -25,6 +25,8 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang.StringUtils;
public class TizenClientCodegen extends DefaultCodegen implements CodegenConfig { public class TizenClientCodegen extends DefaultCodegen implements CodegenConfig {
protected static String PREFIX = "Sami"; protected static String PREFIX = "Sami";
protected Set<String> foundationClasses = new HashSet<String>(); protected Set<String> foundationClasses = new HashSet<String>();
@ -265,6 +267,11 @@ public class TizenClientCodegen extends DefaultCodegen implements CodegenConfig
@Override @Override
public String toOperationId(String operationId) { 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$ // method name cannot use reserved keyword, e.g. return$
if (reservedWords.contains(operationId)) { if (reservedWords.contains(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name"); throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");

View File

@ -1,25 +1,28 @@
package io.swagger.codegen.languages; package io.swagger.codegen.languages;
import java.io.File;
import io.swagger.codegen.SupportingFile; import io.swagger.codegen.SupportingFile;
public class TypeScriptAngularClientCodegen extends TypeScriptNodeClientCodegen { import java.io.File;
public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCodegen {
@Override @Override
public String getName() { public String getName() {
return "typescript-angular"; return "typescript-angular";
} }
public String getHelp() {
return "Generates a TypeScript AngurlarJS client library.";
}
public TypeScriptAngularClientCodegen() { public TypeScriptAngularClientCodegen() {
super(); super();
outputFolder = "generated-code/typescript-angular"; outputFolder = "generated-code/typescript-angular";
modelTemplateFiles.put("model.mustache", ".ts"); modelTemplateFiles.put("model.mustache", ".ts");
apiTemplateFiles.put("api.mustache", ".ts"); apiTemplateFiles.put("api.mustache", ".ts");
templateDir = "TypeScript-Angular"; templateDir = "TypeScript-Angular";
apiPackage = "api"; apiPackage = "API.Client";
modelPackage = "model"; modelPackage = "API.Client";
supportingFiles.add(new SupportingFile("api.d.mustache", apiPackage().replace('.', File.separatorChar), "api.d.ts"));
supportingFiles.add(new SupportingFile("api.d.mustache", apiPackage + File.separator, "api.d.ts"));
} }
} }

View File

@ -1,22 +1,8 @@
package io.swagger.codegen.languages; package io.swagger.codegen.languages;
import io.swagger.codegen.*; import io.swagger.codegen.SupportingFile;
import io.swagger.models.properties.*;
import java.util.*; public class TypeScriptNodeClientCodegen extends AbstractTypeScriptClientCodegen {
import java.io.File;
public class TypeScriptNodeClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client";
protected String groupId = "io.swagger";
protected String artifactId = "swagger-typescript-node-client";
protected String artifactVersion = "1.0.0";
protected String sourceFolder = "src/main/typescript";
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}
@Override @Override
public String getName() { public String getName() {
@ -31,141 +17,8 @@ public class TypeScriptNodeClientCodegen extends DefaultCodegen implements Codeg
public TypeScriptNodeClientCodegen() { public TypeScriptNodeClientCodegen() {
super(); super();
outputFolder = "generated-code/typescript-node"; outputFolder = "generated-code/typescript-node";
modelTemplateFiles.put("model.mustache", ".ts");
apiTemplateFiles.put("api.mustache", ".ts");
templateDir = "TypeScript-node"; templateDir = "TypeScript-node";
apiPackage = "api"; supportingFiles.add(new SupportingFile("api.mustache", null, "api.ts"));
modelPackage = "model";
reservedWords = new HashSet<String>(Arrays.asList("abstract",
"continue", "for", "new", "switch", "assert", "default", "if",
"package", "synchronized", "do", "goto", "private",
"this", "break", "double", "implements", "protected", "throw",
"byte", "else", "import", "public", "throws", "case", "enum",
"instanceof", "return", "transient", "catch", "extends", "int",
"short", "try", "char", "final", "interface", "static", "void",
"class", "finally", "const", "super", "while"));
additionalProperties.put("invokerPackage", invokerPackage);
additionalProperties.put("groupId", groupId);
additionalProperties.put("artifactId", artifactId);
additionalProperties.put("artifactVersion", artifactVersion);
languageSpecificPrimitives = new HashSet<String>(Arrays.asList(
"String",
"boolean",
"Boolean",
"Double",
"Integer",
"Long",
"Float",
"Object"));
instantiationTypes.put("array", "Array");
typeMapping = new HashMap<String, String>();
typeMapping.put("Array", "Array");
typeMapping.put("array", "Array");
typeMapping.put("List", "Array");
typeMapping.put("boolean", "boolean");
typeMapping.put("string", "string");
typeMapping.put("int", "number");
typeMapping.put("float", "number");
typeMapping.put("number", "number");
typeMapping.put("long", "number");
typeMapping.put("short", "number");
typeMapping.put("char", "string");
typeMapping.put("double", "number");
typeMapping.put("object", "any");
typeMapping.put("integer", "number");
typeMapping.put("Map", "any");
typeMapping.put("DateTime", "Date");
} }
@Override
public String escapeReservedWord(String name) {
return "_" + name;
}
@Override
public String apiFileFolder() {
return outputFolder + "/" + apiPackage().replace('.', File.separatorChar);
}
public String modelFileFolder() {
return outputFolder + "/" + modelPackage().replace('.', File.separatorChar);
}
@Override
public String toVarName(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_");
// if it's all uppper case, do nothing
if (name.matches("^[A-Z_]*$"))
return name;
// camelize the variable name
// pet_id => PetId
name = camelize(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) {
// should be the same as the model name
return toModelName(name);
}
@Override
public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return getSwaggerType(p) + "<" + getTypeDeclaration(inner) + ">";
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return getSwaggerType(p) + "<String, " + getTypeDeclaration(inner)
+ ">";
}
return super.getTypeDeclaration(p);
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
String type = null;
if (typeMapping.containsKey(swaggerType)) {
type = typeMapping.get(swaggerType);
if (languageSpecificPrimitives.contains(type))
return type;
} else
type = swaggerType;
return type;
}
} }

View File

@ -0,0 +1,291 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.IO;
using System.Web;
using System.Linq;
using System.Net;
using System.Text;
using Newtonsoft.Json;
using RestSharp;
using RestSharp.Extensions;
namespace {{packageName}}.Client
{
/// <summary>
/// API client is mainly responible for making the HTTP call to the API backend.
/// </summary>
public class ApiClient
{
private readonly Dictionary<String, String> _defaultHeaderMap = new Dictionary<String, String>();
/// <summary>
/// Initializes a new instance of the <see cref="ApiClient" /> class.
/// </summary>
/// <param name="basePath">The base path.</param>
public ApiClient(String basePath="{{basePath}}")
{
BasePath = basePath;
RestClient = new RestClient(BasePath);
}
/// <summary>
/// Gets or sets the base path.
/// </summary>
/// <value>The base path</value>
public string BasePath { get; set; }
/// <summary>
/// Gets or sets the RestClient.
/// </summary>
/// <value>An instance of the RestClient</value>
public RestClient RestClient { get; set; }
/// <summary>
/// Gets the default header.
/// </summary>
public Dictionary<String, String> DefaultHeader
{
get { return _defaultHeaderMap; }
}
/// <summary>
/// Makes the HTTP request (Sync).
/// </summary>
/// <param name="path">URL path.</param>
/// <param name="method">HTTP method.</param>
/// <param name="queryParams">Query parameters.</param>
/// <param name="postBody">HTTP body (POST request).</param>
/// <param name="headerParams">Header parameters.</param>
/// <param name="formParams">Form parameters.</param>
/// <param name="fileParams">File parameters.</param>
/// <param name="authSettings">Authentication settings.</param>
/// <returns>Object</returns>
public Object CallApi(String path, RestSharp.Method method, Dictionary<String, String> queryParams, String postBody,
Dictionary<String, String> headerParams, Dictionary<String, String> formParams,
Dictionary<String, FileParameter> fileParams, String[] authSettings)
{
var request = new RestRequest(path, method);
UpdateParamsForAuth(queryParams, headerParams, authSettings);
// add default header, if any
foreach(var defaultHeader in _defaultHeaderMap)
request.AddHeader(defaultHeader.Key, defaultHeader.Value);
// add header parameter, if any
foreach(var param in headerParams)
request.AddHeader(param.Key, param.Value);
// add query parameter, if any
foreach(var param in queryParams)
request.AddParameter(param.Key, param.Value, ParameterType.GetOrPost);
// add form parameter, if any
foreach(var param in formParams)
request.AddParameter(param.Key, param.Value, ParameterType.GetOrPost);
// add file parameter, if any
foreach(var param in fileParams)
request.AddFile(param.Value.Name, param.Value.Writer, param.Value.FileName, param.Value.ContentType);
if (postBody != null) // http body (model) parameter
request.AddParameter("application/json", postBody, ParameterType.RequestBody);
return (Object)RestClient.Execute(request);
}
/// <summary>
/// Add default header.
/// </summary>
/// <param name="key">Header field name.</param>
/// <param name="value">Header field value.</param>
/// <returns></returns>
public void AddDefaultHeader(string key, string value)
{
_defaultHeaderMap.Add(key, value);
}
/// <summary>
/// Escape string (url-encoded).
/// </summary>
/// <param name="str">String to be escaped.</param>
/// <returns>Escaped string.</returns>
public string EscapeString(string str)
{
return RestSharp.Contrib.HttpUtility.UrlEncode(str);
}
/// <summary>
/// Create FileParameter based on Stream.
/// </summary>
/// <param name="name">Parameter name.</param>
/// <param name="stream">Input stream.</param>
/// <returns>FileParameter.</returns>
public FileParameter ParameterToFile(string name, Stream stream)
{
if (stream is FileStream)
return FileParameter.Create(name, stream.ReadAsBytes(), Path.GetFileName(((FileStream)stream).Name));
else
return FileParameter.Create(name, stream.ReadAsBytes(), "no_file_name_provided");
}
/// <summary>
/// If parameter is DateTime, output in ISO8601 format.
/// If parameter is a list of string, join the list with ",".
/// Otherwise just return the string.
/// </summary>
/// <param name="obj">The parameter (header, path, query, form).</param>
/// <returns>Formatted string.</returns>
public string ParameterToString(object obj)
{
if (obj is DateTime)
return ((DateTime)obj).ToString ("u");
else if (obj is List<string>)
return String.Join(",", (obj as List<string>).ToArray());
else
return Convert.ToString (obj);
}
/// <summary>
/// Deserialize the JSON string into a proper object.
/// </summary>
/// <param name="content">HTTP body (e.g. string, JSON).</param>
/// <param name="type">Object type.</param>
/// <returns>Object representation of the JSON string.</returns>
public object Deserialize(string content, Type type, IList<Parameter> headers=null)
{
if (type == typeof(Object)) // return an object
{
return content;
}
if (type == typeof(Stream))
{
var filePath = String.IsNullOrEmpty(Configuration.TempFolderPath)
? Path.GetTempPath()
: Configuration.TempFolderPath;
var fileName = filePath + Guid.NewGuid();
if (headers != null)
{
var regex = new Regex(@"Content-Disposition:.*filename=['""]?([^'""\s]+)['""]?$");
var match = regex.Match(headers.ToString());
if (match.Success)
fileName = filePath + match.Value.Replace("\"", "").Replace("'", "");
}
File.WriteAllText(fileName, content);
return new FileStream(fileName, FileMode.Open);
}
if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object
{
return DateTime.Parse(content, null, System.Globalization.DateTimeStyles.RoundtripKind);
}
if (type == typeof(String) || type.Name.StartsWith("System.Nullable")) // return primitive type
{
return ConvertType(content, type);
}
// at this point, it must be a model (json)
try
{
return JsonConvert.DeserializeObject(content, type);
}
catch (IOException e)
{
throw new ApiException(500, e.Message);
}
}
/// <summary>
/// Serialize an object into JSON string.
/// </summary>
/// <param name="obj">Object.</param>
/// <returns>JSON string.</returns>
public string Serialize(object obj)
{
try
{
return obj != null ? JsonConvert.SerializeObject(obj) : null;
}
catch (Exception e)
{
throw new ApiException(500, e.Message);
}
}
/// <summary>
/// Get the API key with prefix.
/// </summary>
/// <param name="apiKeyIdentifier">API key identifier (authentication scheme).</param>
/// <returns>API key with prefix.</returns>
public string GetApiKeyWithPrefix (string apiKeyIdentifier)
{
var apiKeyValue = "";
Configuration.ApiKey.TryGetValue (apiKeyIdentifier, out apiKeyValue);
var apiKeyPrefix = "";
if (Configuration.ApiKeyPrefix.TryGetValue (apiKeyIdentifier, out apiKeyPrefix))
return apiKeyPrefix + " " + apiKeyValue;
else
return apiKeyValue;
}
/// <summary>
/// Update parameters based on authentication.
/// </summary>
/// <param name="queryParams">Query parameters.</param>
/// <param name="headerParams">Header parameters.</param>
/// <param name="authSettings">Authentication settings.</param>
public void UpdateParamsForAuth(Dictionary<String, String> queryParams, Dictionary<String, String> headerParams, string[] authSettings)
{
if (authSettings == null || authSettings.Length == 0)
return;
foreach (string auth in authSettings)
{
// determine which one to use
switch(auth)
{
{{#authMethods}}
case "{{name}}":
{{#isApiKey}}{{#isKeyInHeader}}headerParams["{{keyParamName}}"] = GetApiKeyWithPrefix("{{keyParamName}}");{{/isKeyInHeader}}{{#isKeyInQuery}}queryParams["{{keyParamName}}"] = GetApiKeyWithPrefix("{{keyParamName}}");{{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}headerParams["Authorization"] = "Basic " + Base64Encode(Configuration.Username + ":" + Configuration.Password);{{/isBasic}}
{{#isOAuth}}//TODO support oauth{{/isOAuth}}
break;
{{/authMethods}}
default:
//TODO show warning about security definition not found
break;
}
}
}
/// <summary>
/// Encode string in base64 format.
/// </summary>
/// <param name="text">String to be encoded.</param>
/// <returns>Encoded string.</returns>
public static string Base64Encode(string text)
{
var textByte = System.Text.Encoding.UTF8.GetBytes(text);
return System.Convert.ToBase64String(textByte);
}
/// <summary>
/// Dynamically cast the object into target type.
/// Ref: http://stackoverflow.com/questions/4925718/c-dynamic-runtime-cast
/// </summary>
/// <param name="source">Object to be casted</param>
/// <param name="dest">Target type</param>
/// <returns>Casted object</returns>
public static Object ConvertType(Object source, Type dest) {
return Convert.ChangeType(source, dest);
}
}
}

View File

@ -0,0 +1,48 @@
using System;
namespace {{packageName}}.Client {
/// <summary>
/// API Exception
/// </summary>
public class ApiException : Exception {
/// <summary>
/// Gets or sets the error code (HTTP status code)
/// </summary>
/// <value>The error code (HTTP status code).</value>
public int ErrorCode { get; set; }
/// <summary>
/// Gets or sets the error content (body json object)
/// </summary>
/// <value>The error content (Http response body).</value>
public Object ErrorContent { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="ApiException"/> class.
/// </summary>
/// <param name="basePath">The base path.</param>
public ApiException() {}
/// <summary>
/// Initializes a new instance of the <see cref="ApiException"/> class.
/// </summary>
/// <param name="errorCode">HTTP status code.</param>
/// <param name="message">Error message.</param>
public ApiException(int errorCode, string message) : base(message) {
this.ErrorCode = errorCode;
}
/// <summary>
/// Initializes a new instance of the <see cref="ApiException"/> class.
/// </summary>
/// <param name="errorCode">HTTP status code.</param>
/// <param name="message">Error message.</param>
/// <param name="errorContent">Error content.</param>
public ApiException(int errorCode, string message, Object errorContent = null) : base(message) {
this.ErrorCode = errorCode;
this.ErrorContent = errorContent;
}
}
}

View File

@ -0,0 +1,99 @@
using System;
using System.Reflection;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace {{packageName}}.Client
{
/// <summary>
/// Represents a set of configuration settings
/// </summary>
public class Configuration
{
/// <summary>
/// Version of the package.
/// </summary>
/// <value>Version of the package.</value>
public const string Version = "{{packageVersion}}";
/// <summary>
/// Gets or sets the default API client for making HTTP calls.
/// </summary>
/// <value>The API client.</value>
public static ApiClient DefaultApiClient = new ApiClient();
/// <summary>
/// Gets or sets the username (HTTP basic authentication).
/// </summary>
/// <value>The username.</value>
public static String Username { get; set; }
/// <summary>
/// Gets or sets the password (HTTP basic authentication).
/// </summary>
/// <value>The password.</value>
public static String Password { get; set; }
/// <summary>
/// Gets or sets the API key based on the authentication name.
/// </summary>
/// <value>The API key.</value>
public static Dictionary<String, String> ApiKey = new Dictionary<String, String>();
/// <summary>
/// Gets or sets the prefix (e.g. Token) of the API key based on the authentication name.
/// </summary>
/// <value>The prefix of the API key.</value>
public static Dictionary<String, String> ApiKeyPrefix = new Dictionary<String, String>();
private static string _tempFolderPath = Path.GetTempPath();
/// <summary>
/// Gets or sets the temporary folder path to store the files downloaded from the server.
/// </summary>
/// <value>Folder path.</value>
public static String TempFolderPath
{
get { return _tempFolderPath; }
set
{
if (String.IsNullOrEmpty(value))
{
_tempFolderPath = value;
return;
}
// create the directory if it does not exist
if (!Directory.Exists(value))
Directory.CreateDirectory(value);
// check if the path contains directory separator at the end
if (value[value.Length - 1] == Path.DirectorySeparatorChar)
_tempFolderPath = value;
else
_tempFolderPath = value + Path.DirectorySeparatorChar;
}
}
/// <summary>
/// Returns a string with essential information for debugging.
/// </summary>
public static String ToDebugReport()
{
String report = "C# SDK ({{packageName}}) Debug Report:\n";
report += " OS: " + Environment.OSVersion + "\n";
report += " .NET Framework Version: " + Assembly
.GetExecutingAssembly()
.GetReferencedAssemblies()
.Where(x => x.Name == "System.Core").First().Version.ToString() + "\n";
report += " Version of the API: {{version}}\n";
report += " SDK Package Version: {{packageVersion}}\n";
return report;
}
}
}

View File

@ -0,0 +1,10 @@
# Csharp-DotNet2
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.
## 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

@ -0,0 +1,127 @@
using System;
using System.IO;
using System.Collections.Generic;
using RestSharp;
using {{packageName}}.Client;
{{#hasImport}}using {{packageName}}.Model;
{{/hasImport}}
namespace {{packageName}}.Api
{
{{#operations}}
public interface I{{classname}}
{
{{#operation}}
/// <summary>
/// {{summary}} {{notes}}
/// </summary>
{{#allParams}}/// <param name="{{paramName}}">{{description}}</param>
{{/allParams}}/// <returns>{{#returnType}}{{{returnType}}}{{/returnType}}</returns>
{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/operation}}
}
/// <summary>
/// Represents a collection of functions to interact with the API endpoints
/// </summary>
public class {{classname}} : I{{classname}}
{
/// <summary>
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
/// </summary>
/// <param name="apiClient"> an instance of ApiClient (optional)</param>
/// <returns></returns>
public {{classname}}(ApiClient apiClient = null)
{
if (apiClient == null) // use the default one in Configuration
this.ApiClient = Configuration.DefaultApiClient;
else
this.ApiClient = apiClient;
}
/// <summary>
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
/// </summary>
/// <returns></returns>
public {{classname}}(String basePath)
{
this.ApiClient = new ApiClient(basePath);
}
/// <summary>
/// Sets the base path of the API client.
/// </summary>
/// <param name="basePath">The base path</param>
/// <value>The base path</value>
public void SetBasePath(String basePath)
{
this.ApiClient.BasePath = basePath;
}
/// <summary>
/// Gets the base path of the API client.
/// </summary>
/// <param name="basePath">The base path</param>
/// <value>The base path</value>
public String GetBasePath(String basePath)
{
return this.ApiClient.BasePath;
}
/// <summary>
/// Gets or sets the API client.
/// </summary>
/// <value>An instance of the ApiClient</param>
public ApiClient ApiClient {get; set;}
{{#operation}}
/// <summary>
/// {{summary}} {{notes}}
/// </summary>
{{#allParams}}/// <param name="{{paramName}}">{{description}}</param>
{{/allParams}}/// <returns>{{#returnType}}{{{returnType}}}{{/returnType}}</returns>
public {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
{
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set
if ({{paramName}} == null) throw new ApiException(400, "Missing required parameter '{{paramName}}' when calling {{nickname}}");
{{/required}}{{/allParams}}
var path = "{{path}}";
path = path.Replace("{format}", "json");
{{#pathParams}}path = path.Replace("{" + "{{baseName}}" + "}", ApiClient.ParameterToString({{{paramName}}}));
{{/pathParams}}
var queryParams = new Dictionary<String, String>();
var headerParams = new Dictionary<String, String>();
var formParams = new Dictionary<String, String>();
var fileParams = new Dictionary<String, FileParameter>();
String postBody = null;
{{#queryParams}} if ({{paramName}} != null) queryParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // query parameter
{{/queryParams}}
{{#headerParams}} if ({{paramName}} != null) headerParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // header parameter
{{/headerParams}}
{{#formParams}}if ({{paramName}} != null) {{#isFile}}fileParams.Add("{{baseName}}", ApiClient.ParameterToFile("{{baseName}}", {{paramName}}));{{/isFile}}{{^isFile}}formParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // form parameter{{/isFile}}
{{/formParams}}
{{#bodyParam}}postBody = ApiClient.Serialize({{paramName}}); // http body (model) parameter
{{/bodyParam}}
// authentication setting, if any
String[] authSettings = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
// make the HTTP request
IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, authSettings);
if (((int)response.StatusCode) >= 400)
throw new ApiException ((int)response.StatusCode, "Error calling {{nickname}}: " + response.Content, response.Content);
else if (((int)response.StatusCode) == 0)
throw new ApiException ((int)response.StatusCode, "Error calling {{nickname}}: " + response.ErrorMessage, response.ErrorMessage);
{{#returnType}}return ({{{returnType}}}) ApiClient.Deserialize(response.Content, typeof({{{returnType}}}), response.Headers);{{/returnType}}{{^returnType}}return;{{/returnType}}
}
{{/operation}}
}
{{/operations}}
}

View File

@ -0,0 +1,12 @@
wget -nc https://nuget.org/nuget.exe;
mozroots --import --sync
mono nuget.exe install vendor/packages.config -o vendor;
mkdir -p bin;
mcs -sdk:2 -r:vendor/Newtonsoft.Json.7.0.1/lib/net20/Newtonsoft.Json.dll,\
vendor/RestSharp.Net2.1.1.11/lib/net20/RestSharp.Net2.dll,\
System.Runtime.Serialization.dll \
-target:library \
-out:bin/{{packageName}}.dll \
-recurse:src/*.cs \
-doc:bin/{{packageName}}.xml \
-platform:anycpu

View File

@ -0,0 +1,53 @@
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using Newtonsoft.Json;
{{#models}}
{{#model}}
namespace {{packageName}}.Model {
/// <summary>
/// {{description}}
/// </summary>
[DataContract]
public class {{classname}}{{#parent}} : {{{parent}}}{{/parent}} {
{{#vars}}
/// <summary>
/// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}}
/// </summary>{{#description}}
/// <value>{{{description}}}</value>{{/description}}
[DataMember(Name="{{baseName}}", EmitDefaultValue=false)]
[JsonProperty(PropertyName = "{{baseName}}")]
public {{{datatype}}} {{name}} { get; set; }
{{/vars}}
/// <summary>
/// Get the string presentation of the object
/// </summary>
/// <returns>String presentation of the object</returns>
public override string ToString() {
var sb = new StringBuilder();
sb.Append("class {{classname}} {\n");
{{#vars}}
sb.Append(" {{name}}: ").Append({{name}}).Append("\n");
{{/vars}}
sb.Append("}\n");
return sb.ToString();
}
/// <summary>
/// Get the JSON string presentation of the object
/// </summary>
/// <returns>JSON string presentation of the object</returns>
public {{#parent}} new {{/parent}}string ToJson() {
return JsonConvert.SerializeObject(this, Formatting.Indented);
}
}
{{/model}}
{{/models}}
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="RestSharp.Net2" version="1.1.11" targetFramework="net20" developmentDependency="true" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net20" developmentDependency="true" />
</packages>

View File

@ -356,7 +356,7 @@ public class ApiClient {
} }
else if(String.class.equals(cls)) { else if(String.class.equals(cls)) {
if(json != null && json.startsWith("\"") && json.endsWith("\"") && json.length() > 1) 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 else
return json; return json;
} }

View File

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

View File

@ -0,0 +1,8 @@
# Swagger Inflector
Run with
```
mvn package jetty:run
``

View File

@ -0,0 +1,27 @@
package {{invokerPackage}};
import io.swagger.inflector.models.RequestContext;
import io.swagger.inflector.models.ResponseContext;
import javax.ws.rs.core.Response.Status;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import java.io.File;
import java.util.List;
import {{modelPackage}}.*;
{{#imports}}import {{import}};
{{/imports}}
{{#operations}}
public class {{classname}} {
{{#operation}}
public ResponseContext {{nickname}}(RequestContext request {{#allParams}},{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{/allParams}})
{
return new ResponseContext().status(Status.INTERNAL_SERVER_ERROR).entity( "Not implemented" );
}
{{/operation}}
}
{{/operations}}

View File

@ -0,0 +1 @@
{{#isBodyParam}}{{{dataType}}} {{paramName}}{{/isBodyParam}}

View File

@ -0,0 +1 @@
{{#isFormParam}}{{#notFile}}{{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}FormDataContentDisposition fileDetail{{/isFile}}{{/isFormParam}}

View File

@ -0,0 +1 @@
{{#isHeaderParam}}{{{dataType}}} {{paramName}}{{/isHeaderParam}}

View File

@ -0,0 +1,6 @@
controllerPackage: {{invokerPackage}}
modelPackage: {{modelPackage}}
swaggerUrl: ./src/main/swagger/swagger.json
modelMappings:
{{#models}}{{#model}}{{classname}} : {{modelPackage}}.{{classname}}{{/model}}
{{/models}}

View File

@ -0,0 +1,51 @@
package {{package}};
{{#imports}}import {{import}};
{{/imports}}
import io.swagger.annotations.*;
import com.fasterxml.jackson.annotation.JsonProperty;
{{#models}}
{{#model}}{{#description}}
/**
* {{description}}
**/{{/description}}
@ApiModel(description = "{{{description}}}")
public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {
{{#vars}}{{#isEnum}}
public enum {{datatypeWithEnum}} {
{{#allowableValues}}{{#values}} {{.}}, {{/values}}{{/allowableValues}}
};
private {{{datatypeWithEnum}}} {{name}} = {{{defaultValue}}};{{/isEnum}}{{^isEnum}}
private {{{datatype}}} {{name}} = {{{defaultValue}}};{{/isEnum}}{{/vars}}
{{#vars}}
/**{{#description}}
* {{{description}}}{{/description}}{{#minimum}}
* minimum: {{minimum}}{{/minimum}}{{#maximum}}
* maximum: {{maximum}}{{/maximum}}
**/
@ApiModelProperty({{#required}}required = {{required}}, {{/required}}value = "{{{description}}}")
@JsonProperty("{{name}}")
public {{{datatypeWithEnum}}} {{getter}}() {
return {{name}};
}
public void {{setter}}({{{datatypeWithEnum}}} {{name}}) {
this.{{name}} = {{name}};
}
{{/vars}}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class {{classname}} {\n");
{{#parent}}sb.append(" " + super.toString()).append("\n");{{/parent}}
{{#vars}}sb.append(" {{name}}: ").append({{name}}).append("\n");
{{/vars}}sb.append("}\n");
return sb.toString();
}
}
{{/model}}
{{/models}}

View File

@ -0,0 +1 @@
{{#isPathParam}}{{{dataType}}} {{paramName}}{{/isPathParam}}

View File

@ -0,0 +1,174 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.sonatype.oss</groupId>
<artifactId>oss-parent</artifactId>
<version>5</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>{{groupId}}</groupId>
<artifactId>{{artifactId}}</artifactId>
<packaging>jar</packaging>
<name>{{artifactId}}</name>
<version>{{artifactVersion}}</version>
<prerequisites>
<maven>2.2.0</maven>
</prerequisites>
<build>
<defaultGoal>install</defaultGoal>
<directory>target</directory>
<finalName>${project.artifactId}-${project.version}</finalName>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<excludes>
<exclude>**/logback.xml</exclude>
</excludes>
<archive>
<manifestEntries>
<mode>development</mode>
<url>${project.url}</url>
<implementation-version>${project.version}</implementation-version>
<package>io.swagger</package>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty-version}</version>
<configuration>
<monitoredDirName>.</monitoredDirName>
<scanTargets>
<scanTarget>inflector.yaml</scanTarget>
<scanTarget>src/main/swagger/swagger.yaml</scanTarget>
</scanTargets>
<scanIntervalSeconds>1</scanIntervalSeconds>
<webApp>
<contextPath>/</contextPath>
</webApp>
<httpConnector>
<port>8080</port>
<idleTimeout>60000</idleTimeout>
</httpConnector>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- JSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
<version>${jackson-version}</version>
</dependency>
<!-- Jersey -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>${jersey2-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>${jersey2-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey2-version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet-api-version}</version>
<scope>provided</scope>
</dependency>
<!-- Logging -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback-version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-ext</artifactId>
<version>${slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-version}</version>
</dependency>
<!-- Utils -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons-lang-version}</version>
</dependency>
<!-- http client -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-inflector</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
<properties>
<maven-plugin-version>1.0.0</maven-plugin-version>
<swagger-core-version>1.5.0</swagger-core-version>
<swagger-parser-version>1.0.8</swagger-parser-version>
<jackson-version>2.4.2</jackson-version>
<joda-time-version>2.2</joda-time-version>
<joda-version>1.2</joda-version>
<jetty-version>9.2.9.v20150224</jetty-version>
<jersey2-version>2.6</jersey2-version>
<servlet-api-version>2.5</servlet-api-version>
<commons-io-version>2.4</commons-io-version>
<commons-lang-version>2.4</commons-lang-version>
<commons-csv-version>1.1</commons-csv-version>
<logback-version>1.0.1</logback-version>
<junit-version>4.8.2</junit-version>
<slf4j-version>1.6.3</slf4j-version>
</properties>
</project>

View File

@ -0,0 +1 @@
{{#isQueryParam}}{{{dataType}}} {{paramName}}{{/isQueryParam}}

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:j2ee="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>swagger-inflector</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>io.swagger.inflector.SwaggerInflector</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>swagger-inflector</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>CORSFilter</filter-name>
<filter-class>io.swagger.inflector.utils.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CORSFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

View File

@ -1,8 +1,10 @@
io.swagger.codegen.languages.AndroidClientCodegen io.swagger.codegen.languages.AndroidClientCodegen
io.swagger.codegen.languages.AsyncScalaClientCodegen io.swagger.codegen.languages.AsyncScalaClientCodegen
io.swagger.codegen.languages.CSharpClientCodegen io.swagger.codegen.languages.CSharpClientCodegen
io.swagger.codegen.languages.FlashClientCodegen
io.swagger.codegen.languages.JavaClientCodegen io.swagger.codegen.languages.JavaClientCodegen
io.swagger.codegen.languages.JaxRSServerCodegen io.swagger.codegen.languages.JaxRSServerCodegen
io.swagger.codegen.languages.JavaInflectorServerCodegen
io.swagger.codegen.languages.NodeJSServerCodegen io.swagger.codegen.languages.NodeJSServerCodegen
io.swagger.codegen.languages.ObjcClientCodegen io.swagger.codegen.languages.ObjcClientCodegen
io.swagger.codegen.languages.PerlClientCodegen io.swagger.codegen.languages.PerlClientCodegen
@ -26,3 +28,4 @@ io.swagger.codegen.languages.TizenClientCodegen
io.swagger.codegen.languages.TypeScriptAngularClientCodegen io.swagger.codegen.languages.TypeScriptAngularClientCodegen
io.swagger.codegen.languages.TypeScriptNodeClientCodegen io.swagger.codegen.languages.TypeScriptNodeClientCodegen
io.swagger.codegen.languages.AkkaScalaClientCodegen io.swagger.codegen.languages.AkkaScalaClientCodegen
io.swagger.codegen.languages.CsharpDotNet2ClientCodegen

View File

@ -6,11 +6,11 @@
module {{package}} { module {{package}} {
'use strict'; 'use strict';
{{#description}} {{#description}}
/** /**
* {{&description}} * {{&description}}
*/ */
{{/description}} {{/description}}
export class {{classname}} { export class {{classname}} {
private basePath = '{{contextPath}}'; private basePath = '{{contextPath}}';
@ -21,24 +21,37 @@ module {{package}} {
this.basePath = basePath; this.basePath = basePath;
} }
} }
{{#operation}} {{#operation}}
public {{nickname}} ({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}extraHttpRequestParams?: any ) : ng.IHttpPromise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}{}{{/returnType}}> { public {{nickname}} ({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}extraHttpRequestParams?: any ) : ng.IHttpPromise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}{}{{/returnType}}> {
var path = this.basePath + '{{path}}'; var path = this.basePath + '{{path}}';
{{#pathParams}}
{{#pathParams}}
path = path.replace('{' + '{{paramName}}' + '}', String({{paramName}})); path = path.replace('{' + '{{paramName}}' + '}', String({{paramName}}));
{{/pathParams}}
{{/pathParams}}
var queryParameters: any = {}; var queryParameters: any = {};
var headerParams: any = {}; var headerParams: any = {};
{{#allParams}}{{#required}}
{{#allParams}}
{{#required}}
// verify required parameter '{{paramName}}' is set // verify required parameter '{{paramName}}' is set
if (!{{paramName}}) { if (!{{paramName}}) {
throw new Error('Missing required parameter {{paramName}} when calling {{nickname}}'); throw new Error('Missing required parameter {{paramName}} when calling {{nickname}}');
} }
{{/required}}{{/allParams}}
{{#queryParams}}if ({{paramName}} !== undefined) { {{/required}}
{{/allParams}}
{{#queryParams}}
if ({{paramName}} !== undefined) {
queryParameters['{{paramName}}'] = {{paramName}}; queryParameters['{{paramName}}'] = {{paramName}};
}{{/queryParams}} }
{{#headerParams}}headerParams['{{paramName}}'] = {{paramName}};{{/headerParams}}
{{/queryParams}}
{{#headerParams}}
headerParams['{{paramName}}'] = {{paramName}};
{{/headerParams}}
var httpRequestParams: any = { var httpRequestParams: any = {
method: '{{httpMethod}}', method: '{{httpMethod}}',
url: path, url: path,
@ -59,7 +72,7 @@ module {{package}} {
return this.$http(httpRequestParams); return this.$http(httpRequestParams);
} }
{{/operation}} {{/operation}}
} }
} }
{{/operations}} {{/operations}}

View File

@ -1,59 +1,230 @@
import request = require('request');
import promise = require('bluebird');
import http = require('http');
// ===============================================
// This file is autogenerated - Please do not edit
// ===============================================
/* tslint:disable:no-unused-variable */ /* tslint:disable:no-unused-variable */
{{#operations}} {{#models}}
{{#model}}
{{#description}}
/**
* {{{description}}}
*/
{{/description}}
export class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{
{{#vars}}
{{#description}} {{#description}}
/** /**
* {{&description}} * {{{description}}}
*/ */
{{/description}}
{{name}}: {{#isEnum}}{{classname}}.{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}};
{{/vars}}
}
{{#hasEnums}}
export module {{classname}} {
{{#vars}}
{{#isEnum}}
export enum {{datatypeWithEnum}} { {{#allowableValues}}{{#values}}
{{.}} = <any> '{{.}}',{{/values}}{{/allowableValues}}
}
{{/isEnum}}
{{/vars}}
}
{{/hasEnums}}
{{/model}}
{{/models}}
interface Authentication {
/**
* Apply authentication settings to header and query params.
*/
applyToRequest(requestOptions: request.Options): void;
}
class HttpBasicAuth implements Authentication {
public username: string;
public password: string;
applyToRequest(requestOptions: request.Options): void {
requestOptions.auth = {
username: this.username, password: this.password
}
}
}
class ApiKeyAuth implements Authentication {
public apiKey: string;
constructor(private location: string, private paramName: string) {
}
applyToRequest(requestOptions: request.Options): void {
if (this.location == "query") {
(<any>requestOptions.qs)[this.paramName] = this.apiKey;
} else if (this.location == "header") {
requestOptions.headers[this.paramName] = this.apiKey;
}
}
}
class OAuth implements Authentication {
applyToRequest(requestOptions: request.Options): void {
// TODO: support oauth
}
}
class VoidAuth implements Authentication {
public username: string;
public password: string;
applyToRequest(requestOptions: request.Options): void {
// Do nothing
}
}
{{#apiInfo}}
{{#apis}}
{{#operations}}
{{#description}}
/**
* {{&description}}
*/
{{/description}} {{/description}}
export class {{classname}} { export class {{classname}} {
private basePath = '{{contextPath}}'; private basePath = '{{contextPath}}';
public authentications = {
'default': <Authentication>new VoidAuth(),
{{#authMethods}}
{{#isBasic}}
'{{name}}': new HttpBasicAuth(),
{{/isBasic}}
{{#isApiKey}}
'{{name}}': new ApiKeyAuth({{#isKeyInHeader}}'header'{{/isKeyInHeader}}{{^isKeyInHeader}}'query'{{/isKeyInHeader}}, '{{keyParamName}}'),
{{/isApiKey}}
{{#isOAuth}}
'{{name}}': new OAuth(),
{{/isOAuth}}
{{/authMethods}}
}
constructor(private url: string, private username: string, private password: string, basePath?: string) { constructor(url: string, basePath?: string);
{{#authMethods}}
{{#isBasic}}
constructor(url: string, username: string, password: string, basePath?: string);
{{/isBasic}}
{{/authMethods}}
constructor(private url: string, basePathOrUsername: string, password?: string, basePath?: string) {
if (password) {
{{#authMethods}}
{{#isBasic}}
this.username = basePathOrUsername;
this.password = password
{{/isBasic}}
{{/authMethods}}
if (basePath) { if (basePath) {
this.basePath = basePath; this.basePath = basePath;
} }
} else {
if (basePathOrUsername) {
this.basePath = basePathOrUsername
}
}
}
{{#authMethods}}
{{#isBasic}}
set username(username: string) {
this.authentications.{{name}}.username = username;
} }
{{#operation}} set password(password: string) {
this.authentications.{{name}}.password = password;
}
{{/isBasic}}
{{#isApiKey}}
set apiKey(key: string) {
this.authentications.{{name}}.apiKey = key;
}
{{/isApiKey}}
{{#isOAuth}}
{{/isOAuth}}
{{/authMethods}}
{{#operation}}
public {{nickname}} ({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) : Promise<{ response: http.ClientResponse; {{#returnType}}body: {{{returnType}}}; {{/returnType}} }> { public {{nickname}} ({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) : Promise<{ response: http.ClientResponse; {{#returnType}}body: {{{returnType}}}; {{/returnType}} }> {
var path = this.url + this.basePath + '{{path}}'; var path = this.url + this.basePath + '{{path}}';
{{#pathParams}} {{#pathParams}}
path = path.replace('{' + '{{paramName}}' + '}', String({{paramName}})); path = path.replace('{' + '{{paramName}}' + '}', String({{paramName}}));
{{/pathParams}}
{{/pathParams}}
var queryParameters: any = {}; var queryParameters: any = {};
var headerParams: any = {}; var headerParams: any = {};
var formParams: any = {};
{{#allParams}}{{#required}} {{#allParams}}
{{#required}}
// verify required parameter '{{paramName}}' is set // verify required parameter '{{paramName}}' is set
if (!{{paramName}}) { if (!{{paramName}}) {
throw new Error('Missing required parameter {{paramName}} when calling {{nickname}}'); throw new Error('Missing required parameter {{paramName}} when calling {{nickname}}');
} }
{{/required}}{{/allParams}}
{{#queryParams}}if ({{paramName}} !== undefined) { {{/required}}
{{/allParams}}
{{#queryParams}}
if ({{paramName}} !== undefined) {
queryParameters['{{paramName}}'] = {{paramName}}; queryParameters['{{paramName}}'] = {{paramName}};
} }
{{/queryParams}}
{{#headerParams}}headerParams['{{paramName}}'] = {{paramName}}; {{/queryParams}}
{{/headerParams}} {{#headerParams}}
headerParams['{{paramName}}'] = {{paramName}};
{{/headerParams}}
var useFormData = false;
{{#formParams}}
if ({{paramName}} !== undefined) {
formParams['{{paramName}}'] = {{paramName}};
}
{{#isFile}}
useFormData = true;
{{/isFile}}
{{/formParams}}
var deferred = promise.defer<{ response: http.ClientResponse; {{#returnType}}body: {{{returnType}}}; {{/returnType}} }>(); var deferred = promise.defer<{ response: http.ClientResponse; {{#returnType}}body: {{{returnType}}}; {{/returnType}} }>();
request({ var requestOptions: request.Options = {
method: '{{httpMethod}}', method: '{{httpMethod}}',
qs: queryParameters, qs: queryParameters,
headers: headerParams,
uri: path, uri: path,
json: true, json: true,
{{#bodyParam}}body: {{paramName}}, {{#bodyParam}}
{{/bodyParam}} body: {{paramName}},
auth: { {{/bodyParam}}
username: this.username, password: this.password
} }
}, (error, response, body) => {
{{#authMethods}}
this.authentications.{{name}}.applyToRequest(requestOptions);
{{/authMethods}}
this.authentications.default.applyToRequest(requestOptions);
if (Object.keys(formParams).length) {
if (useFormData) {
(<any>requestOptions).formData = formParams;
} else {
requestOptions.form = formParams;
}
}
request(requestOptions, (error, response, body) => {
if (error) { if (error) {
deferred.reject(error); deferred.reject(error);
} else { } else {
@ -67,7 +238,8 @@ export class {{classname}} {
return deferred.promise; return deferred.promise;
} }
{{/operation}}
{{/operation}}
} }
{{/operations}} {{/operations}}
{{/apis}}
{{/apiInfo}}

View File

@ -1,33 +0,0 @@
{{#models}}
{{#model}}
{{#description}}
/**
* {{{description}}}
*/
{{/description}}
export class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{
{{#vars}}
{{#description}}
/**
* {{{description}}}
*/
{{/description}}
{{name}}: {{#isEnum}}{{classname}}.{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}};
{{/vars}}
}
{{#hasEnums}}
export module {{classname}} {
{{#vars}}
{{#isEnum}}
export enum {{datatypeWithEnum}} { {{#allowableValues}}{{#values}}
{{.}} = <any> '{{.}}',{{/values}}{{/allowableValues}}
}
{{/isEnum}}
{{/vars}}
}
{{/hasEnums}}
{{/model}}
{{/models}}

View File

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

View File

@ -154,7 +154,7 @@ namespace {{packageName}}.Client
/// <returns>Escaped string.</returns> /// <returns>Escaped string.</returns>
public string EscapeString(string str) public string EscapeString(string str)
{ {
return HttpUtility.UrlEncode(str); return RestSharp.Contrib.HttpUtility.UrlEncode(str);
} }
/// <summary> /// <summary>
@ -235,7 +235,7 @@ namespace {{packageName}}.Client
{ {
return JsonConvert.DeserializeObject(content, type); return JsonConvert.DeserializeObject(content, type);
} }
catch (IOException e) catch (Exception e)
{ {
throw new ApiException(500, e.Message); throw new ApiException(500, e.Message);
} }

View File

@ -104,11 +104,11 @@ namespace {{packageName}}.Api
String postBody = null; String postBody = null;
pathParams.Add("format", "json"); pathParams.Add("format", "json");
{{#pathParams}} if ({{paramName}} != null) pathParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // path parameter {{#pathParams}}if ({{paramName}} != null) pathParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // path parameter
{{/pathParams}} {{/pathParams}}
{{#queryParams}} if ({{paramName}} != null) queryParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // query parameter {{#queryParams}}if ({{paramName}} != null) queryParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // query parameter
{{/queryParams}} {{/queryParams}}
{{#headerParams}} if ({{paramName}} != null) headerParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // header parameter {{#headerParams}}if ({{paramName}} != null) headerParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // header parameter
{{/headerParams}} {{/headerParams}}
{{#formParams}}if ({{paramName}} != null) {{#isFile}}fileParams.Add("{{baseName}}", ApiClient.ParameterToFile("{{baseName}}", {{paramName}}));{{/isFile}}{{^isFile}}formParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // form parameter{{/isFile}} {{#formParams}}if ({{paramName}} != null) {{#isFile}}fileParams.Add("{{baseName}}", ApiClient.ParameterToFile("{{baseName}}", {{paramName}}));{{/isFile}}{{^isFile}}formParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // form parameter{{/isFile}}
{{/formParams}} {{/formParams}}
@ -150,11 +150,11 @@ namespace {{packageName}}.Api
String postBody = null; String postBody = null;
pathParams.Add("format", "json"); pathParams.Add("format", "json");
{{#pathParams}} if ({{paramName}} != null) pathParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // path parameter {{#pathParams}}if ({{paramName}} != null) pathParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // path parameter
{{/pathParams}} {{/pathParams}}
{{#queryParams}} if ({{paramName}} != null) queryParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // query parameter {{#queryParams}}if ({{paramName}} != null) queryParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // query parameter
{{/queryParams}} {{/queryParams}}
{{#headerParams}} if ({{paramName}} != null) headerParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // header parameter {{#headerParams}}if ({{paramName}} != null) headerParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // header parameter
{{/headerParams}} {{/headerParams}}
{{#formParams}}if ({{paramName}} != null) {{#isFile}}fileParams.Add("{{baseName}}", ApiClient.ParameterToFile("{{baseName}}", {{paramName}}));{{/isFile}}{{^isFile}}formParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // form parameter{{/isFile}} {{#formParams}}if ({{paramName}} != null) {{#isFile}}fileParams.Add("{{baseName}}", ApiClient.ParameterToFile("{{baseName}}", {{paramName}}));{{/isFile}}{{^isFile}}formParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // form parameter{{/isFile}}
{{/formParams}} {{/formParams}}

View File

@ -56,7 +56,7 @@ public class {{classname}} extends SwaggerApi {
{{#headerParams}}headerParams["{{paramName}}"] = toPathValue({{paramName}}); {{#headerParams}}headerParams["{{paramName}}"] = toPathValue({{paramName}});
{{/headerParams}} {{/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(); var requestId: String = getUniqueId();

View File

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

View File

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

View File

@ -1,7 +1,5 @@
#import "{{classPrefix}}ApiClient.h" #import "{{classPrefix}}ApiClient.h"
@implementation {{classPrefix}}ApiClient
NSString *const {{classPrefix}}ResponseObjectErrorKey = @"{{classPrefix}}ResponseObject"; NSString *const {{classPrefix}}ResponseObjectErrorKey = @"{{classPrefix}}ResponseObject";
static long requestId = 0; static long requestId = 0;
@ -9,9 +7,49 @@ static bool offlineState = false;
static NSMutableSet * queuedRequests = nil; static NSMutableSet * queuedRequests = nil;
static bool cacheEnabled = false; static bool cacheEnabled = false;
static AFNetworkReachabilityStatus reachabilityStatus = AFNetworkReachabilityStatusNotReachable; static AFNetworkReachabilityStatus reachabilityStatus = AFNetworkReachabilityStatusNotReachable;
static NSOperationQueue* sharedQueue;
static void (^reachabilityChangeBlock)(int); 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 #pragma mark - Log Methods
- (void)logResponse:(AFHTTPRequestOperation *)operation - (void)logResponse:(AFHTTPRequestOperation *)operation
@ -34,16 +72,10 @@ static void (^reachabilityChangeBlock)(int);
#pragma mark - Cache Methods #pragma mark - Cache Methods
+ (void) setCacheEnabled:(BOOL)enabled {
cacheEnabled = enabled;
}
+(void)clearCache { +(void)clearCache {
[[NSURLCache sharedURLCache] removeAllCachedResponses]; [[NSURLCache sharedURLCache] removeAllCachedResponses];
} }
#pragma mark -
+(void)configureCacheWithMemoryAndDiskCapacity: (unsigned long) memorySize +(void)configureCacheWithMemoryAndDiskCapacity: (unsigned long) memorySize
diskSize: (unsigned long) diskSize { diskSize: (unsigned long) diskSize {
NSAssert(memorySize > 0, @"invalid in-memory cache size"); NSAssert(memorySize > 0, @"invalid in-memory cache size");
@ -58,43 +90,7 @@ static void (^reachabilityChangeBlock)(int);
[NSURLCache setSharedURLCache:cache]; [NSURLCache setSharedURLCache:cache];
} }
+(NSOperationQueue*) sharedQueue { #pragma mark - Utility Methods
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;
}
}
/* /*
* Detect `Accept` from accepts * Detect `Accept` from accepts
@ -141,11 +137,23 @@ static void (^reachabilityChangeBlock)(int);
} }
} }
-(void)setHeaderValue:(NSString*) value + (NSString*)escape:(id)unescaped {
forKey:(NSString*) forKey { if([unescaped isKindOfClass:[NSString class]]){
[self.requestSerializer setValue:value forHTTPHeaderField:forKey]; return (NSString *)CFBridgingRelease
(CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef) unescaped,
NULL,
(CFStringRef)@"!*'();:@&=+$,/?%#[]",
kCFStringEncodingUTF8));
}
else {
return [NSString stringWithFormat:@"%@", unescaped];
}
} }
#pragma mark - Request Methods
+(unsigned long)requestQueueSize { +(unsigned long)requestQueueSize {
return [queuedRequests count]; return [queuedRequests count];
} }
@ -171,46 +179,28 @@ static void (^reachabilityChangeBlock)(int);
[queuedRequests removeObject:requestId]; [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 { -(Boolean) executeRequestWithId:(NSNumber*) requestId {
NSSet* matchingItems = [queuedRequests objectsPassingTest:^BOOL(id obj, BOOL *stop) { NSSet* matchingItems = [queuedRequests objectsPassingTest:^BOOL(id obj, BOOL *stop) {
if([obj intValue] == [requestId intValue]) if([obj intValue] == [requestId intValue]) {
return TRUE; return YES;
else return FALSE; }
else {
return NO;
}
}]; }];
if(matchingItems.count == 1) { if(matchingItems.count == 1) {
if([[{{classPrefix}}Configuration sharedConfig] debug]) if([[{{classPrefix}}Configuration sharedConfig] debug])
NSLog(@"removing request id %@", requestId); NSLog(@"removing request id %@", requestId);
[queuedRequests removeObject:requestId]; [queuedRequests removeObject:requestId];
return true; return YES;
}
else {
return NO;
} }
else
return false;
} }
-(id)initWithBaseURL:(NSURL *)url { #pragma mark - Reachability Methods
self = [super initWithBaseURL:url];
self.requestSerializer = [AFJSONRequestSerializer serializer];
self.responseSerializer = [AFJSONResponseSerializer serializer];
if (!self)
return nil;
return self;
}
+(AFNetworkReachabilityStatus) getReachabilityStatus { +(AFNetworkReachabilityStatus) getReachabilityStatus {
return reachabilityStatus; return reachabilityStatus;
@ -220,12 +210,8 @@ static void (^reachabilityChangeBlock)(int);
reachabilityChangeBlock = changeBlock; reachabilityChangeBlock = changeBlock;
} }
+(void) setOfflineState:(BOOL) state { - (void) configureCacheReachibility {
offlineState = state; [self.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
}
+(void) configureCacheReachibilityForHost:(NSString*)host {
[[{{classPrefix}}ApiClient sharedClientFromPool:host].reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
reachabilityStatus = status; reachabilityStatus = status;
switch (status) { switch (status) {
case AFNetworkReachabilityStatusUnknown: case AFNetworkReachabilityStatusUnknown:
@ -254,99 +240,14 @@ static void (^reachabilityChangeBlock)(int);
default: default:
break; break;
} }
// call the reachability block, if configured // call the reachability block, if configured
if(reachabilityChangeBlock != nil) { if(reachabilityChangeBlock != nil) {
reachabilityChangeBlock(status); reachabilityChangeBlock(status);
} }
}]; }];
[[{{classPrefix}}ApiClient sharedClientFromPool:host].reachabilityManager startMonitoring];
}
-(NSString*) pathWithQueryParamsToString:(NSString*) path [self.reachabilityManager startMonitoring];
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];
} }
#pragma mark - Deserialize methods #pragma mark - Deserialize methods
@ -356,13 +257,14 @@ static void (^reachabilityChangeBlock)(int);
NSTextCheckingResult *match = nil; NSTextCheckingResult *match = nil;
NSMutableArray *resultArray = nil; NSMutableArray *resultArray = nil;
NSMutableDictionary *resultDict = nil; NSMutableDictionary *resultDict = nil;
NSString *innerType = nil;
// return nil if data is nil or class is nil // return nil if data is nil or class is nil
if (!data || !class) { if (!data || !class) {
return nil; return nil;
} }
// remove "*" from class, if ends with "*" // remove "*" from class, if ends with "*"
if ([class hasSuffix:@"*"]) { if ([class hasSuffix:@"*"]) {
class = [class substringToIndex:[class length] - 1]; class = [class substringToIndex:[class length] - 1];
} }
@ -383,7 +285,7 @@ static void (^reachabilityChangeBlock)(int);
range:NSMakeRange(0, [class length])]; range:NSMakeRange(0, [class length])];
if (match) { if (match) {
NSString *innerType = [class substringWithRange:[match rangeAtIndex:1]]; innerType = [class substringWithRange:[match rangeAtIndex:1]];
resultArray = [NSMutableArray arrayWithCapacity:[data count]]; resultArray = [NSMutableArray arrayWithCapacity:[data count]];
[data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { [data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
@ -395,8 +297,8 @@ static void (^reachabilityChangeBlock)(int);
} }
// list of primitives // list of primitives
NSString *arrayOfPrimitivesPet = @"NSArray"; NSString *arrayOfPrimitivesPat = @"NSArray\\* /\\* (.+) \\*/";
regexp = [NSRegularExpression regularExpressionWithPattern:arrayOfPrimitivesPet regexp = [NSRegularExpression regularExpressionWithPattern:arrayOfPrimitivesPat
options:NSRegularExpressionCaseInsensitive options:NSRegularExpressionCaseInsensitive
error:nil]; error:nil];
match = [regexp firstMatchInString:class match = [regexp firstMatchInString:class
@ -404,16 +306,18 @@ static void (^reachabilityChangeBlock)(int);
range:NSMakeRange(0, [class length])]; range:NSMakeRange(0, [class length])];
if (match) { if (match) {
innerType = [class substringWithRange:[match rangeAtIndex:1]];
resultArray = [NSMutableArray arrayWithCapacity:[data count]]; resultArray = [NSMutableArray arrayWithCapacity:[data count]];
[data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { [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; return resultArray;
} }
// map // map
NSString *dictPat = @"NSDictionary\\* /\\* (.+), (.+) \\*/"; NSString *dictPat = @"NSDictionary\\* /\\* (.+?), (.+) \\*/";
regexp = [NSRegularExpression regularExpressionWithPattern:dictPat regexp = [NSRegularExpression regularExpressionWithPattern:dictPat
options:NSRegularExpressionCaseInsensitive options:NSRegularExpressionCaseInsensitive
error:nil]; error:nil];
@ -433,7 +337,7 @@ static void (^reachabilityChangeBlock)(int);
} }
// primitives // primitives
NSArray *primitiveTypes = @[@"NSString", @"NSDate", @"BOOL", @"NSNumber"]; NSArray *primitiveTypes = @[@"NSString", @"NSDate", @"NSNumber"];
if ([primitiveTypes containsObject:class]) { if ([primitiveTypes containsObject:class]) {
if ([class isEqualToString:@"NSString"]) { if ([class isEqualToString:@"NSString"]) {
@ -442,25 +346,24 @@ static void (^reachabilityChangeBlock)(int);
else if ([class isEqualToString:@"NSDate"]) { else if ([class isEqualToString:@"NSDate"]) {
return [NSDate dateWithISO8601String:data]; 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"]) { else if ([class isEqualToString:@"NSNumber"]) {
// NSNumber from NSNumber // NSNumber from NSNumber
if ([data isKindOfClass:[NSNumber class]]) { if ([data isKindOfClass:[NSNumber class]]) {
return data; 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 // NSNumber from NSString
else { } else {
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterDecimalStyle; formatter.numberStyle = NSNumberFormatterDecimalStyle;
return [formatter numberFromString:data]; return [formatter numberFromString:data];
} }
} }
} }
}
// model // model
Class ModelClass = NSClassFromString(class); Class ModelClass = NSClassFromString(class);
@ -600,7 +503,12 @@ static void (^reachabilityChangeBlock)(int);
[self updateHeaderParams:&headerParams queryParams:&queryParams WithAuthSettings:authSettings]; [self updateHeaderParams:&headerParams queryParams:&queryParams WithAuthSettings:authSettings];
NSMutableURLRequest * request = nil; NSMutableURLRequest * request = nil;
NSString* pathWithQueryParams = [self pathWithQueryParamsToString:path queryParams:queryParams]; NSString* pathWithQueryParams = [self pathWithQueryParamsToString:path queryParams:queryParams];
if ([pathWithQueryParams hasPrefix:@"/"]) {
pathWithQueryParams = [pathWithQueryParams substringFromIndex:1];
}
NSString* urlString = [[NSURL URLWithString:pathWithQueryParams relativeToURL:self.baseURL] absoluteString]; NSString* urlString = [[NSURL URLWithString:pathWithQueryParams relativeToURL:self.baseURL] absoluteString];
if (files.count > 0) { if (files.count > 0) {
request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" request = [self.requestSerializer multipartFormRequestWithMethod:@"POST"
@ -674,8 +582,93 @@ static void (^reachabilityChangeBlock)(int);
return requestId; 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];
}
@end @end

View File

@ -6,10 +6,17 @@
#import "{{classPrefix}}QueryParamCollection.h" #import "{{classPrefix}}QueryParamCollection.h"
#import "{{classPrefix}}Configuration.h" #import "{{classPrefix}}Configuration.h"
/**
* 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.
*/
{{#models}}{{#model}}#import "{{classname}}.h" {{#models}}{{#model}}#import "{{classname}}.h"
{{/model}}{{/models}} {{/model}}{{/models}}
@class {{classPrefix}}Configuration;
/** /**
* A key for `NSError` user info dictionaries. * A key for `NSError` user info dictionaries.
* *
@ -25,77 +32,61 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
@property(nonatomic, readonly) NSOperationQueue* queue; @property(nonatomic, readonly) NSOperationQueue* queue;
/** /**
* Get the Api Client instance from pool * Clears Cache
*
* @param baseUrl The base url of api client.
*
* @return The {{classPrefix}}ApiClient instance.
*/
+({{classPrefix}}ApiClient *)sharedClientFromPool:(NSString *)baseUrl;
/**
* Get the operations queue
*
* @return The `shardQueue` static variable.
*/
+(NSOperationQueue*) sharedQueue;
/**
* Clear Cache
*/ */
+(void)clearCache; +(void)clearCache;
/** /**
* Turn on cache * Turns on cache
* *
* @param enabled If the cached is enable, must be `YES` or `NO` * @param enabled If the cached is enable, must be `YES` or `NO`
*/ */
+(void)setCacheEnabled:(BOOL) enabled; +(void)setCacheEnabled:(BOOL) enabled;
/** /**
* Get the request queue size * Gets the request queue size
* *
* @return The size of `queuedRequests` static variable. * @return The size of `queuedRequests` static variable.
*/ */
+(unsigned long)requestQueueSize; +(unsigned long)requestQueueSize;
/** /**
* Set the client unreachable * Sets the client unreachable
* *
* @param state off line state, must be `YES` or `NO` * @param state off line state, must be `YES` or `NO`
*/ */
+(void) setOfflineState:(BOOL) state; +(void) setOfflineState:(BOOL) state;
/** /**
* Get the client reachability * Gets the client reachability
* *
* @return The client reachability. * @return The client reachability.
*/ */
+(AFNetworkReachabilityStatus) getReachabilityStatus; +(AFNetworkReachabilityStatus) getReachabilityStatus;
/** /**
* Get the next request id * Gets the next request id
* *
* @return The next executed request id. * @return The next executed request id.
*/ */
+(NSNumber*) nextRequestId; +(NSNumber*) nextRequestId;
/** /**
* Generate request id and add it to the queue * Generates request id and add it to the queue
* *
* @return The next executed request id. * @return The next executed request id.
*/ */
+(NSNumber*) queueRequest; +(NSNumber*) queueRequest;
/** /**
* Remove request id from the queue * Removes request id from the queue
* *
* @param requestId The request which will be removed. * @param requestId The request which will be removed.
*/ */
+(void) cancelRequest:(NSNumber*)requestId; +(void) cancelRequest:(NSNumber*)requestId;
/** /**
* URL encode NSString * Gets URL encoded NSString
* *
* @param unescaped The string which will be escaped. * @param unescaped The string which will be escaped.
* *
@ -104,21 +95,19 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
+(NSString*) escape:(id)unescaped; +(NSString*) escape:(id)unescaped;
/** /**
* Customize the behavior when the reachability changed * Customizes the behavior when the reachability changed
* *
* @param changeBlock The block will be executed when the reachability changed. * @param changeBlock The block will be executed when the reachability changed.
*/ */
+(void) setReachabilityChangeBlock:(void(^)(int))changeBlock; +(void) setReachabilityChangeBlock:(void(^)(int))changeBlock;
/** /**
* Set the client reachability strategy * Sets the api client reachability strategy
*
* @param host The host of {{classPrefix}}ApiClient.
*/ */
+(void) configureCacheReachibilityForHost:(NSString*)host; - (void)configureCacheReachibility;
/** /**
* Detect Accept header from accepts NSArray * Detects Accept header from accepts NSArray
* *
* @param accepts NSArray of header * @param accepts NSArray of header
* *
@ -127,7 +116,7 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
+(NSString *) selectHeaderAccept:(NSArray *)accepts; +(NSString *) selectHeaderAccept:(NSArray *)accepts;
/** /**
* Detect Content-Type header from contentTypes NSArray * Detects Content-Type header from contentTypes NSArray
* *
* @param contentTypes NSArray of header * @param contentTypes NSArray of header
* *
@ -136,7 +125,7 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
+(NSString *) selectHeaderContentType:(NSArray *)contentTypes; +(NSString *) selectHeaderContentType:(NSArray *)contentTypes;
/** /**
* Set header for request * Sets header for request
* *
* @param value The header value * @param value The header value
* @param forKey The header key * @param forKey The header key
@ -145,7 +134,7 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
forKey:(NSString*) forKey; forKey:(NSString*) forKey;
/** /**
* Update header parameters and query parameters for authentication * Updates header parameters and query parameters for authentication
* *
* @param headers The header parameter will be udpated, passed by pointer to pointer. * @param headers The header parameter will be udpated, passed by pointer to pointer.
* @param querys The query parameters will be updated, passed by pointer to pointer. * @param querys The query parameters will be updated, passed by pointer to pointer.
@ -156,7 +145,7 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
WithAuthSettings:(NSArray *)authSettings; WithAuthSettings:(NSArray *)authSettings;
/** /**
* Deserialize the given data to Objective-C object. * Deserializes the given data to Objective-C object.
* *
* @param data The data will be deserialized. * @param data The data will be deserialized.
* @param class The type of objective-c object. * @param class The type of objective-c object.
@ -164,7 +153,7 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
- (id) deserialize:(id) data class:(NSString *) class; - (id) deserialize:(id) data class:(NSString *) class;
/** /**
* Logging request and response * Logs request and response
* *
* @param operation AFHTTPRequestOperation for the HTTP request. * @param operation AFHTTPRequestOperation for the HTTP request.
* @param request The HTTP request. * @param request The HTTP request.
@ -175,7 +164,7 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
error:(NSError *)error; error:(NSError *)error;
/** /**
* Perform request * Performs request
* *
* @param path Request url. * @param path Request url.
* @param method Request method. * @param method Request method.

View File

@ -25,6 +25,8 @@
- (instancetype) init { - (instancetype) init {
self = [super init]; self = [super init];
if (self) { if (self) {
self.apiClient = nil;
self.host = @"{{basePath}}";
self.username = @""; self.username = @"";
self.password = @""; self.password = @"";
self.tempFolderPath = nil; self.tempFolderPath = nil;
@ -60,12 +62,20 @@
#pragma mark - Setter Methods #pragma mark - Setter Methods
- (void) setValue:(NSString *)value forApiKeyField:(NSString *)field { - (void) setApiKey:(NSString *)apiKey forApiKeyIdentifier:(NSString *)identifier {
[self.mutableApiKey setValue:value forKey:field]; [self.mutableApiKey setValue:apiKey forKey:identifier];
} }
- (void) setValue:(NSString *)value forApiKeyPrefixField:(NSString *)field { - (void) removeApiKey:(NSString *)identifier {
[self.mutableApiKeyPrefix setValue:value forKey:field]; [self.mutableApiKey removeObjectForKey:identifier];
}
- (void) setApiKeyPrefix:(NSString *)prefix forApiKeyPrefixIdentifier:(NSString *)identifier {
[self.mutableApiKeyPrefix setValue:prefix forKey:identifier];
}
- (void) removeApiKeyPrefix:(NSString *)identifier {
[self.mutableApiKeyPrefix removeObjectForKey:identifier];
} }
- (void) setLoggingFile:(NSString *)loggingFile { - (void) setLoggingFile:(NSString *)loggingFile {
@ -75,10 +85,10 @@
} }
_loggingFile = loggingFile; _loggingFile = loggingFile;
self.loggingFileHanlder = [NSFileHandle fileHandleForWritingAtPath:_loggingFile]; _loggingFileHanlder = [NSFileHandle fileHandleForWritingAtPath:_loggingFile];
if (self.loggingFileHanlder == nil) { if (_loggingFileHanlder == nil) {
[[NSFileManager defaultManager] createFileAtPath:_loggingFile contents:nil attributes:nil]; [[NSFileManager defaultManager] createFileAtPath:_loggingFile contents:nil attributes:nil];
self.loggingFileHanlder = [NSFileHandle fileHandleForWritingAtPath:_loggingFile]; _loggingFileHanlder = [NSFileHandle fileHandleForWritingAtPath:_loggingFile];
} }
} }
@ -96,13 +106,26 @@
- (NSDictionary *) authSettings { - (NSDictionary *) authSettings {
return @{ return @{
@"api_key": @{ {{#authMethods}}
{{#isApiKey}}
@"{{name}}":
@{
@"type": @"api_key", @"type": @"api_key",
@"in": @"header", @"in": {{#isKeyInHeader}}@"header"{{/isKeyInHeader}}{{#isKeyInQuery}}@"query"{{/isKeyInQuery}},
@"key": @"api_key", @"key": @"{{keyParamName}}",
@"value": [self getApiKeyWithPrefix:@"api_key"] @"value": [self getApiKeyWithPrefix:@"{{keyParamName}}"]
}, },
{{/isApiKey}}
{{#isBasic}}
@"{{name}}":
@{
@"type": @"basic",
@"in": @"header",
@"key": @"Authorization",
@"value": [self getBasicAuthToken]
},
{{/isBasic}}
{{/authMethods}}
}; };
} }

View File

@ -1,26 +1,49 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "{{classPrefix}}ApiClient.h"
/** The `{{classPrefix}}Configuration` class manages the configurations for the sdk.
*
* 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.
*/
@class {{classPrefix}}ApiClient;
@interface {{classPrefix}}Configuration : NSObject @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 * Api key values for Api Key type Authentication
* *
* To add or remove api key, use `setValue:forApiKeyField:`. * To add or remove api key, use `setApiKey:forApiKeyIdentifier:`.
*/ */
@property (readonly, nonatomic, strong) NSDictionary *apiKey; @property (readonly, nonatomic, strong) NSDictionary *apiKey;
/** /**
* Api key prefix values to be prepend to the respective api key * Api key prefix values to be prepend to the respective api key
* *
* To add or remove prefix, use `setValue:forApiKeyPrefixField:`. * To add or remove prefix, use `setApiKeyPrefix:forApiKeyPrefixIdentifier:`.
*/ */
@property (readonly, nonatomic, strong) NSDictionary *apiKeyPrefix; @property (readonly, nonatomic, strong) NSDictionary *apiKeyPrefix;
/** /**
* Usename and Password for Basic type Authentication * Usename for HTTP Basic Authentication
*/
@property (nonatomic) NSString *username;
/**
* Password for HTTP Basic Authentication
*/ */
@property (nonatomic) NSString *username;
@property (nonatomic) NSString *password; @property (nonatomic) NSString *password;
/** /**
@ -31,37 +54,74 @@
/** /**
* Logging Settings * Logging Settings
*/ */
@property (nonatomic) BOOL debug;
@property (nonatomic) NSString *loggingFile;
@property (nonatomic) NSFileHandle *loggingFileHanlder;
/** /**
* Get configuration singleton instance * Debug switch, default false
*/
@property (nonatomic) BOOL debug;
/**
* Debug file location, default log in console
*/
@property (nonatomic) NSString *loggingFile;
/**
* Log file handler, this property is used by sdk internally.
*/
@property (nonatomic, readonly) NSFileHandle *loggingFileHanlder;
/**
* Gets configuration singleton instance
*/ */
+ (instancetype) sharedConfig; + (instancetype) sharedConfig;
/** /**
* Sets field in `apiKey` * Sets API key
*
* To remove a apiKey for an identifier, just set the apiKey to nil.
*
* @param apiKey API key or token.
* @param identifier API key identifier (authentication schema).
*
*/ */
- (void) setValue:(NSString *)value forApiKeyField:(NSString*)field; - (void) setApiKey:(NSString *)apiKey forApiKeyIdentifier:(NSString*)identifier;
/** /**
* Sets field in `apiKeyPrefix` * Removes api key
*
* @param identifier API key identifier.
*/ */
- (void) setValue:(NSString *)value forApiKeyPrefixField:(NSString *)field; - (void) removeApiKey:(NSString *)identifier;
/** /**
* Get API key (with prefix if set) * Sets the prefix for API key
*
* To remove a apiKeyPrefix for an identifier, just set the apiKeyPrefix to nil.
*
* @param apiKeyPrefix API key prefix.
* @param identifier API key identifier.
*/
- (void) setApiKeyPrefix:(NSString *)prefix forApiKeyPrefixIdentifier:(NSString *)identifier;
/**
* Removes api key prefix
*
* @param identifier API key identifier.
*/
- (void) removeApiKeyPrefix:(NSString *)identifier;
/**
* Gets API key (with prefix if set)
*/ */
- (NSString *) getApiKeyWithPrefix:(NSString *) key; - (NSString *) getApiKeyWithPrefix:(NSString *) key;
/** /**
* Get Basic Auth token * Gets Basic Auth token
*/ */
- (NSString *) getBasicAuthToken; - (NSString *) getBasicAuthToken;
/** /**
* Get Authentication Setings * Gets Authentication Setings
*/ */
- (NSDictionary *) authSettings; - (NSDictionary *) authSettings;

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" 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 ## Author
{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}} {{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}}

View File

@ -11,14 +11,16 @@
@implementation {{classname}} @implementation {{classname}}
static NSString * basePath = @"{{basePath}}";
#pragma mark - Initialize methods #pragma mark - Initialize methods
- (id) init { - (id) init {
self = [super init]; self = [super init];
if (self) { 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]; self.defaultHeaders = [NSMutableDictionary dictionary];
} }
return self; return self;
@ -27,12 +29,7 @@ static NSString * basePath = @"{{basePath}}";
- (id) initWithApiClient:({{classPrefix}}ApiClient *)apiClient { - (id) initWithApiClient:({{classPrefix}}ApiClient *)apiClient {
self = [super init]; self = [super init];
if (self) { if (self) {
if (apiClient) {
self.apiClient = apiClient; self.apiClient = apiClient;
}
else {
self.apiClient = [{{classPrefix}}ApiClient sharedClientFromPool:basePath];
}
self.defaultHeaders = [NSMutableDictionary dictionary]; self.defaultHeaders = [NSMutableDictionary dictionary];
} }
return self; return self;
@ -50,14 +47,6 @@ static NSString * basePath = @"{{basePath}}";
return singletonAPI; return singletonAPI;
} }
+(void) setBasePath:(NSString*)path {
basePath = path;
}
+(NSString*) getBasePath {
return basePath;
}
-(void) addHeader:(NSString*)value forKey:(NSString*)key { -(void) addHeader:(NSString*)value forKey:(NSString*)key {
[self.defaultHeaders setValue:value forKey:key]; [self.defaultHeaders setValue:value forKey:key];
} }
@ -93,13 +82,14 @@ static NSString * basePath = @"{{basePath}}";
} }
{{/required}}{{/allParams}} {{/required}}{{/allParams}}
NSMutableString* requestUrl = [NSMutableString stringWithFormat:@"%@{{path}}", basePath]; NSMutableString* resourcePath = [NSMutableString stringWithFormat:@"{{path}}"];
// remove format in URL if needed // remove format in URL if needed
if ([requestUrl rangeOfString:@".{format}"].location != NSNotFound) if ([resourcePath rangeOfString:@".{format}"].location != NSNotFound) {
[requestUrl replaceCharactersInRange: [requestUrl rangeOfString:@".{format}"] withString:@".json"]; [resourcePath replaceCharactersInRange: [resourcePath rangeOfString:@".{format}"] withString:@".json"];
}
{{#pathParams}}[requestUrl replaceCharactersInRange: [requestUrl rangeOfString:[NSString stringWithFormat:@"%@%@%@", @"{", @"{{baseName}}", @"}"]] withString: [{{classPrefix}}ApiClient escape:{{paramName}}]]; {{#pathParams}}[resourcePath replaceCharactersInRange: [resourcePath rangeOfString:[NSString stringWithFormat:@"%@%@%@", @"{", @"{{baseName}}", @"}"]] withString: [{{classPrefix}}ApiClient escape:{{paramName}}]];
{{/pathParams}} {{/pathParams}}
NSMutableDictionary* queryParams = [[NSMutableDictionary alloc] init]; NSMutableDictionary* queryParams = [[NSMutableDictionary alloc] init];
@ -175,7 +165,7 @@ static NSString * basePath = @"{{basePath}}";
} }
{{/requiredParams}} {{/requiredParams}}
{{/requiredParamCount}} {{/requiredParamCount}}
return [self.apiClient requestWithCompletionBlock: requestUrl return [self.apiClient requestWithCompletionBlock: resourcePath
method: @"{{httpMethod}}" method: @"{{httpMethod}}"
queryParams: queryParams queryParams: queryParams
formParams: formParams formParams: formParams

View File

@ -5,6 +5,12 @@
#import "{{classPrefix}}ApiClient.h" #import "{{classPrefix}}ApiClient.h"
{{newline}} {{newline}}
/**
* 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.
*/
{{#operations}} {{#operations}}
@interface {{classname}}: NSObject @interface {{classname}}: NSObject
@ -14,8 +20,6 @@
-(void) addHeader:(NSString*)value forKey:(NSString*)key; -(void) addHeader:(NSString*)value forKey:(NSString*)key;
-(unsigned long) requestQueueSize; -(unsigned long) requestQueueSize;
+({{classname}}*) apiWithHeader:(NSString*)headerValue key:(NSString*)key; +({{classname}}*) apiWithHeader:(NSString*)headerValue key:(NSString*)key;
+(void) setBasePath:(NSString*)basePath;
+(NSString*) getBasePath;
{{#operation}} {{#operation}}
/// ///
/// ///

View File

@ -4,11 +4,20 @@
@implementation {{classname}} @implementation {{classname}}
/**
* Maps json key to property name.
* This method is used by `JSONModel`.
*/
+ (JSONKeyMapper *)keyMapper + (JSONKeyMapper *)keyMapper
{ {
return [[JSONKeyMapper alloc] initWithDictionary:@{ {{#vars}}@"{{baseName}}": @"{{name}}"{{#hasMore}}, {{/hasMore}}{{/vars}} }]; return [[JSONKeyMapper alloc] initWithDictionary:@{ {{#vars}}@"{{baseName}}": @"{{name}}"{{#hasMore}}, {{/hasMore}}{{/vars}} }];
} }
/**
* Indicates whether the property with the given name is optional.
* If `propertyName` is optional, then return `YES`, otherwise return `NO`.
* This method is used by `JSONModel`.
*/
+ (BOOL)propertyIsOptional:(NSString *)propertyName + (BOOL)propertyIsOptional:(NSString *)propertyName
{ {
NSArray *optionalProperties = @[{{#vars}}{{^required}}@"{{name}}"{{#hasMore}}, {{/hasMore}}{{/required}}{{/vars}}]; NSArray *optionalProperties = @[{{#vars}}{{^required}}@"{{name}}"{{#hasMore}}, {{/hasMore}}{{/required}}{{/vars}}];
@ -21,6 +30,14 @@
} }
} }
/**
* Gets the string presentation of the object.
* This method will be called when logging model object using `NSLog`.
*/
- (NSString *)description {
return [[self toDictionary] description];
}
{{/model}} {{/model}}
@end @end
{{/models}} {{/models}}

View File

@ -1,5 +1,12 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "{{classPrefix}}Object.h" #import "{{classPrefix}}Object.h"
/**
* 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.
*/
{{#imports}}#import "{{import}}.h" {{#imports}}#import "{{import}}.h"
{{/imports}} {{/imports}}
{{newline}} {{newline}}

View File

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

View File

@ -1,5 +1,8 @@
from __future__ import absolute_import from __future__ import absolute_import
# import apis into api package # import apis into api package
{{#apiInfo}}{{#apis}}from .{{classVarName}} import {{classname}} {{#apiInfo}}
{{/apis}}{{/apiInfo}} {{#apis}}
from .{{classVarName}} import {{classname}}
{{/apis}}
{{/apiInfo}}

View File

@ -1,5 +1,5 @@
from __future__ import absolute_import from __future__ import absolute_import
# import models into model package # import models into model package
{{#models}}{{#model}}from .{{classVarName}} import {{classname}} {{#models}}{{#model}}from .{{classVarName}} import {{classname}}{{/model}}
{{/model}}{{/models}} {{/models}}

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# coding: utf-8 # coding: utf-8
""" """
@ -16,9 +15,8 @@ Copyright 2015 SmartBear Software
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. 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 from __future__ import absolute_import
import sys import sys
@ -30,8 +28,13 @@ from six import iteritems
from ..configuration import Configuration from ..configuration import Configuration
from ..api_client import ApiClient from ..api_client import ApiClient
{{#operations}} {{#operations}}
class {{classname}}(object): 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): def __init__(self, api_client=None):
config = Configuration() config = Configuration()
@ -41,38 +44,48 @@ class {{classname}}(object):
if not config.api_client: if not config.api_client:
config.api_client = ApiClient('{{basePath}}') config.api_client = ApiClient('{{basePath}}')
self.api_client = config.api_client self.api_client = config.api_client
{{#operation}}
{{#operation}}
def {{nickname}}(self, {{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}**kwargs): def {{nickname}}(self, {{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}**kwargs):
""" """
{{{summary}}} {{{summary}}}
{{{notes}}} {{{notes}}}
SDK also supports asynchronous requests in which you can define a `callback` function This method makes a synchronous HTTP request by default.To make an
to be passed along and invoked when receiving response: asynchronous HTTP request, please define a `callback` function
to be invoked when receiving the response.
>>> def callback_function(response): >>> def callback_function(response):
>>> pprint(response) >>> pprint(response)
>>> >>>
>>> thread = api.{{nickname}}({{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}callback=callback_function) >>> thread = api.{{nickname}}({{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}callback=callback_function)
:param callback function: The callback function for asynchronous request. (optional) :param callback function: The callback function
{{#allParams}}:param {{dataType}} {{paramName}}: {{{description}}} {{#required}}(required){{/required}}{{#optional}}(optional){{/optional}} for asynchronous request. (optional)
{{/allParams}} {{#allParams}}
:param {{dataType}} {{paramName}}: {{{description}}}{{#required}} (required){{/required}}{{#optional}}(optional){{/optional}}
{{/allParams}}
:return: {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}None{{/returnType}} :return: {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}None{{/returnType}}
If the method is called asynchronously, returns the request thread. If the method is called asynchronously,
returns the request thread.
""" """
{{#allParams}}{{#required}} {{#allParams}}
{{#required}}
# verify the required parameter '{{paramName}}' is set # verify the required parameter '{{paramName}}' is set
if {{paramName}} is None: if {{paramName}} is None:
raise ValueError("Missing the required parameter `{{paramName}}` when calling `{{nickname}}`") raise ValueError("Missing the required parameter `{{paramName}}` when calling `{{nickname}}`")
{{/required}}{{/allParams}} {{/required}}
{{/allParams}}
all_params = [{{#allParams}}'{{paramName}}'{{#hasMore}}, {{/hasMore}}{{/allParams}}] all_params = [{{#allParams}}'{{paramName}}'{{#hasMore}}, {{/hasMore}}{{/allParams}}]
all_params.append('callback') all_params.append('callback')
params = locals() params = locals()
for key, val in iteritems(params['kwargs']): for key, val in iteritems(params['kwargs']):
if key not in all_params: if key not in all_params:
raise TypeError("Got an unexpected keyword argument '%s' to method {{nickname}}" % key) raise TypeError(
"Got an unexpected keyword argument '%s'"
" to method {{nickname}}" % key
)
params[key] = val params[key] = val
del params['kwargs'] del params['kwargs']
@ -80,45 +93,59 @@ class {{classname}}(object):
method = '{{httpMethod}}' method = '{{httpMethod}}'
path_params = {} path_params = {}
{{#pathParams}} {{#pathParams}}
if '{{paramName}}' in params: if '{{paramName}}' in params:
path_params['{{baseName}}'] = params['{{paramName}}'] path_params['{{baseName}}'] = params['{{paramName}}']
{{/pathParams}} {{/pathParams}}
query_params = {} query_params = {}
{{#queryParams}} {{#queryParams}}
if '{{paramName}}' in params: if '{{paramName}}' in params:
query_params['{{baseName}}'] = params['{{paramName}}'] query_params['{{baseName}}'] = params['{{paramName}}']
{{/queryParams}} {{/queryParams}}
header_params = {} header_params = {}
{{#headerParams}} {{#headerParams}}
if '{{paramName}}' in params: if '{{paramName}}' in params:
header_params['{{baseName}}'] = params['{{paramName}}'] header_params['{{baseName}}'] = params['{{paramName}}']
{{/headerParams}} {{/headerParams}}
form_params = {} form_params = {}
files = {} files = {}
{{#formParams}} {{#formParams}}
if '{{paramName}}' in params: if '{{paramName}}' in params:
{{#notFile}}form_params['{{baseName}}'] = params['{{paramName}}']{{/notFile}}{{#isFile}}files['{{baseName}}'] = params['{{paramName}}']{{/isFile}} {{#notFile}}form_params['{{baseName}}'] = params['{{paramName}}']{{/notFile}}{{#isFile}}files['{{baseName}}'] = params['{{paramName}}']{{/isFile}}
{{/formParams}} {{/formParams}}
body_params = None body_params = None
{{#bodyParam}} {{#bodyParam}}
if '{{paramName}}' in params: if '{{paramName}}' in params:
body_params = params['{{paramName}}'] body_params = params['{{paramName}}']
{{/bodyParam}} {{/bodyParam}}
# HTTP header `Accept` # HTTP header `Accept`
header_params['Accept'] = self.api_client.select_header_accept([{{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}}]) header_params['Accept'] = self.api_client.\
select_header_accept([{{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}}])
if not header_params['Accept']: if not header_params['Accept']:
del header_params['Accept'] del header_params['Accept']
# HTTP header `Content-Type` # HTTP header `Content-Type`
header_params['Content-Type'] = self.api_client.select_header_content_type([{{#consumes}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/consumes}}]) header_params['Content-Type'] = self.api_client.\
select_header_content_type([{{#consumes}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/consumes}}])
# Authentication setting # Authentication setting
auth_settings = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}] auth_settings = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}]
response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, response = self.api_client.call_api(resource_path, method,
body=body_params, post_params=form_params, files=files, path_params,
response_type={{#returnType}}'{{returnType}}'{{/returnType}}{{^returnType}}None{{/returnType}}, auth_settings=auth_settings, callback=params.get('callback')) query_params,
header_params,
body=body_params,
post_params=form_params,
files=files,
response_type={{#returnType}}'{{returnType}}'{{/returnType}}{{^returnType}}None{{/returnType}},
auth_settings=auth_settings,
callback=params.get('callback'))
return response return response
{{/operation}} {{/operation}}
{{/operations}} {{/operations}}

View File

@ -1,10 +1,20 @@
#!/usr/bin/env python
# coding: utf-8 # coding: utf-8
"""Swagger generic API client. This client handles the client- """
server communication, and is invariant across implementations. Specifics of Copyright 2015 SmartBear Software
the methods and models for each application are generated from the Swagger
templates.""" 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 __future__ import absolute_import
from . import models from . import models
@ -35,36 +45,59 @@ except ImportError:
from .configuration import Configuration from .configuration import Configuration
class ApiClient(object): 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 Swagger generic API client. This client handles the client-
:param header_name: a header to pass when making calls to the API server communication, and is invariant across implementations. Specifics of
:param header_value: a header value to pass when making calls to the API 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.
""" """
def __init__(self, host=Configuration().host, header_name=None, header_value=None):
self.default_headers = {} self.default_headers = {}
if header_name is not None: if header_name is not None:
self.default_headers[header_name] = header_value self.default_headers[header_name] = header_value
self.host = host self.host = host
self.cookie = None self.cookie = cookie
# Set default User-Agent. # Set default User-Agent.
self.user_agent = 'Python-Swagger' self.user_agent = 'Python-Swagger'
@property @property
def user_agent(self): def user_agent(self):
"""
Gets user agent.
"""
return self.default_headers['User-Agent'] return self.default_headers['User-Agent']
@user_agent.setter @user_agent.setter
def user_agent(self, value): def user_agent(self, value):
"""
Sets user agent.
"""
self.default_headers['User-Agent'] = value self.default_headers['User-Agent'] = value
def set_default_header(self, header_name, header_value): def set_default_header(self, header_name, header_value):
self.default_headers[header_name] = header_value self.default_headers[header_name] = header_value
def __call_api(self, resource_path, method, path_params=None, query_params=None, header_params=None, def __call_api(self, resource_path, method,
body=None, post_params=None, files=None, response_type=None, auth_settings=None, callback=None): path_params=None, query_params=None, header_params=None,
body=None, post_params=None, files=None,
response_type=None, auth_settings=None, callback=None):
# headers parameters # headers parameters
header_params = header_params or {} header_params = header_params or {}
@ -79,12 +112,14 @@ class ApiClient(object):
path_params = self.sanitize_for_serialization(path_params) path_params = self.sanitize_for_serialization(path_params)
for k, v in iteritems(path_params): for k, v in iteritems(path_params):
replacement = quote(str(self.to_path_value(v))) replacement = quote(str(self.to_path_value(v)))
resource_path = resource_path.replace('{' + k + '}', replacement) resource_path = resource_path.\
replace('{' + k + '}', replacement)
# query parameters # query parameters
if query_params: if query_params:
query_params = self.sanitize_for_serialization(query_params) query_params = self.sanitize_for_serialization(query_params)
query_params = {k: self.to_path_value(v) for k, v in iteritems(query_params)} query_params = {k: self.to_path_value(v)
for k, v in iteritems(query_params)}
# post parameters # post parameters
if post_params: if post_params:
@ -102,7 +137,9 @@ class ApiClient(object):
url = self.host + resource_path url = self.host + resource_path
# perform request and return response # perform request and return response
response_data = self.request(method, url, query_params=query_params, headers=header_params, response_data = self.request(method, url,
query_params=query_params,
headers=header_params,
post_params=post_params, body=body) post_params=post_params, body=body)
self.last_response = response_data self.last_response = response_data
@ -120,11 +157,12 @@ class ApiClient(object):
def to_path_value(self, obj): 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: if type(obj) == list:
return ','.join(obj) return ','.join(obj)
@ -133,46 +171,58 @@ class ApiClient(object):
def sanitize_for_serialization(self, obj): 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 None, return None.
If obj is str, int, float, bool, return directly. If obj is str, int, float, bool, return directly.
If obj is datetime.datetime, datetime.date convert to string in iso8601 format. If obj is datetime.datetime, datetime.date
convert to string in iso8601 format.
If obj is list, santize each element in the list. If obj is list, santize each element in the list.
If obj is dict, return the dict. If obj is dict, return the dict.
If obj is swagger model, return the properties 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)): if isinstance(obj, type(None)):
return None return None
elif isinstance(obj, (str, int, float, bool, tuple)): elif isinstance(obj, (str, int, float, bool, tuple)):
return obj return obj
elif isinstance(obj, list): elif isinstance(obj, list):
return [self.sanitize_for_serialization(sub_obj) for sub_obj in obj] return [self.sanitize_for_serialization(sub_obj)
for sub_obj in obj]
elif isinstance(obj, (datetime, date)): elif isinstance(obj, (datetime, date)):
return obj.isoformat() return obj.isoformat()
else: else:
if isinstance(obj, dict): if isinstance(obj, dict):
obj_dict = obj obj_dict = obj
else: else:
# Convert model obj to dict except attributes `swagger_types`, `attribute_map` # Convert model obj to dict except
# attributes `swagger_types`, `attribute_map`
# and attributes which value is not None. # and attributes which value is not None.
# Convert attribute name to json key in model definition for request. # Convert attribute name to json key in
obj_dict = {obj.attribute_map[key]: val # model definition for request.
obj_dict = {obj.attribute_map[key[1:]]: val
for key, val in iteritems(obj.__dict__) for key, val in iteritems(obj.__dict__)
if key != 'swagger_types' and key != 'attribute_map' and val is not None} if key != 'swagger_types'
and key != 'attribute_map'
and val is not None}
return {key: self.sanitize_for_serialization(val) return {key: self.sanitize_for_serialization(val)
for key, val in iteritems(obj_dict)} for key, val in iteritems(obj_dict)}
def deserialize(self, response, response_type): 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 :param response_type: class literal for
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 # handle file downloading
# save response body into a tmp file and return the instance
if "file" == response_type: if "file" == response_type:
return self.__deserialize_file(response) return self.__deserialize_file(response)
@ -186,26 +236,31 @@ class ApiClient(object):
def __deserialize(self, data, klass): def __deserialize(self, data, klass):
""" """
:param data: dict, list or str Deserializes dict, list, str into an object.
:param klass: class literal, or string of class name
:return: object :param data: dict, list or str.
:param klass: class literal, or string of class name.
:return: object.
""" """
if data is None: if data is None:
return None return None
if type(klass) == str: if type(klass) == str:
if 'list[' in klass: if klass.startswith('list['):
sub_kls = re.match('list\[(.*)\]', klass).group(1) sub_kls = re.match('list\[(.*)\]', klass).group(1)
return [self.__deserialize(sub_data, sub_kls) for sub_data in data] 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) sub_kls = re.match('dict\(([^,]*), (.*)\)', klass).group(2)
return {k: self.__deserialize(v, sub_kls) for k, v in iteritems(data)} return {k: self.__deserialize(v, sub_kls)
for k, v in iteritems(data)}
# convert str to class # convert str to class
# for native types # for native types
if klass in ['int', 'float', 'str', 'bool', "date", 'datetime', "object"]: if klass in ['int', 'float', 'str', 'bool',
"date", 'datetime', "object"]:
klass = eval(klass) klass = eval(klass)
# for model types # for model types
else: else:
@ -227,25 +282,30 @@ class ApiClient(object):
body=None, post_params=None, files=None, body=None, post_params=None, files=None,
response_type=None, auth_settings=None, callback=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 resource_path: Path to method endpoint.
:param method: Method to call. :param method: Method to call.
:param path_params: Path parameters in the url. :param path_params: Path parameters in the url.
:param query_params: Query parameters in the url. :param query_params: Query parameters in the url.
:param header_params: Header parameters to be placed in the request header. :param header_params: Header parameters to be
placed in the request header.
:param body: Request body. :param body: Request body.
:param post_params dict: Request post form parameters, for `application/x-www-form-urlencoded`, `multipart/form-data`. :param post_params dict: Request post form parameters,
for `application/x-www-form-urlencoded`, `multipart/form-data`.
:param auth_settings list: Auth Settings names for the request. :param auth_settings list: Auth Settings names for the request.
:param response: Response data type. :param response: Response data type.
:param files dict: key -> filename, value -> filepath, for `multipart/form-data`. :param files dict: key -> filename, value -> filepath,
for `multipart/form-data`.
:param callback function: Callback function for asynchronous request. :param callback function: Callback function for asynchronous request.
If provide this parameter, the request will be called asynchronously. If provide this parameter,
the request will be called asynchronously.
:return: :return:
If provide parameter callback, the request will be called asynchronously. If provide parameter callback,
the request will be called asynchronously.
The method will return the request thread. The method will return the request thread.
If parameter callback is None, then the method will return the response directly. If parameter callback is None,
then the method will return the response directly.
""" """
if callback is None: if callback is None:
return self.__call_api(resource_path, method, return self.__call_api(resource_path, method,
@ -255,33 +315,60 @@ class ApiClient(object):
else: else:
thread = threading.Thread(target=self.__call_api, thread = threading.Thread(target=self.__call_api,
args=(resource_path, method, args=(resource_path, method,
path_params, query_params, header_params, path_params, query_params,
body, post_params, files, header_params, body,
response_type, auth_settings, callback)) post_params, files,
response_type, auth_settings,
callback))
thread.start() thread.start()
return thread return thread
def request(self, method, url, query_params=None, headers=None, def request(self, method, url, query_params=None, headers=None,
post_params=None, body=None): post_params=None, body=None):
""" """
Perform http request using RESTClient. Makes the HTTP request using RESTClient.
""" """
if method == "GET": if method == "GET":
return RESTClient.GET(url, query_params=query_params, headers=headers) return RESTClient.GET(url,
query_params=query_params,
headers=headers)
elif method == "HEAD": elif method == "HEAD":
return RESTClient.HEAD(url, query_params=query_params, headers=headers) return RESTClient.HEAD(url,
query_params=query_params,
headers=headers)
elif method == "POST": elif method == "POST":
return RESTClient.POST(url, headers=headers, post_params=post_params, body=body) return RESTClient.POST(url,
headers=headers,
post_params=post_params,
body=body)
elif method == "PUT": elif method == "PUT":
return RESTClient.PUT(url, headers=headers, post_params=post_params, body=body) return RESTClient.PUT(url,
headers=headers,
post_params=post_params,
body=body)
elif method == "PATCH": elif method == "PATCH":
return RESTClient.PATCH(url, headers=headers, post_params=post_params, body=body) return RESTClient.PATCH(url,
headers=headers,
post_params=post_params,
body=body)
elif method == "DELETE": elif method == "DELETE":
return RESTClient.DELETE(url, query_params=query_params, headers=headers) return RESTClient.DELETE(url,
query_params=query_params,
headers=headers)
else: else:
raise ValueError("http method must be `GET`, `HEAD`, `POST`, `PATCH`, `PUT` or `DELETE`") raise ValueError(
"http method must be `GET`, `HEAD`,"
" `POST`, `PATCH`, `PUT` or `DELETE`."
)
def prepare_post_parameters(self, post_params=None, files=None): 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 = {} params = {}
if post_params: if post_params:
@ -289,18 +376,24 @@ class ApiClient(object):
if files: if files:
for k, v in iteritems(files): for k, v in iteritems(files):
if v: if not v:
continue
with open(v, 'rb') as f: with open(v, 'rb') as f:
filename = os.path.basename(f.name) filename = os.path.basename(f.name)
filedata = f.read() filedata = f.read()
mimetype = mimetypes.guess_type(filename)[0] or 'application/octet-stream' mimetype = mimetypes.\
guess_type(filename)[0] or 'application/octet-stream'
params[k] = tuple([filename, filedata, mimetype]) params[k] = tuple([filename, filedata, mimetype])
return params return params
def select_header_accept(self, accepts): 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: if not accepts:
return return
@ -314,7 +407,10 @@ class ApiClient(object):
def select_header_content_type(self, content_types): 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: if not content_types:
return 'application/json' return 'application/json'
@ -328,7 +424,11 @@ class ApiClient(object):
def update_params_for_auth(self, headers, querys, auth_settings): 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() config = Configuration()
@ -343,23 +443,30 @@ class ApiClient(object):
elif auth_setting['in'] == 'query': elif auth_setting['in'] == 'query':
querys[auth_setting['key']] = auth_setting['value'] querys[auth_setting['key']] = auth_setting['value']
else: else:
raise ValueError('Authentication token must be in `query` or `header`') raise ValueError(
'Authentication token must be in `query` or `header`'
)
def __deserialize_file(self, response): def __deserialize_file(self, response):
""" """
Save response body into a file in (the defined) temporary folder, using the filename Saves response body into a file in (the defined) temporary folder,
from the `Content-Disposition` header if provided, otherwise a random filename. using the filename from the `Content-Disposition` header if provided,
otherwise a random filename.
:param response: RESTResponse :param response: RESTResponse.
:return: file path :return: file path.
""" """
fd, path = tempfile.mkstemp(dir=configuration.temp_folder_path) config = Configuration()
fd, path = tempfile.mkstemp(dir=config.temp_folder_path)
os.close(fd) os.close(fd)
os.remove(path) os.remove(path)
content_disposition = response.getheader("Content-Disposition") content_disposition = response.getheader("Content-Disposition")
if content_disposition: if content_disposition:
filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', content_disposition).group(1) filename = re.\
search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', content_disposition).\
group(1)
path = os.path.join(os.path.dirname(path), filename) path = os.path.join(os.path.dirname(path), filename)
with open(path, "w") as f: with open(path, "w") as f:
@ -369,12 +476,12 @@ class ApiClient(object):
def __deserialize_primitive(self, data, klass): def __deserialize_primitive(self, data, klass):
""" """
Deserialize string to primitive type Deserializes string to primitive type.
:param data: str :param data: str.
:param klass: class literal :param klass: class literal.
:return: int, float, str, bool :return: int, float, str, bool.
""" """
try: try:
value = klass(data) value = klass(data)
@ -386,16 +493,18 @@ class ApiClient(object):
def __deserialize_object(self): def __deserialize_object(self):
""" """
Deserialize empty object Deserializes empty object.
:return: object.
""" """
return object() return object()
def __deserialize_date(self, string): def __deserialize_date(self, string):
""" """
Deserialize string to date Deserializes string to date.
:param string: str :param string: str.
:return: date :return: date.
""" """
try: try:
from dateutil.parser import parse from dateutil.parser import parse
@ -403,16 +512,20 @@ class ApiClient(object):
except ImportError: except ImportError:
return string return string
except ValueError: except ValueError:
raise ApiException(status=0, reason="Failed to parse `{0}` into a date object".format(string)) raise ApiException(
status=0,
reason="Failed to parse `{0}` into a date object"
.format(string)
)
def __deserialize_datatime(self, string): def __deserialize_datatime(self, string):
""" """
Deserialize string to datetime. Deserializes string to datetime.
The string should be in iso8601 datetime format. The string should be in iso8601 datetime format.
:param string: str :param string: str.
:return: datetime :return: datetime.
""" """
try: try:
from dateutil.parser import parse from dateutil.parser import parse
@ -420,14 +533,19 @@ class ApiClient(object):
except ImportError: except ImportError:
return string return string
except ValueError: except ValueError:
raise ApiException(status=0, reason="Failed to parse `{0}` into a datetime object".format(string)) raise ApiException(
status=0,
reason="Failed to parse `{0}` into a datetime object".
format(string)
)
def __deserialize_model(self, data, klass): def __deserialize_model(self, data, klass):
""" """
Deserialize list or dict to model Deserializes list or dict to model.
:param data: dict, list :param data: dict, list.
:param klass: class literal :param klass: class literal.
:return: model object.
""" """
instance = klass() instance = klass()

View File

@ -1,10 +1,35 @@
# 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 from __future__ import absolute_import
import base64 import base64
import urllib3 import urllib3
import httplib
try:
import httplib
except ImportError:
# python3
import http.client as httplib
import sys import sys
import logging import logging
def singleton(cls, *args, **kw): def singleton(cls, *args, **kw):
instances = {} instances = {}
@ -17,24 +42,45 @@ def singleton(cls, *args, **kw):
@singleton @singleton
class Configuration(object): 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): def __init__(self):
"""
Constructor
"""
# Default Base url # Default Base url
self.host = "{{basePath}}" self.host = "{{basePath}}"
# Default api client # Default api client
self.api_client = None self.api_client = None
# Temp file folder for download
self.temp_folder_path = None
# Authentication Settings # Authentication Settings
# dict to store API key(s)
self.api_key = {} self.api_key = {}
# dict to store API prefix (e.g. Bearer)
self.api_key_prefix = {} self.api_key_prefix = {}
# Username for HTTP basic authentication
self.username = "" self.username = ""
# Password for HTTP basic authentication
self.password = "" self.password = ""
# Logging Settings # Logging Settings
self.logging_format = '%(asctime)s %(levelname)s %(message)s' self.logging_format = '%(asctime)s %(levelname)s %(message)s'
# Debug file location
self.__logging_file = None self.__logging_file = None
# Debug switch
self.__debug = False self.__debug = False
self.init_logger() self.init_logger()
def init_logger(self): def init_logger(self):
"""
Initializes logger settings.
"""
self.logger = logging.getLogger() self.logger = logging.getLogger()
formatter = logging.Formatter(self.logging_format) formatter = logging.Formatter(self.logging_format)
stream_handler = logging.StreamHandler() stream_handler = logging.StreamHandler()
@ -79,43 +125,65 @@ class Configuration(object):
# setting log level to default `logging.WARNING` # setting log level to default `logging.WARNING`
self.logger.setLevel(logging.WARNING) self.logger.setLevel(logging.WARNING)
def get_api_key_with_prefix(self, key): def get_api_key_with_prefix(self, identifier):
""" Return api key prepend prefix for key """ """
if self.api_key.get(key) and self.api_key_prefix.get(key): Gets API key (with prefix if set).
return self.api_key_prefix[key] + ' ' + self.api_key[key]
elif self.api_key.get(key): :param identifier: The identifier of apiKey.
return self.api_key[key] :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): 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)\ return urllib3.util.make_headers(basic_auth=self.username + ':' + self.password)\
.get('authorization') .get('authorization')
def auth_settings(self): def auth_settings(self):
""" Return Auth Settings for api client """ """
return { {{#authMethods}}{{#isApiKey}} Gets Auth Settings dict for api client.
'{{name}}': {
:return: The Auth Settings information dict.
"""
return {
{{#authMethods}}
{{#isApiKey}}
'{{name}}':
{
'type': 'api_key', 'type': 'api_key',
'in': {{#isKeyInHeader}}'header'{{/isKeyInHeader}}{{#isKeyInQuery}}'query'{{/isKeyInQuery}}, 'in': {{#isKeyInHeader}}'header'{{/isKeyInHeader}}{{#isKeyInQuery}}'query'{{/isKeyInQuery}},
'key': '{{keyParamName}}', 'key': '{{keyParamName}}',
'value': self.get_api_key_with_prefix('{{keyParamName}}') 'value': self.get_api_key_with_prefix('{{keyParamName}}')
}, },
{{/isApiKey}}{{#isBasic}} {{/isApiKey}}
'{{name}}': { {{#isBasic}}
'{{name}}':
{
'type': 'basic', 'type': 'basic',
'in': 'header', 'in': 'header',
'key': 'Authorization', 'key': 'Authorization',
'value': self.get_basic_auth_token() 'value': self.get_basic_auth_token()
}, },
{{/isBasic}}{{/authMethods}} {{/isBasic}}
{{/authMethods}}
} }
def to_debug_report(self): def to_debug_report(self):
"""
Gets the essential information for debugging.
:return: The report for debugging.
"""
return "Python SDK Debug Report:\n"\ return "Python SDK Debug Report:\n"\
"OS: {env}\n"\ "OS: {env}\n"\
"Python Version: {pyversion}\n"\ "Python Version: {pyversion}\n"\
"Version of the API: {{version}}\n"\ "Version of the API: {{version}}\n"\
"SDK Package Version: {{packageVersion}}".format(env=sys.platform, pyversion=sys.version) "SDK Package Version: {{packageVersion}}".\
format(env=sys.platform, pyversion=sys.version)

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# coding: utf-8 # coding: utf-8
""" """
@ -16,21 +15,26 @@ Copyright 2015 SmartBear Software
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
""" """
{{#models}} {{#models}}
{{#model}} {{#model}}
from pprint import pformat
from six import iteritems
class {{classname}}(object): class {{classname}}(object):
""" """
NOTE: This class is auto generated by the swagger code generator program. NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually. Do not edit the class manually.
""" """
def __init__(self): def __init__(self):
""" """
Swagger model Swagger model
:param dict swaggerTypes: The key is attribute name and the value is attribute type. :param dict swaggerTypes: The key is attribute name
:param dict attributeMap: The key is attribute name and the value is json key in definition. and the value is attribute type.
:param dict attributeMap: The key is attribute name
and the value is json key in definition.
""" """
self.swagger_types = { self.swagger_types = {
{{#vars}}'{{name}}': '{{{datatype}}}'{{#hasMore}}, {{#vars}}'{{name}}': '{{{datatype}}}'{{#hasMore}},
@ -41,19 +45,72 @@ class {{classname}}(object):
{{#vars}}'{{name}}': '{{baseName}}'{{#hasMore}}, {{#vars}}'{{name}}': '{{baseName}}'{{#hasMore}},
{{/hasMore}}{{/vars}} {{/hasMore}}{{/vars}}
} }
{{#vars}}
{{#description}}# {{description}}{{/description}} {{#vars}}
self.{{name}} = None # {{{datatype}}} self._{{name}} = None
{{/vars}} {{/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(
"Invalid value for `{{name}}`, must be one of {0}"
.format(allowed_values)
)
{{/isEnum}}self._{{name}} = {{name}}
{{/vars}}
def to_dict(self):
"""
Return model properties dict
"""
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(
lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
prop
))
elif hasattr(prop, "to_dict"):
result[name[1:]] = prop.to_dict()
else:
result[name[1:]] = prop
return result
def to_str(self):
"""
Return model properties str
"""
return pformat(self.to_dict())
def __repr__(self): def __repr__(self):
properties = [] """
for p in self.__dict__: For `print` and `pprint`
if p != 'swaggerTypes' and p != 'attributeMap': """
properties.append('{prop}={val!r}'.format(prop=p, val=self.__dict__[p])) return self.to_str()
return '<{name} {props}>'.format(name=__name__, props=' '.join(properties))
{{/model}} {{/model}}
{{/models}} {{/models}}

View File

@ -1,6 +1,20 @@
# coding: utf-8 # 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: Credit: this file (rest.py) is modified based on rest.py in Dropbox Python SDK:
https://www.dropbox.com/developers/core/sdks/python https://www.dropbox.com/developers/core/sdks/python
""" """
@ -51,6 +65,7 @@ class RESTResponse(io.IOBase):
""" """
return self.urllib3_response.getheader(name, default) return self.urllib3_response.getheader(name, default)
class RESTClientObject(object): class RESTClientObject(object):
def __init__(self, pools_size=4): def __init__(self, pools_size=4):
@ -87,14 +102,17 @@ class RESTClientObject(object):
:param query_params: query parameters in the url :param query_params: query parameters in the url
:param headers: http request headers :param headers: http request headers
:param body: request json body, for `application/json` :param body: request json body, for `application/json`
:param post_params: request post parameters, `application/x-www-form-urlencode` :param post_params: request post parameters,
`application/x-www-form-urlencode`
and `multipart/form-data` and `multipart/form-data`
""" """
method = method.upper() method = method.upper()
assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', 'PATCH'] assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', 'PATCH']
if post_params and body: if post_params and body:
raise ValueError("body parameter cannot be used with post_params parameter.") raise ValueError(
"body parameter cannot be used with post_params parameter."
)
post_params = post_params or {} post_params = post_params or {}
headers = headers or {} headers = headers or {}
@ -144,22 +162,37 @@ class RESTClientObject(object):
return r return r
def GET(self, url, headers=None, query_params=None): def GET(self, url, headers=None, query_params=None):
return self.request("GET", url, headers=headers, query_params=query_params) return self.request("GET", url,
headers=headers,
query_params=query_params)
def HEAD(self, url, headers=None, query_params=None): def HEAD(self, url, headers=None, query_params=None):
return self.request("HEAD", url, headers=headers, query_params=query_params) return self.request("HEAD", url,
headers=headers,
query_params=query_params)
def DELETE(self, url, headers=None, query_params=None): def DELETE(self, url, headers=None, query_params=None):
return self.request("DELETE", url, headers=headers, query_params=query_params) return self.request("DELETE", url,
headers=headers,
query_params=query_params)
def POST(self, url, headers=None, post_params=None, body=None): def POST(self, url, headers=None, post_params=None, body=None):
return self.request("POST", url, headers=headers, post_params=post_params, body=body) return self.request("POST", url,
headers=headers,
post_params=post_params,
body=body)
def PUT(self, url, headers=None, post_params=None, body=None): def PUT(self, url, headers=None, post_params=None, body=None):
return self.request("PUT", url, headers=headers, post_params=post_params, body=body) return self.request("PUT", url,
headers=headers,
post_params=post_params,
body=body)
def PATCH(self, url, headers=None, post_params=None, body=None): def PATCH(self, url, headers=None, post_params=None, body=None):
return self.request("PATCH", url, headers=headers, post_params=post_params, body=body) return self.request("PATCH", url,
headers=headers,
post_params=post_params,
body=body)
class ApiException(Exception): class ApiException(Exception):
@ -183,13 +216,14 @@ class ApiException(Exception):
error_message = "({0})\n"\ error_message = "({0})\n"\
"Reason: {1}\n".format(self.status, self.reason) "Reason: {1}\n".format(self.status, self.reason)
if self.headers: 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: 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 return error_message
class RESTClient(object): class RESTClient(object):
""" """
A class with all class methods to perform JSON requests. A class with all class methods to perform JSON requests.

View File

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

View File

@ -18,13 +18,13 @@ from .models import *
class ApiClient: class ApiClient:
"""Generic API client for Swagger client library builds""" """Generic API client for Swagger client library builds"""
def __init__(self, apiKey=None, apiServer=None): def __init__(self, apiKey=None, apiServer=None, cookie=None):
if apiKey == None: if apiKey == None:
raise Exception('You must pass an apiKey when instantiating the ' raise Exception('You must pass an apiKey when instantiating the '
'APIClient') 'APIClient')
self.apiKey = apiKey self.apiKey = apiKey
self.apiServer = apiServer self.apiServer = apiServer
self.cookie = None self.cookie = cookie
def callAPI(self, resourcePath, method, queryParams, postData, def callAPI(self, resourcePath, method, queryParams, postData,
headerParams=None): headerParams=None):

View File

@ -22,7 +22,7 @@ public interface {{classname}} {
{{#isMultipart}}@Multipart{{/isMultipart}}{{^isMultipart}}@FormUrlEncoded{{/isMultipart}}{{/-first}}{{/formParams}} {{#isMultipart}}@Multipart{{/isMultipart}}{{^isMultipart}}@FormUrlEncoded{{/isMultipart}}{{/-first}}{{/formParams}}
@{{httpMethod}}("{{path}}") @{{httpMethod}}("{{path}}")
{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}} {{nickname}}({{^allParams}});{{/allParams}} {{#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}} );{{/hasMore}}{{/allParams}}
{{/operation}} {{/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.Gson;
import com.google.gson.GsonBuilder; 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.RestAdapter;
import retrofit.converter.ConversionException;
import retrofit.converter.Converter;
import retrofit.converter.GsonConverter; import retrofit.converter.GsonConverter;
import retrofit.mime.TypedByteArray;
import retrofit.mime.TypedInput;
import retrofit.mime.TypedOutput;
public class ServiceGenerator { public class ServiceGenerator {
// No need to instantiate this class. // No need to instantiate this class.
@ -15,9 +27,63 @@ public class ServiceGenerator {
.create(); .create();
RestAdapter adapter = new RestAdapter.Builder() RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint("{{basePath}}") .setEndpoint("{{basePath}}")
.setConverter(new GsonConverter(gson)) .setConverter(new GsonConverterWrapper(gson))
.build(); .build();
return adapter.create(serviceClass); 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]) { if (cls == classOf[String]) {
json match { json match {
case s: String => { 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 else s
} }
case _ => null case _ => null

View File

@ -6,13 +6,13 @@
import Foundation import Foundation
class {{projectName}}API { public class {{projectName}}API {
static let basePath = "{{basePath}}" static let basePath = "{{basePath}}"
static var credential: NSURLCredential? static var credential: NSURLCredential?
static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory() static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory()
} }
class APIBase { public class APIBase {
func toParameters(encodable: JSONEncodable?) -> [String: AnyObject]? { func toParameters(encodable: JSONEncodable?) -> [String: AnyObject]? {
let encoded: AnyObject? = encodable?.encodeToJSON() let encoded: AnyObject? = encodable?.encodeToJSON()
@ -28,7 +28,7 @@ class APIBase {
} }
} }
class RequestBuilder<T> { public class RequestBuilder<T> {
var credential: NSURLCredential? var credential: NSURLCredential?
var headers: [String:String] = [:] var headers: [String:String] = [:]
let parameters: [String:AnyObject]? let parameters: [String:AnyObject]?
@ -36,24 +36,24 @@ class RequestBuilder<T> {
let method: String let method: String
let URLString: String let URLString: String
required init(method: String, URLString: String, parameters: [String:AnyObject]?, isBody: Bool) { required public init(method: String, URLString: String, parameters: [String:AnyObject]?, isBody: Bool) {
self.method = method self.method = method
self.URLString = URLString self.URLString = URLString
self.parameters = parameters self.parameters = parameters
self.isBody = isBody self.isBody = isBody
} }
func execute(completion: (response: Response<T>?, erorr: NSError?) -> Void) { } public func execute(completion: (response: Response<T>?, erorr: NSError?) -> Void) { }
func addHeader(#name: String, value: String) -> Self { public func addHeader(#name: String, value: String) -> Self {
if !value.isEmpty { if !value.isEmpty {
headers[name] = value headers[name] = value
} }
return self return self
} }
func addCredential() -> Self { public func addCredential() -> Self {
self.credential = OneteamAPI.credential self.credential = {{projectName}}API.credential
return self return self
} }
} }

View File

@ -29,7 +29,47 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
managerStore[managerId] = manager managerStore[managerId] = manager
let encoding = isBody ? Alamofire.ParameterEncoding.JSON : Alamofire.ParameterEncoding.URL let encoding = isBody ? Alamofire.ParameterEncoding.JSON : Alamofire.ParameterEncoding.URL
let request = manager.request(Alamofire.Method(rawValue: method)!, URLString, parameters: parameters, encoding: encoding) let xMethod = Alamofire.Method(rawValue: method)
let fileKeys = parameters == nil ? [] : map(filter(parameters!) { $1.isKindOfClass(NSURL) }) { $0.0 }
if fileKeys.count > 0 {
manager.upload(
xMethod!, URLString, headers: nil,
multipartFormData: { mpForm in
for (k, v) in self.parameters! {
switch v {
case let fileURL as NSURL:
mpForm.appendBodyPart(fileURL: fileURL, name: k)
break
case let string as NSString:
mpForm.appendBodyPart(data: string.dataUsingEncoding(NSUTF8StringEncoding)!, name: k)
break
case let number as NSNumber:
mpForm.appendBodyPart(data: number.stringValue.dataUsingEncoding(NSUTF8StringEncoding)!, name: k)
break
default:
fatalError("Unprocessable value \(v) with key \(k)")
break
}
}
},
encodingMemoryThreshold: Manager.MultipartFormDataEncodingMemoryThreshold,
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
self.processRequest(upload, managerId, completion)
case .Failure(let encodingError):
completion(response: nil, erorr: encodingError)
}
}
)
} else {
processRequest(manager.request(xMethod!, URLString, parameters: parameters, encoding: encoding), managerId, completion)
}
}
private func processRequest(request: Request, _ managerId: String, _ completion: (response: Response<T>?, erorr: NSError?) -> Void) {
if let credential = self.credential { if let credential = self.credential {
request.authenticate(usingCredential: credential) request.authenticate(usingCredential: credential)
} }

View File

@ -1,2 +1,2 @@
github "Alamofire/Alamofire" >= 1.2 github "Alamofire/Alamofire" >= 1.3
github "mxcl/PromiseKit" >=1.5.3 github "mxcl/PromiseKit" >=1.5.3

View File

@ -65,7 +65,7 @@ extension NSDate: JSONEncodable {
} }
{{#usePromiseKit}}extension RequestBuilder { {{#usePromiseKit}}extension RequestBuilder {
func execute() -> Promise<Response<T>> { public func execute() -> Promise<Response<T>> {
let deferred = Promise<Response<T>>.defer() let deferred = Promise<Response<T>>.defer()
self.execute { (response: Response<T>?, error: NSError?) in self.execute { (response: Response<T>?, error: NSError?) in
if let response = response { if let response = response {

View File

@ -10,18 +10,18 @@ protocol JSONEncodable {
func encodeToJSON() -> AnyObject func encodeToJSON() -> AnyObject
} }
class Response<T> { public class Response<T> {
let statusCode: Int public let statusCode: Int
let header: [String: String] public let header: [String: String]
let body: T public let body: T
init(statusCode: Int, header: [String: String], body: T) { public init(statusCode: Int, header: [String: String], body: T) {
self.statusCode = statusCode self.statusCode = statusCode
self.header = header self.header = header
self.body = body self.body = body
} }
convenience init(response: NSHTTPURLResponse, body: T) { public convenience init(response: NSHTTPURLResponse, body: T) {
let rawHeader = response.allHeaderFields let rawHeader = response.allHeaderFields
var header = [String:String]() var header = [String:String]()
for (key, value) in rawHeader { for (key, value) in rawHeader {

View File

@ -0,0 +1,20 @@
Pod::Spec.new do |s|
s.name = '{{projectName}}'{{#projectDescription}}
s.summary = '{{projectDescription}}'{{/projectDescription}}
s.ios.deployment_target = '8.0'
s.osx.deployment_target = '10.9'
s.version = '{{#podVersion}}{{podVersion}}{{/podVersion}}{{^podVersion}}0.0.1{{/podVersion}}'
s.source = {{#podSource}}{{& podSource}}{{/podSource}}{{^podSource}}{ :git => 'git@github.com:swagger-api/swagger-mustache.git', :tag => 'v1.0.0' }{{/podSource}}{{#podAuthors}}
s.authors = {{& podAuthors}}{{/podAuthors}}{{#podSocialMediaURL}}
s.social_media_url = '{{podSocialMediaURL}}'{{/podSocialMediaURL}}{{#podDocsetURL}}
s.docset_url = '{{podDocsetURL}}'{{/podDocsetURL}}
s.license = {{#podLicense}}{{& podLicense}}{{/podLicense}}{{^podLicense}}'Apache License, Version 2.0'{{/podLicense}}{{#podHomepage}}
s.homepage = '{{podHomepage}}'{{/podHomepage}}{{#podSummary}}
s.summary = '{{podSummary}}'{{/podSummary}}{{#podDescription}}
s.description = '{{podDescription}}'{{/podDescription}}{{#podScreenshots}}
s.screenshots = {{& podScreenshots}}{{/podScreenshots}}{{#podDocumentationURL}}
s.documentation_url = '{{podDocumentationURL}}'{{/podDocumentationURL}}
s.source_files = '{{projectName}}/Classes/Swaggers/**/*.swift'
s.dependency 'PromiseKit', '~> 2.1'
s.dependency 'Alamofire', '~> 1.3'
end

View File

@ -11,7 +11,7 @@ import PromiseKit
extension {{projectName}}API { extension {{projectName}}API {
{{#description}} {{#description}}
/** {{description}} */{{/description}} /** {{description}} */{{/description}}
class {{classname}}: APIBase { public class {{classname}}: APIBase {
{{#operation}} {{#operation}}
/** /**
{{#summary}} {{#summary}}
@ -32,20 +32,22 @@ extension {{projectName}}API {
:returns: Promise<Response<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}>> {{description}} :returns: Promise<Response<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}>> {{description}}
*/ */
func {{operationId}}({{#allParams}}{{^secondaryParam}}#{{/secondaryParam}}{{paramName}}: {{{dataType}}}{{^required}}?{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> { public class func {{operationId}}({{#allParams}}{{^secondaryParam}}#{{/secondaryParam}}{{paramName}}: {{{dataType}}}{{^required}}?{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {
{{^pathParams}}let{{/pathParams}}{{#pathParams}}{{^secondaryParam}}var{{/secondaryParam}}{{/pathParams}} path = "{{path}}"{{#pathParams}} {{^pathParams}}let{{/pathParams}}{{#pathParams}}{{^secondaryParam}}var{{/secondaryParam}}{{/pathParams}} path = "{{path}}"{{#pathParams}}
path = path.stringByReplacingOccurrencesOfString("{{=<% %>=}}{<%paramName%>}<%={{ }}=%>", withString: "\({{paramName}})", options: .LiteralSearch, range: nil){{/pathParams}} path = path.stringByReplacingOccurrencesOfString("{{=<% %>=}}{<%paramName%>}<%={{ }}=%>", withString: "\({{paramName}})", options: .LiteralSearch, range: nil){{/pathParams}}
let url = {{projectName}}API.basePath + path let URLString = {{projectName}}API.basePath + path
{{#bodyParam}} {{#bodyParam}}
let parameters = {{paramName}}{{^required}}?{{/required}}.encodeToJSON() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}} let parameters = {{paramName}}{{^required}}?{{/required}}.encodeToJSON() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}}
let nillableParameters: [String:AnyObject?] = {{^queryParams}}[:]{{/queryParams}}{{#queryParams}}{{^secondaryParam}}[{{/secondaryParam}} let nillableParameters: [String:AnyObject?] = {{^queryParams}}{{^formParams}}[:]{{/formParams}}{{#formParams}}{{^secondaryParam}}[{{/secondaryParam}}
"{{paramName}}": {{paramName}}{{#hasMore}},{{/hasMore}}{{^hasMore}}
]{{/hasMore}}{{/formParams}}{{/queryParams}}{{#queryParams}}{{^secondaryParam}}[{{/secondaryParam}}
"{{paramName}}": {{paramName}}{{#hasMore}},{{/hasMore}}{{^hasMore}} "{{paramName}}": {{paramName}}{{#hasMore}},{{/hasMore}}{{^hasMore}}
]{{/hasMore}}{{/queryParams}} ]{{/hasMore}}{{/queryParams}}
let parameters = APIHelper.rejectNil(nillableParameters){{/bodyParam}} let parameters = APIHelper.rejectNil(nillableParameters){{/bodyParam}}
let requestBuilder: RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}>.Type = {{projectName}}API.requestBuilderFactory.getBuilder() let requestBuilder: RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}>.Type = {{projectName}}API.requestBuilderFactory.getBuilder()
return requestBuilder(method: "{{httpMethod}}", URLString: url, parameters: parameters, isBody: {{^queryParams}}true{{/queryParams}}{{#queryParams}}{{^secondaryParam}}false{{/secondaryParam}}{{/queryParams}}) return requestBuilder(method: "{{httpMethod}}", URLString: URLString, parameters: parameters, isBody: {{^queryParams}}{{^formParams}}true{{/formParams}}{{/queryParams}}{{#queryParams}}{{^secondaryParam}}false{{/secondaryParam}}{{/queryParams}}{{#formParams}}{{^secondaryParam}}false{{/secondaryParam}}{{/formParams}})
} }
{{/operation}} {{/operation}}
} }

View File

@ -10,15 +10,15 @@ import Foundation
{{#description}} {{#description}}
/** {{description}} */{{/description}} /** {{description}} */{{/description}}
class {{classname}}: JSONEncodable { public class {{classname}}: JSONEncodable {
{{#vars}}{{#isEnum}} {{#vars}}{{#isEnum}}
enum {{datatypeWithEnum}}: String { {{#allowableValues}}{{#values}} public enum {{datatypeWithEnum}}: String { {{#allowableValues}}{{#values}}
case {{enum}} = "{{raw}}"{{/values}}{{/allowableValues}} case {{enum}} = "{{raw}}"{{/values}}{{/allowableValues}}
} }
{{/isEnum}}{{/vars}} {{/isEnum}}{{/vars}}
{{#vars}}{{#isEnum}}{{#description}}/** {{description}} */ {{#vars}}{{#isEnum}}{{#description}}/** {{description}} */
{{/description}}var {{name}}: {{{datatypeWithEnum}}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/unwrapRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}{{^isEnum}}{{#description}}/** {{description}} */ {{/description}}public var {{name}}: {{{datatypeWithEnum}}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/unwrapRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}{{^isEnum}}{{#description}}/** {{description}} */
{{/description}}var {{name}}: {{{datatype}}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/unwrapRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}} {{/description}}public var {{name}}: {{{datatype}}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/unwrapRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}
{{/vars}} {{/vars}}
// MARK: JSONEncodable // MARK: JSONEncodable

View File

@ -86,7 +86,7 @@ class JavaModelTest extends FlatSpec with Matchers {
vars.get(1).setter should be("setUrls") vars.get(1).setter should be("setUrls")
vars.get(1).datatype should be("List<String>") vars.get(1).datatype should be("List<String>")
vars.get(1).name should be("urls") vars.get(1).name should be("urls")
vars.get(1).defaultValue should be("new ArrayList<String>() ") vars.get(1).defaultValue should be("new ArrayList<String>()")
vars.get(1).baseType should be("List") vars.get(1).baseType should be("List")
vars.get(1).containerType should be("array") vars.get(1).containerType should be("array")
vars.get(1).required should equal(null) vars.get(1).required should equal(null)
@ -114,7 +114,7 @@ class JavaModelTest extends FlatSpec with Matchers {
vars.get(0).setter should be("setTranslations") vars.get(0).setter should be("setTranslations")
vars.get(0).datatype should be("Map<String, String>") vars.get(0).datatype should be("Map<String, String>")
vars.get(0).name should be("translations") vars.get(0).name should be("translations")
vars.get(0).defaultValue should be("new HashMap<String, String>() ") vars.get(0).defaultValue should be("new HashMap<String, String>()")
vars.get(0).baseType should be("Map") vars.get(0).baseType should be("Map")
vars.get(0).containerType should be("map") vars.get(0).containerType should be("map")
vars.get(0).required should equal(null) vars.get(0).required should equal(null)
@ -122,7 +122,7 @@ class JavaModelTest extends FlatSpec with Matchers {
} }
ignore should "convert a model with a map with complex list property" in { it should "convert a model with a map with complex list property" in {
val model = new ModelImpl() val model = new ModelImpl()
.description("a sample model") .description("a sample model")
.property("translations", new MapProperty() .property("translations", new MapProperty()
@ -145,13 +145,33 @@ class JavaModelTest extends FlatSpec with Matchers {
vars.get(0).setter should be("setTranslations") vars.get(0).setter should be("setTranslations")
vars.get(0).datatype should be("Map<String, List<Pet>>") vars.get(0).datatype should be("Map<String, List<Pet>>")
vars.get(0).name should be("translations") vars.get(0).name should be("translations")
vars.get(0).defaultValue should be("new HashMap<String, List<Pet>>() ") vars.get(0).defaultValue should be("new HashMap<String, List<Pet>>()")
vars.get(0).baseType should be("Map") vars.get(0).baseType should be("Map")
vars.get(0).containerType should be("map") vars.get(0).containerType should be("map")
vars.get(0).required should equal(null) vars.get(0).required should equal(null)
vars.get(0).isContainer should equal(true) vars.get(0).isContainer should equal(true)
} }
it should "convert a model with a 2D list property" in {
val model = new ModelImpl().name("sample").property("list2D", new ArrayProperty().items(
new ArrayProperty().items(new RefProperty("Pet"))))
val codegen = new JavaClientCodegen()
val cm = codegen.fromModel("sample", model)
val vars = cm.vars
vars.size should be (1)
val list = vars.get(0)
list.baseName should be("list2D")
list.getter should be("getList2D")
list.setter should be("setList2D")
list.datatype should be("List<List<Pet>>")
list.name should be("list2D")
list.defaultValue should be ("new ArrayList<List<Pet>>()")
list.baseType should be("List")
list.containerType should be("array")
list.required should equal(null)
list.isContainer should equal(true)
}
it should "convert a model with complex properties" in { it should "convert a model with complex properties" in {
val model = new ModelImpl() val model = new ModelImpl()
.description("a sample model") .description("a sample model")
@ -198,7 +218,7 @@ class JavaModelTest extends FlatSpec with Matchers {
vars.get(0).setter should be("setChildren") vars.get(0).setter should be("setChildren")
vars.get(0).datatype should be("List<Children>") vars.get(0).datatype should be("List<Children>")
vars.get(0).name should be("children") vars.get(0).name should be("children")
vars.get(0).defaultValue should be("new ArrayList<Children>() ") vars.get(0).defaultValue should be("new ArrayList<Children>()")
vars.get(0).baseType should be("List") vars.get(0).baseType should be("List")
vars.get(0).containerType should be("array") vars.get(0).containerType should be("array")
vars.get(0).required should equal(null) vars.get(0).required should equal(null)
@ -227,7 +247,7 @@ class JavaModelTest extends FlatSpec with Matchers {
vars.get(0).setter should be("setChildren") vars.get(0).setter should be("setChildren")
vars.get(0).datatype should be("Map<String, Children>") vars.get(0).datatype should be("Map<String, Children>")
vars.get(0).name should be("children") vars.get(0).name should be("children")
vars.get(0).defaultValue should be("new HashMap<String, Children>() ") vars.get(0).defaultValue should be("new HashMap<String, Children>()")
vars.get(0).baseType should be("Map") vars.get(0).baseType should be("Map")
vars.get(0).containerType should be("map") vars.get(0).containerType should be("map")
vars.get(0).required should equal(null) vars.get(0).required should equal(null)

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