Merge branch 'ruby-api-client' into ruby-apiclient

This commit is contained in:
geekerzp 2015-08-20 11:34:07 +08:00
commit 6d58d44542
268 changed files with 13274 additions and 6103 deletions

47
.dockerignore Normal file
View File

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

13
Dockerfile Normal file
View File

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

View File

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

31
bin/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.
*/
import io.swagger.codegen.CliOption;
import io.swagger.codegen.ClientOptInput;
import io.swagger.codegen.ClientOpts;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.DefaultGenerator;
import io.swagger.models.Swagger;
import io.swagger.parser.SwaggerParser;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
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.project.MavenProject;
import config.Config;
import config.ConfigParser;
import java.io.File;
import java.util.ServiceLoader;
@ -66,6 +71,12 @@ public class CodeGenMojo extends AbstractMojo {
@Parameter(name = "language", required = true)
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
@ -90,7 +101,20 @@ public class CodeGenMojo extends AbstractMojo {
if (null != templateDirectory) {
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);
input.setConfig(config);
new DefaultGenerator().opts(input).generate();

View File

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

View File

@ -65,6 +65,8 @@ public interface CodegenConfig {
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);
List<CodegenSecurity> fromSecurity(Map<String, SecuritySchemeDefinition> schemes);

View File

@ -63,7 +63,7 @@ import java.util.regex.Pattern;
public class DefaultCodegen {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);
protected static final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);
protected String outputFolder = "";
protected Set<String> defaultIncludes = new HashSet<String>();
@ -80,6 +80,7 @@ public class DefaultCodegen {
protected List<SupportingFile> supportingFiles = new ArrayList<SupportingFile>();
protected List<CliOption> cliOptions = new ArrayList<CliOption>();
protected boolean skipOverwrite;
protected boolean supportsInheritance = false;
public List<CliOption> cliOptions() {
return cliOptions;
@ -229,6 +230,11 @@ public class DefaultCodegen {
}
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;
}
@ -426,14 +432,6 @@ public class DefaultCodegen {
return dp.getDefault().toString();
}
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 {
return "null";
}
@ -510,6 +508,10 @@ public class DefaultCodegen {
}
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);
if (reservedWords.contains(name)) {
m.name = escapeReservedWord(name);
@ -529,12 +531,59 @@ public class DefaultCodegen {
// TODO
} else if (model instanceof ComposedModel) {
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 String parentModel = toModelName(parent.getSimpleRef());
m.parent = parentModel;
addImport(m, parentModel);
final ModelImpl child = (ModelImpl) composed.getChild();
addVars(m, child.getProperties(), child.getRequired());
if (parent != null) {
final String parentRef = toModelName(parent.getSimpleRef());
m.parent = parentRef;
addImport(m, parentRef);
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 {
ModelImpl impl = (ModelImpl) model;
if (impl.getAdditionalProperties() != null) {
@ -557,7 +606,7 @@ public class DefaultCodegen {
public CodegenProperty fromProperty(String name, Property p) {
if (p == null) {
LOGGER.error("unexpected missing property for name " + null);
LOGGER.error("unexpected missing property for name " + name);
return null;
}
CodegenProperty property = CodegenModelFactory.newInstance(CodegenModelType.PROPERTY);
@ -1173,7 +1222,9 @@ public class DefaultCodegen {
if (mappedType != null) {
addImport(m, mappedType);
}
} /**
}
/**
* Underscore the given word.
*
* @param word The word
@ -1235,9 +1286,8 @@ public class DefaultCodegen {
} else {
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
@ -1258,7 +1308,13 @@ public class DefaultCodegen {
name = name.substring(0, 1).toLowerCase() + name.substring(1);
}
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)
Pattern p = Pattern.compile("\\/(.?)");
Matcher m = p.matcher(word);

View File

@ -2,6 +2,8 @@ package io.swagger.codegen;
import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Template;
import io.swagger.models.ComposedModel;
import io.swagger.models.Contact;
import io.swagger.models.Info;
import io.swagger.models.License;
@ -11,7 +13,9 @@ import io.swagger.models.Path;
import io.swagger.models.Swagger;
import io.swagger.models.auth.OAuth2Definition;
import io.swagger.models.auth.SecuritySchemeDefinition;
import io.swagger.models.parameters.Parameter;
import io.swagger.util.Json;
import org.apache.commons.io.IOUtils;
import java.io.File;
@ -21,6 +25,8 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
@ -106,10 +112,8 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
if (swagger.getBasePath() != null) {
hostBuilder.append(swagger.getBasePath());
} else {
hostBuilder.append("/");
}
String contextPath = swagger.getBasePath() == null ? "/" : swagger.getBasePath();
String contextPath = swagger.getBasePath() == null ? "" : swagger.getBasePath();
String basePath = hostBuilder.toString();
@ -119,11 +123,13 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
// models
Map<String, Model> definitions = swagger.getDefinitions();
if (definitions != null) {
for (String name : definitions.keySet()) {
List<String> sortedModelKeys = sortModelsByInheritance(definitions);
for (String name : sortedModelKeys) {
Model model = definitions.get(name);
Map<String, Model> modelMap = new HashMap<String, Model>();
modelMap.put(name, model);
Map<String, Object> models = processModels(config, modelMap);
Map<String, Object> models = processModels(config, modelMap, definitions);
models.putAll(config.additionalProperties());
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) {
Map<String, List<CodegenOperation>> ops = new HashMap<String, List<CodegenOperation>>();
for (String resourcePath : paths.keySet()) {
Path path = paths.get(resourcePath);
processOperation(resourcePath, "get", path.getGet(), ops);
processOperation(resourcePath, "put", path.getPut(), ops);
processOperation(resourcePath, "post", path.getPost(), ops);
processOperation(resourcePath, "delete", path.getDelete(), ops);
processOperation(resourcePath, "patch", path.getPatch(), ops);
processOperation(resourcePath, "options", path.getOptions(), ops);
processOperation(resourcePath, "get", path.getGet(), ops, path);
processOperation(resourcePath, "put", path.getPut(), ops, path);
processOperation(resourcePath, "post", path.getPost(), ops, path);
processOperation(resourcePath, "delete", path.getDelete(), ops, path);
processOperation(resourcePath, "patch", path.getPatch(), ops, path);
processOperation(resourcePath, "options", path.getOptions(), ops, path);
}
return ops;
}
@ -350,14 +402,35 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
return map.get(name);
}
public void processOperation(String resourcePath, String httpMethod, Operation operation, Map<String, List<CodegenOperation>> operations) {
public void processOperation(String resourcePath, String httpMethod, Operation operation, Map<String, List<CodegenOperation>> operations, Path path) {
if (operation != null) {
List<String> tags = operation.getTags();
if (tags == null) {
tags = new ArrayList<String>();
tags.add("default");
}
/*
build up a set of parameter "ids" defined at the operation level
per the swagger 2.0 spec "A unique parameter is defined by a combination of a name and location"
i'm assuming "location" == "in"
*/
Set<String> operationParameters = new HashSet<String>();
if (operation.getParameters() != null) {
for (Parameter parameter : operation.getParameters()) {
operationParameters.add(generateParameterId(parameter));
}
}
//need to propagate path level down to the operation
if(path.getParameters() != null) {
for (Parameter parameter : path.getParameters()) {
//skip propagation if a parameter with the same name is already defined at the operation level
if (!operationParameters.contains(generateParameterId(parameter))) {
operation.addParameter(parameter);
}
}
}
for (String tag : tags) {
CodegenOperation co = config.fromOperation(resourcePath, httpMethod, operation, swagger.getDefinitions());
@ -392,7 +465,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
authMethods.put(securityName, oauth2Operation);
} else {
authMethods.put(securityName, securityDefinition);
authMethods.put(securityName, securityDefinition);
}
}
}
@ -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) {
// remove spaces and make strong case
String[] parts = tag.split(" ");
@ -475,14 +552,14 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
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>();
objs.put("package", config.modelPackage());
List<Object> models = new ArrayList<Object>();
Set<String> allImports = new LinkedHashSet<String>();
for (String key : definitions.keySet()) {
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>();
mo.put("model", cm);
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
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));
}
@ -396,4 +401,4 @@ public class AkkaScalaClientCodegen extends DefaultCodegen implements CodegenCon
}
}
}
}

View File

@ -13,6 +13,8 @@ import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client";
protected String groupId = "io.swagger";
@ -168,6 +170,11 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
@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");

View File

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

View File

@ -14,6 +14,8 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String packageName = "IO.Swagger";
protected String packageVersion = "1.0.0";
@ -237,6 +239,11 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
@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");

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.HashSet;
import org.apache.commons.lang.StringUtils;
public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client";
protected String groupId = "io.swagger";
protected String artifactId = "swagger-java-client";
protected String artifactVersion = "1.0.0";
protected String sourceFolder = "src/main/java";
protected String localVariablePrefix = "";
public JavaClientCodegen() {
super();
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("artifactVersion", "artifact version in generated pom.xml"));
cliOptions.add(new CliOption("sourceFolder", "source folder for generated code"));
cliOptions.add(new CliOption("localVariablePrefix", "prefix for generated code members and local variables"));
}
public CodegenType getTag() {
@ -109,6 +112,11 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
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);
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("ApiClient.mustache", invokerFolder, "ApiClient.java"));
@ -205,6 +213,18 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
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
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
@ -222,6 +242,11 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
@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");
@ -249,4 +274,8 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
public void setSourceFolder(String 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
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
String basePath = resourcePath;

View File

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

View File

@ -16,6 +16,8 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
protected Set<String> foundationClasses = new HashSet<String>();
protected String podName = "SwaggerClient";
@ -57,7 +59,7 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.clear();
typeMapping.put("enum", "NSString");
typeMapping.put("Date", "NSDate");
typeMapping.put("date", "NSDate");
typeMapping.put("DateTime", "NSDate");
typeMapping.put("boolean", "NSNumber");
typeMapping.put("string", "NSString");
@ -213,21 +215,22 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
Property inner = ap.getItems();
String innerType = getSwaggerType(inner);
// In this codition, type of property p is array of primitive,
// return container type with pointer, e.g. `NSArray*'
if (languageSpecificPrimitives.contains(innerType)) {
return getSwaggerType(p) + "*";
}
// In this codition, type of property p is array of model,
// return container type combine inner type with pointer, e.g. `NSArray<SWGTag>*'
String innerTypeDeclaration = getTypeDeclaration(inner);
if (innerTypeDeclaration.endsWith("*")) {
innerTypeDeclaration = innerTypeDeclaration.substring(0, innerTypeDeclaration.length() - 1);
}
return getSwaggerType(p) + "<" + innerTypeDeclaration + ">*";
// In this codition, type of property p is array of primitive,
// return container type with pointer, e.g. `NSArray* /* NSString */'
if (languageSpecificPrimitives.contains(innerType)) {
return getSwaggerType(p) + "*" + " /* " + innerTypeDeclaration + " */";
}
// In this codition, type of property p is array of model,
// return container type combine inner type with pointer, e.g. `NSArray<SWGTag>*'
else {
return getSwaggerType(p) + "<" + innerTypeDeclaration + ">*";
}
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
@ -358,6 +361,11 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
@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");

View File

@ -9,11 +9,12 @@ 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.HashSet;
import org.apache.commons.lang.StringUtils;
public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String moduleName = "SwaggerClient";
protected String moduleVersion = "1.0.0";
@ -158,15 +159,17 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String toVarName(String name) {
// return the name in underscore style
// PhoneNumber => phone_number
name = underscore(name);
// parameter name starting with number won't compile
// need to escape it by appending _ at the beginning
if (name.matches("^[0-9]")) {
if (name.matches("^\\d.*")) {
name = "_" + name;
}
// return the name in underscore style
// PhoneNumber => phone_number
return underscore(name);
return name;
}
@Override
@ -213,6 +216,11 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
@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");

View File

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

View File

@ -12,6 +12,8 @@ import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class Python3ClientCodegen extends DefaultCodegen implements CodegenConfig {
String module = "client";
@ -201,6 +203,11 @@ public class Python3ClientCodegen extends DefaultCodegen implements CodegenConfi
@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");

View File

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

View File

@ -15,6 +15,8 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
public class RetrofitClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client";
protected String groupId = "io.swagger";
@ -171,6 +173,11 @@ public class RetrofitClientCodegen extends DefaultCodegen implements CodegenConf
@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");

View File

@ -13,6 +13,8 @@ import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import org.apache.commons.lang.StringUtils;
public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String gemName = null;
protected String moduleName = null;
@ -264,6 +266,11 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
@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");

View File

@ -24,6 +24,8 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
public class ScalaClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client";
protected String groupId = "io.swagger";
@ -209,6 +211,11 @@ public class ScalaClientCodegen extends DefaultCodegen implements CodegenConfig
@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");

View File

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

View File

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

View File

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

View File

@ -100,7 +100,7 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("number", "Double");
typeMapping.put("double", "Double");
typeMapping.put("object", "String");
typeMapping.put("file", "NSData");
typeMapping.put("file", "NSURL");
importMapping = new HashMap<String, String>();
@ -109,6 +109,17 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
StringUtils.join(RESPONSE_LIBRARIES, ", ") + " are available."));
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"));
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
@ -143,6 +154,7 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
additionalProperties.put("usePromiseKit", true);
}
supportingFiles.add(new SupportingFile("Podspec.mustache", "", projectName + ".podspec"));
supportingFiles.add(new SupportingFile("Cartfile.mustache", "", "Cartfile"));
supportingFiles.add(new SupportingFile("APIHelper.mustache", sourceFolder, "APIHelper.swift"));
supportingFiles.add(new SupportingFile("AlamofireImplementations.mustache", sourceFolder,
@ -283,4 +295,4 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
return builder.toString();
}
}
}

View File

@ -25,6 +25,8 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
public class TizenClientCodegen extends DefaultCodegen implements CodegenConfig {
protected static String PREFIX = "Sami";
protected Set<String> foundationClasses = new HashSet<String>();
@ -265,6 +267,11 @@ public class TizenClientCodegen extends DefaultCodegen implements CodegenConfig
@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");

View File

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

View File

@ -1,171 +1,24 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.models.properties.*;
import io.swagger.codegen.SupportingFile;
import java.util.*;
import java.io.File;
public class TypeScriptNodeClientCodegen extends AbstractTypeScriptClientCodegen {
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 String getName() {
return "typescript-node";
}
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}
@Override
public String getHelp() {
return "Generates a TypeScript nodejs client library.";
}
@Override
public String getName() {
return "typescript-node";
}
public TypeScriptNodeClientCodegen() {
super();
outputFolder = "generated-code/typescript-node";
templateDir = "TypeScript-node";
supportingFiles.add(new SupportingFile("api.mustache", null, "api.ts"));
}
@Override
public String getHelp() {
return "Generates a TypeScript nodejs client library.";
}
public TypeScriptNodeClientCodegen() {
super();
outputFolder = "generated-code/typescript-node";
modelTemplateFiles.put("model.mustache", ".ts");
apiTemplateFiles.put("api.mustache", ".ts");
templateDir = "TypeScript-node";
apiPackage = "api";
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)) {
if(json != null && json.startsWith("\"") && json.endsWith("\"") && json.length() > 1)
return json.substring(1, json.length() - 2);
return json.substring(1, json.length() - 1);
else
return json;
}

View File

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

View File

@ -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.AsyncScalaClientCodegen
io.swagger.codegen.languages.CSharpClientCodegen
io.swagger.codegen.languages.FlashClientCodegen
io.swagger.codegen.languages.JavaClientCodegen
io.swagger.codegen.languages.JaxRSServerCodegen
io.swagger.codegen.languages.JavaInflectorServerCodegen
io.swagger.codegen.languages.NodeJSServerCodegen
io.swagger.codegen.languages.ObjcClientCodegen
io.swagger.codegen.languages.PerlClientCodegen
@ -26,3 +28,4 @@ io.swagger.codegen.languages.TizenClientCodegen
io.swagger.codegen.languages.TypeScriptAngularClientCodegen
io.swagger.codegen.languages.TypeScriptNodeClientCodegen
io.swagger.codegen.languages.AkkaScalaClientCodegen
io.swagger.codegen.languages.CsharpDotNet2ClientCodegen

View File

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

View File

@ -1,73 +1,245 @@
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 */
{{#operations}}
{{#models}}
{{#model}}
{{#description}}
/**
* {{{description}}}
*/
{{/description}}
export class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{
{{#vars}}
{{#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}}
export class {{classname}} {
private basePath = '{{contextPath}}';
constructor(private url: string, private username: string, private password: string, basePath?: string) {
if (basePath) {
this.basePath = basePath;
}
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}}
}
{{#operation}}
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}}';
{{#pathParams}}
path = path.replace('{' + '{{paramName}}' + '}', String({{paramName}}));
{{/pathParams}}
var queryParameters: any = {};
var headerParams: any = {};
{{#allParams}}{{#required}}
// verify required parameter '{{paramName}}' is set
if (!{{paramName}}) {
throw new Error('Missing required parameter {{paramName}} when calling {{nickname}}');
}
{{/required}}{{/allParams}}
{{#queryParams}}if ({{paramName}} !== undefined) {
queryParameters['{{paramName}}'] = {{paramName}};
}
{{/queryParams}}
{{#headerParams}}headerParams['{{paramName}}'] = {{paramName}};
{{/headerParams}}
var deferred = promise.defer<{ response: http.ClientResponse; {{#returnType}}body: {{{returnType}}}; {{/returnType}} }>();
request({
method: '{{httpMethod}}',
qs: queryParameters,
uri: path,
json: true,
{{#bodyParam}}body: {{paramName}},
{{/bodyParam}}
auth: {
username: this.username, password: this.password
}
}, (error, response, body) => {
if (error) {
deferred.reject(error);
} else {
if (response.statusCode >= 200 && response.statusCode <= 299) {
deferred.resolve({ response: response, body: body });
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) {
this.basePath = basePath;
}
} else {
deferred.reject({ response: response, body: body });
if (basePathOrUsername) {
this.basePath = basePathOrUsername
}
}
}
});
}
{{#authMethods}}
{{#isBasic}}
return deferred.promise;
}
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}} }> {
var path = this.url + this.basePath + '{{path}}';
{{#pathParams}}
path = path.replace('{' + '{{paramName}}' + '}', String({{paramName}}));
{{/pathParams}}
var queryParameters: any = {};
var headerParams: any = {};
var formParams: any = {};
{{#allParams}}
{{#required}}
// verify required parameter '{{paramName}}' is set
if (!{{paramName}}) {
throw new Error('Missing required parameter {{paramName}} when calling {{nickname}}');
}
{{/required}}
{{/allParams}}
{{#queryParams}}
if ({{paramName}} !== undefined) {
queryParameters['{{paramName}}'] = {{paramName}};
}
{{/queryParams}}
{{#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 requestOptions: request.Options = {
method: '{{httpMethod}}',
qs: queryParameters,
headers: headerParams,
uri: path,
json: true,
{{#bodyParam}}
body: {{paramName}},
{{/bodyParam}}
}
{{#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) {
deferred.reject(error);
} else {
if (response.statusCode >= 200 && response.statusCode <= 299) {
deferred.resolve({ response: response, body: body });
} else {
deferred.reject({ response: response, body: body });
}
}
});
return deferred.promise;
}
{{/operation}}
}
{{/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)) {
if(json != null && json.startsWith("\"") && json.endsWith("\"") && json.length() > 1)
return json.substring(1, json.length() - 2);
return json.substring(1, json.length() - 1);
else
return json;
}

View File

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

View File

@ -104,11 +104,11 @@ namespace {{packageName}}.Api
String postBody = null;
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}}
{{#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}}
{{#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}}
{{#formParams}}if ({{paramName}} != null) {{#isFile}}fileParams.Add("{{baseName}}", ApiClient.ParameterToFile("{{baseName}}", {{paramName}}));{{/isFile}}{{^isFile}}formParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // form parameter{{/isFile}}
{{/formParams}}
@ -150,11 +150,11 @@ namespace {{packageName}}.Api
String postBody = null;
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}}
{{#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}}
{{#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}}
{{#formParams}}if ({{paramName}} != null) {{#isFile}}fileParams.Add("{{baseName}}", ApiClient.ParameterToFile("{{baseName}}", {{paramName}}));{{/isFile}}{{^isFile}}formParams.Add("{{baseName}}", ApiClient.ParameterToString({{paramName}})); // form parameter{{/isFile}}
{{/formParams}}

View File

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

View File

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

View File

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

View File

@ -1,7 +1,5 @@
#import "{{classPrefix}}ApiClient.h"
@implementation {{classPrefix}}ApiClient
NSString *const {{classPrefix}}ResponseObjectErrorKey = @"{{classPrefix}}ResponseObject";
static long requestId = 0;
@ -9,41 +7,75 @@ static bool offlineState = false;
static NSMutableSet * queuedRequests = nil;
static bool cacheEnabled = false;
static AFNetworkReachabilityStatus reachabilityStatus = AFNetworkReachabilityStatusNotReachable;
static NSOperationQueue* sharedQueue;
static void (^reachabilityChangeBlock)(int);
@implementation {{classPrefix}}ApiClient
- (instancetype)init {
NSString *baseUrl = [[{{classPrefix}}Configuration sharedConfig] host];
return [self initWithBaseURL:[NSURL URLWithString:baseUrl]];
}
- (instancetype)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if (self) {
self.requestSerializer = [AFJSONRequestSerializer serializer];
self.responseSerializer = [AFJSONResponseSerializer serializer];
// configure reachability
[self configureCacheReachibility];
}
return self;
}
+ (void)initialize {
if (self == [{{classPrefix}}ApiClient class]) {
queuedRequests = [[NSMutableSet alloc] init];
// initialize URL cache
[self configureCacheWithMemoryAndDiskCapacity:4*1024*1024 diskSize:32*1024*1024];
}
}
#pragma mark - Setter Methods
+ (void) setOfflineState:(BOOL) state {
offlineState = state;
}
+ (void) setCacheEnabled:(BOOL)enabled {
cacheEnabled = enabled;
}
- (void)setHeaderValue:(NSString*) value
forKey:(NSString*) forKey {
[self.requestSerializer setValue:value forHTTPHeaderField:forKey];
}
#pragma mark - Log Methods
- (void)logResponse:(AFHTTPRequestOperation *)operation
forRequest:(NSURLRequest *)request
error:(NSError*)error {
{{classPrefix}}Configuration *config = [{{classPrefix}}Configuration sharedConfig];
NSString *message = [NSString stringWithFormat:@"\n[DEBUG] Request body \n~BEGIN~\n %@\n~END~\n"\
"[DEBUG] HTTP Response body \n~BEGIN~\n %@\n~END~\n",
[[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding],
operation.responseString];
if (config.loggingFileHanlder) {
[config.loggingFileHanlder seekToEndOfFile];
[config.loggingFileHanlder writeData:[message dataUsingEncoding:NSUTF8StringEncoding]];
}
NSLog(@"%@", message);
}
#pragma mark - Cache Methods
+ (void) setCacheEnabled:(BOOL)enabled {
cacheEnabled = enabled;
}
+(void)clearCache {
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}
#pragma mark -
+(void)configureCacheWithMemoryAndDiskCapacity: (unsigned long) memorySize
diskSize: (unsigned long) diskSize {
NSAssert(memorySize > 0, @"invalid in-memory cache size");
@ -58,43 +90,7 @@ static void (^reachabilityChangeBlock)(int);
[NSURLCache setSharedURLCache:cache];
}
+(NSOperationQueue*) sharedQueue {
return sharedQueue;
}
+({{classPrefix}}ApiClient *)sharedClientFromPool:(NSString *)baseUrl {
static NSMutableDictionary *_pool = nil;
if (queuedRequests == nil) {
queuedRequests = [[NSMutableSet alloc]init];
}
if(_pool == nil) {
// setup static vars
// create queue
sharedQueue = [[NSOperationQueue alloc] init];
// create pool
_pool = [[NSMutableDictionary alloc] init];
// initialize URL cache
[{{classPrefix}}ApiClient configureCacheWithMemoryAndDiskCapacity:4*1024*1024 diskSize:32*1024*1024];
// configure reachability
[{{classPrefix}}ApiClient configureCacheReachibilityForHost:baseUrl];
}
@synchronized(self) {
{{classPrefix}}ApiClient * client = [_pool objectForKey:baseUrl];
if (client == nil) {
client = [[{{classPrefix}}ApiClient alloc] initWithBaseURL:[NSURL URLWithString:baseUrl]];
[_pool setValue:client forKey:baseUrl ];
if([[{{classPrefix}}Configuration sharedConfig] debug])
NSLog(@"new client for path %@", baseUrl);
}
if([[{{classPrefix}}Configuration sharedConfig] debug])
NSLog(@"returning client for path %@", baseUrl);
return client;
}
}
#pragma mark - Utility Methods
/*
* Detect `Accept` from accepts
@ -104,13 +100,13 @@ static void (^reachabilityChangeBlock)(int);
if (accepts == nil || [accepts count] == 0) {
return @"";
}
NSMutableArray *lowerAccepts = [[NSMutableArray alloc] initWithCapacity:[accepts count]];
[accepts enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[lowerAccepts addObject:[obj lowercaseString]];
}];
if ([lowerAccepts containsObject:@"application/json"]) {
return @"application/json";
}
@ -127,7 +123,7 @@ static void (^reachabilityChangeBlock)(int);
if (contentTypes == nil || [contentTypes count] == 0) {
return @"application/json";
}
NSMutableArray *lowerContentTypes = [[NSMutableArray alloc] initWithCapacity:[contentTypes count]];
[contentTypes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[lowerContentTypes addObject:[obj lowercaseString]];
@ -141,11 +137,23 @@ static void (^reachabilityChangeBlock)(int);
}
}
-(void)setHeaderValue:(NSString*) value
forKey:(NSString*) forKey {
[self.requestSerializer setValue:value forHTTPHeaderField:forKey];
+ (NSString*)escape:(id)unescaped {
if([unescaped isKindOfClass:[NSString class]]){
return (NSString *)CFBridgingRelease
(CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef) unescaped,
NULL,
(CFStringRef)@"!*'();:@&=+$,/?%#[]",
kCFStringEncodingUTF8));
}
else {
return [NSString stringWithFormat:@"%@", unescaped];
}
}
#pragma mark - Request Methods
+(unsigned long)requestQueueSize {
return [queuedRequests count];
}
@ -171,46 +179,28 @@ static void (^reachabilityChangeBlock)(int);
[queuedRequests removeObject:requestId];
}
+(NSString*) escape:(id)unescaped {
if([unescaped isKindOfClass:[NSString class]]){
return (NSString *)CFBridgingRelease
(CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef) unescaped,
NULL,
(CFStringRef)@"!*'();:@&=+$,/?%#[]",
kCFStringEncodingUTF8));
}
else {
return [NSString stringWithFormat:@"%@", unescaped];
}
}
-(Boolean) executeRequestWithId:(NSNumber*) requestId {
NSSet* matchingItems = [queuedRequests objectsPassingTest:^BOOL(id obj, BOOL *stop) {
if([obj intValue] == [requestId intValue])
return TRUE;
else return FALSE;
if([obj intValue] == [requestId intValue]) {
return YES;
}
else {
return NO;
}
}];
if(matchingItems.count == 1) {
if([[{{classPrefix}}Configuration sharedConfig] debug])
NSLog(@"removing request id %@", requestId);
[queuedRequests removeObject:requestId];
return true;
return YES;
}
else {
return NO;
}
else
return false;
}
-(id)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
self.requestSerializer = [AFJSONRequestSerializer serializer];
self.responseSerializer = [AFJSONResponseSerializer serializer];
if (!self)
return nil;
return self;
}
#pragma mark - Reachability Methods
+(AFNetworkReachabilityStatus) getReachabilityStatus {
return reachabilityStatus;
@ -220,12 +210,8 @@ static void (^reachabilityChangeBlock)(int);
reachabilityChangeBlock = changeBlock;
}
+(void) setOfflineState:(BOOL) state {
offlineState = state;
}
+(void) configureCacheReachibilityForHost:(NSString*)host {
[[{{classPrefix}}ApiClient sharedClientFromPool:host].reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
- (void) configureCacheReachibility {
[self.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
reachabilityStatus = status;
switch (status) {
case AFNetworkReachabilityStatusUnknown:
@ -254,16 +240,352 @@ static void (^reachabilityChangeBlock)(int);
default:
break;
}
// call the reachability block, if configured
if(reachabilityChangeBlock != nil) {
reachabilityChangeBlock(status);
}
}];
[[{{classPrefix}}ApiClient sharedClientFromPool:host].reachabilityManager startMonitoring];
[self.reachabilityManager startMonitoring];
}
-(NSString*) pathWithQueryParamsToString:(NSString*) path
queryParams:(NSDictionary*) queryParams {
#pragma mark - Deserialize methods
- (id) deserialize:(id) data class:(NSString *) class {
NSRegularExpression *regexp = nil;
NSTextCheckingResult *match = nil;
NSMutableArray *resultArray = nil;
NSMutableDictionary *resultDict = nil;
NSString *innerType = nil;
// return nil if data is nil or class is nil
if (!data || !class) {
return nil;
}
// remove "*" from class, if ends with "*"
if ([class hasSuffix:@"*"]) {
class = [class substringToIndex:[class length] - 1];
}
// pure object
if ([class isEqualToString:@"NSObject"]) {
return [[NSObject alloc] init];
}
// list of models
NSString *arrayOfModelsPat = @"NSArray<(.+)>";
regexp = [NSRegularExpression regularExpressionWithPattern:arrayOfModelsPat
options:NSRegularExpressionCaseInsensitive
error:nil];
match = [regexp firstMatchInString:class
options:0
range:NSMakeRange(0, [class length])];
if (match) {
innerType = [class substringWithRange:[match rangeAtIndex:1]];
resultArray = [NSMutableArray arrayWithCapacity:[data count]];
[data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[resultArray addObject:[self deserialize:obj class:innerType]];
}
];
return resultArray;
}
// list of primitives
NSString *arrayOfPrimitivesPat = @"NSArray\\* /\\* (.+) \\*/";
regexp = [NSRegularExpression regularExpressionWithPattern:arrayOfPrimitivesPat
options:NSRegularExpressionCaseInsensitive
error:nil];
match = [regexp firstMatchInString:class
options:0
range:NSMakeRange(0, [class length])];
if (match) {
innerType = [class substringWithRange:[match rangeAtIndex:1]];
resultArray = [NSMutableArray arrayWithCapacity:[data count]];
[data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[resultArray addObject:[self deserialize:obj class:innerType]];
}];
return resultArray;
}
// map
NSString *dictPat = @"NSDictionary\\* /\\* (.+?), (.+) \\*/";
regexp = [NSRegularExpression regularExpressionWithPattern:dictPat
options:NSRegularExpressionCaseInsensitive
error:nil];
match = [regexp firstMatchInString:class
options:0
range:NSMakeRange(0, [class length])];
if (match) {
NSString *valueType = [class substringWithRange:[match rangeAtIndex:2]];
resultDict = [NSMutableDictionary dictionaryWithCapacity:[data count]];
[data enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[resultDict setValue:[self deserialize:obj class:valueType] forKey:key];
}];
return resultDict;
}
// primitives
NSArray *primitiveTypes = @[@"NSString", @"NSDate", @"NSNumber"];
if ([primitiveTypes containsObject:class]) {
if ([class isEqualToString:@"NSString"]) {
return [NSString stringWithString:data];
}
else if ([class isEqualToString:@"NSDate"]) {
return [NSDate dateWithISO8601String:data];
}
else if ([class isEqualToString:@"NSNumber"]) {
// NSNumber from NSNumber
if ([data isKindOfClass:[NSNumber class]]) {
return data;
}
else if ([data isKindOfClass:[NSString class]]) {
// NSNumber (NSCFBoolean) from NSString
if ([[data lowercaseString] isEqualToString:@"true"] || [[data lowercaseString] isEqualToString:@"false"]) {
return [NSNumber numberWithBool:[data boolValue]];
// NSNumber from NSString
} else {
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
return [formatter numberFromString:data];
}
}
}
}
// model
Class ModelClass = NSClassFromString(class);
if ([ModelClass instancesRespondToSelector:@selector(initWithDictionary:error:)]) {
return [[ModelClass alloc] initWithDictionary:data error:nil];
}
return nil;
}
#pragma mark - Operation Methods
- (void) operationWithCompletionBlock: (NSURLRequest *)request
requestId: (NSNumber *) requestId
completionBlock: (void (^)(id, NSError *))completionBlock {
AFHTTPRequestOperation *op = [self HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id response) {
if([self executeRequestWithId:requestId]) {
if([[{{classPrefix}}Configuration sharedConfig] debug]) {
[self logResponse:operation forRequest:request error:nil];
}
completionBlock(response, nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if([self executeRequestWithId:requestId]) {
NSMutableDictionary *userInfo = [error.userInfo mutableCopy];
if(operation.responseObject) {
// Add in the (parsed) response body.
userInfo[{{classPrefix}}ResponseObjectErrorKey] = operation.responseObject;
}
NSError *augmentedError = [error initWithDomain:error.domain code:error.code userInfo:userInfo];
if([[{{classPrefix}}Configuration sharedConfig] debug])
[self logResponse:nil forRequest:request error:augmentedError];
completionBlock(nil, augmentedError);
}
}];
[self.operationQueue addOperation:op];
}
- (void) downloadOperationWithCompletionBlock: (NSURLRequest *)request
requestId: (NSNumber *) requestId
completionBlock: (void (^)(id, NSError *))completionBlock {
AFHTTPRequestOperation *op = [self HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id responseObject) {
{{classPrefix}}Configuration *config = [{{classPrefix}}Configuration sharedConfig];
NSString *directory = nil;
if (config.tempFolderPath) {
directory = config.tempFolderPath;
}
else {
directory = NSTemporaryDirectory();
}
NSDictionary *headers = operation.response.allHeaderFields;
NSString *filename = nil;
if ([headers objectForKey:@"Content-Disposition"]) {
NSString *pattern = @"filename=['\"]?([^'\"\\s]+)['\"]?";
NSRegularExpression *regexp = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionCaseInsensitive
error:nil];
NSString *contentDispositionHeader = [headers objectForKey:@"Content-Disposition"];
NSTextCheckingResult *match = [regexp firstMatchInString:contentDispositionHeader
options:0
range:NSMakeRange(0, [contentDispositionHeader length])];
filename = [contentDispositionHeader substringWithRange:[match rangeAtIndex:1]];
}
else {
filename = [NSString stringWithFormat:@"%@", [[NSProcessInfo processInfo] globallyUniqueString]];
}
NSString *filepath = [directory stringByAppendingPathComponent:filename];
NSURL *file = [NSURL fileURLWithPath:filepath];
[operation.responseData writeToURL:file atomically:YES];
completionBlock(file, nil);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if ([self executeRequestWithId:requestId]) {
NSMutableDictionary *userInfo = [error.userInfo mutableCopy];
if (operation.responseObject) {
userInfo[{{classPrefix}}ResponseObjectErrorKey] = operation.responseObject;
}
NSError *augmentedError = [error initWithDomain:error.domain code:error.code userInfo:userInfo];
if ([[{{classPrefix}}Configuration sharedConfig] debug]) {
[self logResponse:nil forRequest:request error:augmentedError];
}
completionBlock(nil, augmentedError);
}
}];
[self.operationQueue addOperation:op];
}
#pragma mark - Perform Request Methods
-(NSNumber*) requestWithCompletionBlock: (NSString*) path
method: (NSString*) method
queryParams: (NSDictionary*) queryParams
formParams: (NSDictionary *) formParams
files: (NSDictionary *) files
body: (id) body
headerParams: (NSDictionary*) headerParams
authSettings: (NSArray *) authSettings
requestContentType: (NSString*) requestContentType
responseContentType: (NSString*) responseContentType
responseType: (NSString *) responseType
completionBlock: (void (^)(id, NSError *))completionBlock {
// setting request serializer
if ([requestContentType isEqualToString:@"application/json"]) {
self.requestSerializer = [{{classPrefix}}JSONRequestSerializer serializer];
}
else if ([requestContentType isEqualToString:@"application/x-www-form-urlencoded"]) {
self.requestSerializer = [AFHTTPRequestSerializer serializer];
}
else if ([requestContentType isEqualToString:@"multipart/form-data"]) {
self.requestSerializer = [AFHTTPRequestSerializer serializer];
}
else {
NSAssert(false, @"unsupport request type %@", requestContentType);
}
// setting response serializer
if ([responseContentType isEqualToString:@"application/json"]) {
self.responseSerializer = [{{classPrefix}}JSONResponseSerializer serializer];
}
else {
self.responseSerializer = [AFHTTPResponseSerializer serializer];
}
// auth setting
[self updateHeaderParams:&headerParams queryParams:&queryParams WithAuthSettings:authSettings];
NSMutableURLRequest * request = nil;
NSString* pathWithQueryParams = [self pathWithQueryParamsToString:path queryParams:queryParams];
if ([pathWithQueryParams hasPrefix:@"/"]) {
pathWithQueryParams = [pathWithQueryParams substringFromIndex:1];
}
NSString* urlString = [[NSURL URLWithString:pathWithQueryParams relativeToURL:self.baseURL] absoluteString];
if (files.count > 0) {
request = [self.requestSerializer multipartFormRequestWithMethod:@"POST"
URLString:urlString
parameters:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formParams enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSData *data = [obj dataUsingEncoding:NSUTF8StringEncoding];
[formData appendPartWithFormData:data name:key];
}];
[files enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSURL *filePath = (NSURL *)obj;
[formData appendPartWithFileURL:filePath name:key error:nil];
}];
} error:nil];
}
else {
if (formParams) {
request = [self.requestSerializer requestWithMethod:method
URLString:urlString
parameters:formParams
error:nil];
}
if (body) {
request = [self.requestSerializer requestWithMethod:method
URLString:urlString
parameters:body
error:nil];
}
}
BOOL hasHeaderParams = false;
if(headerParams != nil && [headerParams count] > 0) {
hasHeaderParams = true;
}
if(offlineState) {
NSLog(@"%@ cache forced", path);
[request setCachePolicy:NSURLRequestReturnCacheDataDontLoad];
}
else if(!hasHeaderParams && [method isEqualToString:@"GET"] && cacheEnabled) {
NSLog(@"%@ cache enabled", path);
[request setCachePolicy:NSURLRequestUseProtocolCachePolicy];
}
else {
NSLog(@"%@ cache disabled", path);
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
}
if(hasHeaderParams){
for(NSString * key in [headerParams keyEnumerator]){
[request setValue:[headerParams valueForKey:key] forHTTPHeaderField:key];
}
}
[self.requestSerializer setValue:responseContentType forHTTPHeaderField:@"Accept"];
// Always disable cookies!
[request setHTTPShouldHandleCookies:NO];
NSNumber* requestId = [{{classPrefix}}ApiClient queueRequest];
if ([responseType isEqualToString:@"NSURL*"]) {
[self downloadOperationWithCompletionBlock:request requestId:requestId completionBlock:^(id data, NSError *error) {
completionBlock(data, error);
}];
}
else {
[self operationWithCompletionBlock:request requestId:requestId completionBlock:^(id data, NSError *error) {
completionBlock([self deserialize:data class:responseType], error);
}];
}
return requestId;
}
#pragma mark -
- (NSString*) pathWithQueryParamsToString:(NSString*) path
queryParams:(NSDictionary*) queryParams {
NSString * separator = nil;
int counter = 0;
@ -323,18 +645,18 @@ static void (^reachabilityChangeBlock)(int);
- (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"]];
@ -344,338 +666,9 @@ static void (^reachabilityChangeBlock)(int);
}
}
}
*headers = [NSDictionary dictionaryWithDictionary:headersWithAuth];
*querys = [NSDictionary dictionaryWithDictionary:querysWithAuth];
}
#pragma mark - Deserialize methods
- (id) deserialize:(id) data class:(NSString *) class {
NSRegularExpression *regexp = nil;
NSTextCheckingResult *match = nil;
NSMutableArray *resultArray = nil;
NSMutableDictionary *resultDict = nil;
// return nil if data is nil or class is nil
if (!data || !class) {
return nil;
}
// remove "*" from class, if ends with "*"
if ([class hasSuffix:@"*"]) {
class = [class substringToIndex:[class length] - 1];
}
// pure object
if ([class isEqualToString:@"NSObject"]) {
return [[NSObject alloc] init];
}
// list of models
NSString *arrayOfModelsPat = @"NSArray<(.+)>";
regexp = [NSRegularExpression regularExpressionWithPattern:arrayOfModelsPat
options:NSRegularExpressionCaseInsensitive
error:nil];
match = [regexp firstMatchInString:class
options:0
range:NSMakeRange(0, [class length])];
if (match) {
NSString *innerType = [class substringWithRange:[match rangeAtIndex:1]];
resultArray = [NSMutableArray arrayWithCapacity:[data count]];
[data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[resultArray addObject:[self deserialize:obj class:innerType]];
}
];
return resultArray;
}
// list of primitives
NSString *arrayOfPrimitivesPet = @"NSArray";
regexp = [NSRegularExpression regularExpressionWithPattern:arrayOfPrimitivesPet
options:NSRegularExpressionCaseInsensitive
error:nil];
match = [regexp firstMatchInString:class
options:0
range:NSMakeRange(0, [class length])];
if (match) {
resultArray = [NSMutableArray arrayWithCapacity:[data count]];
[data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[resultArray addObject:[self deserialize:obj class:NSStringFromClass([obj class])]];
}];
return resultArray;
}
// map
NSString *dictPat = @"NSDictionary\\* /\\* (.+), (.+) \\*/";
regexp = [NSRegularExpression regularExpressionWithPattern:dictPat
options:NSRegularExpressionCaseInsensitive
error:nil];
match = [regexp firstMatchInString:class
options:0
range:NSMakeRange(0, [class length])];
if (match) {
NSString *valueType = [class substringWithRange:[match rangeAtIndex:2]];
resultDict = [NSMutableDictionary dictionaryWithCapacity:[data count]];
[data enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[resultDict setValue:[self deserialize:obj class:valueType] forKey:key];
}];
return resultDict;
}
// primitives
NSArray *primitiveTypes = @[@"NSString", @"NSDate", @"BOOL", @"NSNumber"];
if ([primitiveTypes containsObject:class]) {
if ([class isEqualToString:@"NSString"]) {
return [NSString stringWithString:data];
}
else if ([class isEqualToString:@"NSDate"]) {
return [NSDate dateWithISO8601String:data];
}
else if ([class isEqualToString:@"BOOL"]) {
// Returns YES on encountering one of "Y", "y", "T", "t", or a
// digit 1-9—the method ignores any trailing characters
// NSString => BOOL => NSNumber
return [NSNumber numberWithBool:[data boolValue]];
}
else if ([class isEqualToString:@"NSNumber"]) {
// NSNumber from NSNumber
if ([data isKindOfClass:[NSNumber class]]) {
return data;
}
// NSNumber from NSString
else {
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
return [formatter numberFromString:data];
}
}
}
// model
Class ModelClass = NSClassFromString(class);
if ([ModelClass instancesRespondToSelector:@selector(initWithDictionary:error:)]) {
return [[ModelClass alloc] initWithDictionary:data error:nil];
}
return nil;
}
#pragma mark - Operation Methods
- (void) operationWithCompletionBlock: (NSURLRequest *)request
requestId: (NSNumber *) requestId
completionBlock: (void (^)(id, NSError *))completionBlock {
AFHTTPRequestOperation *op = [self HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id response) {
if([self executeRequestWithId:requestId]) {
if([[{{classPrefix}}Configuration sharedConfig] debug]) {
[self logResponse:operation forRequest:request error:nil];
}
completionBlock(response, nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if([self executeRequestWithId:requestId]) {
NSMutableDictionary *userInfo = [error.userInfo mutableCopy];
if(operation.responseObject) {
// Add in the (parsed) response body.
userInfo[{{classPrefix}}ResponseObjectErrorKey] = operation.responseObject;
}
NSError *augmentedError = [error initWithDomain:error.domain code:error.code userInfo:userInfo];
if([[{{classPrefix}}Configuration sharedConfig] debug])
[self logResponse:nil forRequest:request error:augmentedError];
completionBlock(nil, augmentedError);
}
}];
[self.operationQueue addOperation:op];
}
- (void) downloadOperationWithCompletionBlock: (NSURLRequest *)request
requestId: (NSNumber *) requestId
completionBlock: (void (^)(id, NSError *))completionBlock {
AFHTTPRequestOperation *op = [self HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id responseObject) {
{{classPrefix}}Configuration *config = [{{classPrefix}}Configuration sharedConfig];
NSString *directory = nil;
if (config.tempFolderPath) {
directory = config.tempFolderPath;
}
else {
directory = NSTemporaryDirectory();
}
NSDictionary *headers = operation.response.allHeaderFields;
NSString *filename = nil;
if ([headers objectForKey:@"Content-Disposition"]) {
NSString *pattern = @"filename=['\"]?([^'\"\\s]+)['\"]?";
NSRegularExpression *regexp = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionCaseInsensitive
error:nil];
NSString *contentDispositionHeader = [headers objectForKey:@"Content-Disposition"];
NSTextCheckingResult *match = [regexp firstMatchInString:contentDispositionHeader
options:0
range:NSMakeRange(0, [contentDispositionHeader length])];
filename = [contentDispositionHeader substringWithRange:[match rangeAtIndex:1]];
}
else {
filename = [NSString stringWithFormat:@"%@", [[NSProcessInfo processInfo] globallyUniqueString]];
}
NSString *filepath = [directory stringByAppendingPathComponent:filename];
NSURL *file = [NSURL fileURLWithPath:filepath];
[operation.responseData writeToURL:file atomically:YES];
completionBlock(file, nil);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if ([self executeRequestWithId:requestId]) {
NSMutableDictionary *userInfo = [error.userInfo mutableCopy];
if (operation.responseObject) {
userInfo[{{classPrefix}}ResponseObjectErrorKey] = operation.responseObject;
}
NSError *augmentedError = [error initWithDomain:error.domain code:error.code userInfo:userInfo];
if ([[{{classPrefix}}Configuration sharedConfig] debug]) {
[self logResponse:nil forRequest:request error:augmentedError];
}
completionBlock(nil, augmentedError);
}
}];
[self.operationQueue addOperation:op];
}
#pragma mark - Perform Request Methods
-(NSNumber*) requestWithCompletionBlock: (NSString*) path
method: (NSString*) method
queryParams: (NSDictionary*) queryParams
formParams: (NSDictionary *) formParams
files: (NSDictionary *) files
body: (id) body
headerParams: (NSDictionary*) headerParams
authSettings: (NSArray *) authSettings
requestContentType: (NSString*) requestContentType
responseContentType: (NSString*) responseContentType
responseType: (NSString *) responseType
completionBlock: (void (^)(id, NSError *))completionBlock {
// setting request serializer
if ([requestContentType isEqualToString:@"application/json"]) {
self.requestSerializer = [{{classPrefix}}JSONRequestSerializer serializer];
}
else if ([requestContentType isEqualToString:@"application/x-www-form-urlencoded"]) {
self.requestSerializer = [AFHTTPRequestSerializer serializer];
}
else if ([requestContentType isEqualToString:@"multipart/form-data"]) {
self.requestSerializer = [AFHTTPRequestSerializer serializer];
}
else {
NSAssert(false, @"unsupport request type %@", requestContentType);
}
// setting response serializer
if ([responseContentType isEqualToString:@"application/json"]) {
self.responseSerializer = [{{classPrefix}}JSONResponseSerializer serializer];
}
else {
self.responseSerializer = [AFHTTPResponseSerializer serializer];
}
// auth setting
[self updateHeaderParams:&headerParams queryParams:&queryParams WithAuthSettings:authSettings];
NSMutableURLRequest * request = nil;
NSString* pathWithQueryParams = [self pathWithQueryParamsToString:path queryParams:queryParams];
NSString* urlString = [[NSURL URLWithString:pathWithQueryParams relativeToURL:self.baseURL] absoluteString];
if (files.count > 0) {
request = [self.requestSerializer multipartFormRequestWithMethod:@"POST"
URLString:urlString
parameters:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formParams enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSData *data = [obj dataUsingEncoding:NSUTF8StringEncoding];
[formData appendPartWithFormData:data name:key];
}];
[files enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSURL *filePath = (NSURL *)obj;
[formData appendPartWithFileURL:filePath name:key error:nil];
}];
} error:nil];
}
else {
if (formParams) {
request = [self.requestSerializer requestWithMethod:method
URLString:urlString
parameters:formParams
error:nil];
}
if (body) {
request = [self.requestSerializer requestWithMethod:method
URLString:urlString
parameters:body
error:nil];
}
}
BOOL hasHeaderParams = false;
if(headerParams != nil && [headerParams count] > 0) {
hasHeaderParams = true;
}
if(offlineState) {
NSLog(@"%@ cache forced", path);
[request setCachePolicy:NSURLRequestReturnCacheDataDontLoad];
}
else if(!hasHeaderParams && [method isEqualToString:@"GET"] && cacheEnabled) {
NSLog(@"%@ cache enabled", path);
[request setCachePolicy:NSURLRequestUseProtocolCachePolicy];
}
else {
NSLog(@"%@ cache disabled", path);
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
}
if(hasHeaderParams){
for(NSString * key in [headerParams keyEnumerator]){
[request setValue:[headerParams valueForKey:key] forHTTPHeaderField:key];
}
}
[self.requestSerializer setValue:responseContentType forHTTPHeaderField:@"Accept"];
// Always disable cookies!
[request setHTTPShouldHandleCookies:NO];
NSNumber* requestId = [{{classPrefix}}ApiClient queueRequest];
if ([responseType isEqualToString:@"NSURL*"]) {
[self downloadOperationWithCompletionBlock:request requestId:requestId completionBlock:^(id data, NSError *error) {
completionBlock(data, error);
}];
}
else {
[self operationWithCompletionBlock:request requestId:requestId completionBlock:^(id data, NSError *error) {
completionBlock([self deserialize:data class:responseType], error);
}];
}
return requestId;
}
@end

View File

@ -5,11 +5,18 @@
#import "{{classPrefix}}JSONRequestSerializer.h"
#import "{{classPrefix}}QueryParamCollection.h"
#import "{{classPrefix}}Configuration.h"
{{#models}}{{#model}}#import "{{classname}}.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"
{{/model}}{{/models}}
@class {{classPrefix}}Configuration;
/**
* A key for `NSError` user info dictionaries.
*
@ -25,77 +32,61 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
@property(nonatomic, readonly) NSOperationQueue* queue;
/**
* Get the Api Client instance from pool
*
* @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
* Clears Cache
*/
+(void)clearCache;
/**
* Turn on cache
* Turns on cache
*
* @param enabled If the cached is enable, must be `YES` or `NO`
*/
+(void)setCacheEnabled:(BOOL) enabled;
/**
* Get the request queue size
* Gets the request queue size
*
* @return The size of `queuedRequests` static variable.
*/
+(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;
/**
* Get the client reachability
* Gets the client reachability
*
* @return The client reachability.
*/
+(AFNetworkReachabilityStatus) getReachabilityStatus;
/**
* Get the next request id
* Gets the next request id
*
* @return The next executed request id.
*/
+(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.
*/
+(NSNumber*) queueRequest;
/**
* Remove request id from the queue
* Removes request id from the queue
*
* @param requestId The request which will be removed.
*/
+(void) cancelRequest:(NSNumber*)requestId;
/**
* URL encode NSString
* Gets URL encoded NSString
*
* @param unescaped The string which will be escaped.
*
@ -104,21 +95,19 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
+(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.
*/
+(void) setReachabilityChangeBlock:(void(^)(int))changeBlock;
/**
* Set the client reachability strategy
*
* @param host The host of {{classPrefix}}ApiClient.
* Sets the api client reachability strategy
*/
+(void) configureCacheReachibilityForHost:(NSString*)host;
- (void)configureCacheReachibility;
/**
* Detect Accept header from accepts NSArray
* Detects Accept header from accepts NSArray
*
* @param accepts NSArray of header
*
@ -127,7 +116,7 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
+(NSString *) selectHeaderAccept:(NSArray *)accepts;
/**
* Detect Content-Type header from contentTypes NSArray
* Detects Content-Type header from contentTypes NSArray
*
* @param contentTypes NSArray of header
*
@ -136,7 +125,7 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
+(NSString *) selectHeaderContentType:(NSArray *)contentTypes;
/**
* Set header for request
* Sets header for request
*
* @param value The header value
* @param forKey The header key
@ -145,7 +134,7 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
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 querys The query parameters will be updated, passed by pointer to pointer.
@ -156,7 +145,7 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
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 class The type of objective-c object.
@ -164,7 +153,7 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
- (id) deserialize:(id) data class:(NSString *) class;
/**
* Logging request and response
* Logs request and response
*
* @param operation AFHTTPRequestOperation for the HTTP request.
* @param request The HTTP request.
@ -175,7 +164,7 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
error:(NSError *)error;
/**
* Perform request
* Performs request
*
* @param path Request url.
* @param method Request method.
@ -185,7 +174,7 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
* @param authSettings Request authentication names.
* @param requestContentType Request content-type.
* @param responseContentType Response content-type.
* @param completionBlock The block will be executed when the request completed.
* @param completionBlock The block will be executed when the request completed.
*
* @return The request id.
*/

View File

@ -25,6 +25,8 @@
- (instancetype) init {
self = [super init];
if (self) {
self.apiClient = nil;
self.host = @"{{basePath}}";
self.username = @"";
self.password = @"";
self.tempFolderPath = nil;
@ -54,18 +56,26 @@
NSString *basicAuthCredentials = [NSString stringWithFormat:@"%@:%@", self.username, self.password];
NSData *data = [basicAuthCredentials dataUsingEncoding:NSUTF8StringEncoding];
basicAuthCredentials = [NSString stringWithFormat:@"Basic %@", [data base64EncodedStringWithOptions:0]];
return basicAuthCredentials;
}
#pragma mark - Setter Methods
- (void) setValue:(NSString *)value forApiKeyField:(NSString *)field {
[self.mutableApiKey setValue:value forKey:field];
- (void) setApiKey:(NSString *)apiKey forApiKeyIdentifier:(NSString *)identifier {
[self.mutableApiKey setValue:apiKey forKey:identifier];
}
- (void) setValue:(NSString *)value forApiKeyPrefixField:(NSString *)field {
[self.mutableApiKeyPrefix setValue:value forKey:field];
- (void) removeApiKey:(NSString *)identifier {
[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 {
@ -73,12 +83,12 @@
if ([self.loggingFileHanlder isKindOfClass:[NSFileHandle class]]) {
[self.loggingFileHanlder closeFile];
}
_loggingFile = loggingFile;
self.loggingFileHanlder = [NSFileHandle fileHandleForWritingAtPath:_loggingFile];
if (self.loggingFileHanlder == nil) {
_loggingFileHanlder = [NSFileHandle fileHandleForWritingAtPath:_loggingFile];
if (_loggingFileHanlder == nil) {
[[NSFileManager defaultManager] createFileAtPath:_loggingFile contents:nil attributes:nil];
self.loggingFileHanlder = [NSFileHandle fileHandleForWritingAtPath:_loggingFile];
_loggingFileHanlder = [NSFileHandle fileHandleForWritingAtPath:_loggingFile];
}
}
@ -95,15 +105,28 @@
#pragma mark -
- (NSDictionary *) authSettings {
return @{
@"api_key": @{
@"type": @"api_key",
@"in": @"header",
@"key": @"api_key",
@"value": [self getApiKeyWithPrefix:@"api_key"]
},
};
return @{
{{#authMethods}}
{{#isApiKey}}
@"{{name}}":
@{
@"type": @"api_key",
@"in": {{#isKeyInHeader}}@"header"{{/isKeyInHeader}}{{#isKeyInQuery}}@"query"{{/isKeyInQuery}},
@"key": @"{{keyParamName}}",
@"value": [self getApiKeyWithPrefix:@"{{keyParamName}}"]
},
{{/isApiKey}}
{{#isBasic}}
@"{{name}}":
@{
@"type": @"basic",
@"in": @"header",
@"key": @"Authorization",
@"value": [self getBasicAuthToken]
},
{{/isBasic}}
{{/authMethods}}
};
}
@end

View File

@ -1,26 +1,49 @@
#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
/**
* Default api client
*/
@property (nonatomic) {{classPrefix}}ApiClient *apiClient;
/**
* Default base url
*/
@property (nonatomic) NSString *host;
/**
* 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;
/**
* 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;
/**
* 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;
/**
@ -31,37 +54,74 @@
/**
* 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;
/**
* 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;
/**
* Get Basic Auth token
* Gets Basic Auth token
*/
- (NSString *) getBasicAuthToken;
/**
* Get Authentication Setings
* Gets Authentication Setings
*/
- (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"
```
## Recommendation
It's recommended to create an instance of ApiClient per thread in a multithreaded environment to avoid any potential issue.
## Author
{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}}

View File

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

View File

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

View File

@ -3,12 +3,21 @@
#import "{{classname}}.h"
@implementation {{classname}}
/**
* Maps json key to property name.
* This method is used by `JSONModel`.
*/
+ (JSONKeyMapper *)keyMapper
{
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
{
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}}
@end
{{/models}}

View File

@ -1,5 +1,12 @@
#import <Foundation/Foundation.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}}
{{newline}}
@ -8,7 +15,7 @@
@protocol {{classname}}
@end
@interface {{classname}} : {{classPrefix}}Object
{{#vars}}

View File

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

View File

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

View File

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

View File

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

View File

@ -1,10 +1,20 @@
#!/usr/bin/env python
# coding: utf-8
"""Swagger generic API client. This client handles the client-
server communication, and is invariant across implementations. Specifics of
the methods and models for each application are generated from the Swagger
templates."""
"""
Copyright 2015 SmartBear Software
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from __future__ import absolute_import
from . import models
@ -27,415 +37,523 @@ from datetime import date
from six import iteritems
try:
# for python3
from urllib.parse import quote
# for python3
from urllib.parse import quote
except ImportError:
# for python2
from urllib import quote
# for python2
from urllib import quote
from .configuration import Configuration
class ApiClient(object):
"""
Generic API client for Swagger client library builds
:param host: The base path for the server to call
:param header_name: a header to pass when making calls to the API
:param header_value: a header value to pass when making calls to the API
"""
def __init__(self, host=Configuration().host, header_name=None, header_value=None):
self.default_headers = {}
if header_name is not None:
self.default_headers[header_name] = header_value
self.host = host
self.cookie = None
# Set default User-Agent.
self.user_agent = 'Python-Swagger'
@property
def user_agent(self):
return self.default_headers['User-Agent']
@user_agent.setter
def user_agent(self, value):
self.default_headers['User-Agent'] = value
def set_default_header(self, 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,
body=None, post_params=None, files=None, response_type=None, auth_settings=None, callback=None):
# headers parameters
header_params = header_params or {}
header_params.update(self.default_headers)
if self.cookie:
header_params['Cookie'] = self.cookie
if header_params:
header_params = self.sanitize_for_serialization(header_params)
# path parameters
if path_params:
path_params = self.sanitize_for_serialization(path_params)
for k, v in iteritems(path_params):
replacement = quote(str(self.to_path_value(v)))
resource_path = resource_path.replace('{' + k + '}', replacement)
# query parameters
if 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)}
# post parameters
if post_params:
post_params = self.prepare_post_parameters(post_params, files)
post_params = self.sanitize_for_serialization(post_params)
# auth setting
self.update_params_for_auth(header_params, query_params, auth_settings)
# body
if body:
body = self.sanitize_for_serialization(body)
# request url
url = self.host + resource_path
# perform request and return response
response_data = self.request(method, url, query_params=query_params, headers=header_params,
post_params=post_params, body=body)
self.last_response = response_data
# deserialize response data
if response_type:
deserialized_data = self.deserialize(response_data, response_type)
else:
deserialized_data = None
if callback:
callback(deserialized_data)
else:
return deserialized_data
def to_path_value(self, obj):
"""
Convert a string or object to a path-friendly value
Generic API client for Swagger client library builds.
:param obj: object or string value
Swagger generic API client. This client handles the client-
server communication, and is invariant across implementations. Specifics of
the methods and models for each application are generated from the Swagger
templates.
:return string: quoted value
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.
"""
if type(obj) == list:
return ','.join(obj)
else:
return str(obj)
def __init__(self, host=Configuration().host,
header_name=None, header_value=None, cookie=None):
def sanitize_for_serialization(self, obj):
"""
Sanitize an object for Request.
"""
Constructor of the class.
"""
self.default_headers = {}
if header_name is not None:
self.default_headers[header_name] = header_value
self.host = host
self.cookie = cookie
# Set default User-Agent.
self.user_agent = 'Python-Swagger'
If obj is None, return None.
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 list, santize each element in the list.
If obj is dict, return the dict.
If obj is swagger model, return the properties dict.
"""
if isinstance(obj, type(None)):
return None
elif isinstance(obj, (str, int, float, bool, tuple)):
return obj
elif isinstance(obj, list):
return [self.sanitize_for_serialization(sub_obj) for sub_obj in obj]
elif isinstance(obj, (datetime, date)):
return obj.isoformat()
else:
if isinstance(obj, dict):
obj_dict = obj
else:
# Convert model obj to dict except attributes `swagger_types`, `attribute_map`
# and attributes which value is not None.
# Convert attribute name to json key in model definition for request.
obj_dict = {obj.attribute_map[key]: val
for key, val in iteritems(obj.__dict__)
if key != 'swagger_types' and key != 'attribute_map' and val is not None}
return {key: self.sanitize_for_serialization(val)
for key, val in iteritems(obj_dict)}
@property
def user_agent(self):
"""
Gets user agent.
"""
return self.default_headers['User-Agent']
def deserialize(self, response, response_type):
"""
Derialize response into an object.
@user_agent.setter
def user_agent(self, value):
"""
Sets user agent.
"""
self.default_headers['User-Agent'] = value
:param response: RESTResponse object to be deserialized
:param response_type: class literal for deserialzied object, or string of class name
def set_default_header(self, header_name, header_value):
self.default_headers[header_name] = header_value
:return: deserialized object
"""
# handle file downloading - save response body into a tmp file and return the instance
if "file" == response_type:
return self.__deserialize_file(response)
def __call_api(self, resource_path, method,
path_params=None, query_params=None, header_params=None,
body=None, post_params=None, files=None,
response_type=None, auth_settings=None, callback=None):
# fetch data from response object
try:
data = json.loads(response.data)
except ValueError:
data = response.data
# headers parameters
header_params = header_params or {}
header_params.update(self.default_headers)
if self.cookie:
header_params['Cookie'] = self.cookie
if header_params:
header_params = self.sanitize_for_serialization(header_params)
return self.__deserialize(data, response_type)
# path parameters
if path_params:
path_params = self.sanitize_for_serialization(path_params)
for k, v in iteritems(path_params):
replacement = quote(str(self.to_path_value(v)))
resource_path = resource_path.\
replace('{' + k + '}', replacement)
def __deserialize(self, data, klass):
"""
:param data: dict, list or str
:param klass: class literal, or string of class name
# query parameters
if 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)}
:return: object
"""
if data is None:
return None
# post parameters
if post_params:
post_params = self.prepare_post_parameters(post_params, files)
post_params = self.sanitize_for_serialization(post_params)
if type(klass) == str:
if 'list[' in klass:
sub_kls = re.match('list\[(.*)\]', klass).group(1)
return [self.__deserialize(sub_data, sub_kls) for sub_data in data]
# auth setting
self.update_params_for_auth(header_params, query_params, auth_settings)
if 'dict(' in klass:
sub_kls = re.match('dict\((.*), (.*)\)', klass).group(2)
return {k: self.__deserialize(v, sub_kls) for k, v in iteritems(data)}
# body
if body:
body = self.sanitize_for_serialization(body)
# convert str to class
# for native types
if klass in ['int', 'float', 'str', 'bool', "date", 'datetime', "object"]:
klass = eval(klass)
# for model types
else:
klass = eval('models.' + klass)
# request url
url = self.host + resource_path
if klass in [int, float, str, bool]:
return self.__deserialize_primitive(data, klass)
elif klass == object:
return self.__deserialize_object()
elif klass == date:
return self.__deserialize_date(data)
elif klass == datetime:
return self.__deserialize_datatime(data)
else:
return self.__deserialize_model(data, klass)
# perform request and return response
response_data = self.request(method, url,
query_params=query_params,
headers=header_params,
post_params=post_params, body=body)
def call_api(self, resource_path, method,
path_params=None, query_params=None, header_params=None,
body=None, post_params=None, files=None,
response_type=None, auth_settings=None, callback=None):
"""
Perform http request and return deserialized data
self.last_response = response_data
:param resource_path: Path to method endpoint.
:param method: Method to call.
:param path_params: Path 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 body: Request body.
: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 response: Response data type.
:param files dict: key -> filename, value -> filepath, for `multipart/form-data`.
:param callback function: Callback function for asynchronous request.
If provide this parameter, the request will be called asynchronously.
:return:
If provide parameter callback, the request will be called asynchronously.
The method will return the request thread.
If parameter callback is None, then the method will return the response directly.
"""
if callback is None:
return self.__call_api(resource_path, method,
path_params, query_params, header_params,
body, post_params, files,
response_type, auth_settings, callback)
else:
thread = threading.Thread(target=self.__call_api,
args=(resource_path, method,
path_params, query_params, header_params,
body, post_params, files,
response_type, auth_settings, callback))
thread.start()
return thread
def request(self, method, url, query_params=None, headers=None,
post_params=None, body=None):
"""
Perform http request using RESTClient.
"""
if method == "GET":
return RESTClient.GET(url, query_params=query_params, headers=headers)
elif method == "HEAD":
return RESTClient.HEAD(url, query_params=query_params, headers=headers)
elif method == "POST":
return RESTClient.POST(url, headers=headers, post_params=post_params, body=body)
elif method == "PUT":
return RESTClient.PUT(url, headers=headers, post_params=post_params, body=body)
elif method == "PATCH":
return RESTClient.PATCH(url, headers=headers, post_params=post_params, body=body)
elif method == "DELETE":
return RESTClient.DELETE(url, query_params=query_params, headers=headers)
else:
raise ValueError("http method must be `GET`, `HEAD`, `POST`, `PATCH`, `PUT` or `DELETE`")
def prepare_post_parameters(self, post_params=None, files=None):
params = {}
if post_params:
params.update(post_params)
if files:
for k, v in iteritems(files):
if v:
with open(v, 'rb') as f:
filename = os.path.basename(f.name)
filedata = f.read()
mimetype = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
params[k] = tuple([filename, filedata, mimetype])
return params
def select_header_accept(self, accepts):
"""
Return `Accept` based on an array of accepts provided
"""
if not accepts:
return
accepts = list(map(lambda x: x.lower(), accepts))
if 'application/json' in accepts:
return 'application/json'
else:
return ', '.join(accepts)
def select_header_content_type(self, content_types):
"""
Return `Content-Type` baseed on an array of content_types provided
"""
if not content_types:
return 'application/json'
content_types = list(map(lambda x: x.lower(), content_types))
if 'application/json' in content_types:
return 'application/json'
else:
return content_types[0]
def update_params_for_auth(self, headers, querys, auth_settings):
"""
Update header and query params based on authentication setting
"""
config = Configuration()
if not auth_settings:
return
for auth in auth_settings:
auth_setting = config.auth_settings().get(auth)
if auth_setting:
if auth_setting['in'] == 'header':
headers[auth_setting['key']] = auth_setting['value']
elif auth_setting['in'] == 'query':
querys[auth_setting['key']] = auth_setting['value']
# deserialize response data
if response_type:
deserialized_data = self.deserialize(response_data, response_type)
else:
raise ValueError('Authentication token must be in `query` or `header`')
deserialized_data = None
def __deserialize_file(self, response):
"""
Save response body into a file in (the defined) temporary folder, using the filename
from the `Content-Disposition` header if provided, otherwise a random filename.
if callback:
callback(deserialized_data)
else:
return deserialized_data
:param response: RESTResponse
:return: file path
"""
fd, path = tempfile.mkstemp(dir=configuration.temp_folder_path)
os.close(fd)
os.remove(path)
def to_path_value(self, obj):
"""
Takes value and turn it into a string suitable for inclusion in
the path, by url-encoding.
content_disposition = response.getheader("Content-Disposition")
if content_disposition:
filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', content_disposition).group(1)
path = os.path.join(os.path.dirname(path), filename)
:param obj: object or string value.
with open(path, "w") as f:
f.write(response.data)
:return string: quoted value.
"""
if type(obj) == list:
return ','.join(obj)
else:
return str(obj)
return path
def sanitize_for_serialization(self, obj):
"""
Builds a JSON POST object.
def __deserialize_primitive(self, data, klass):
"""
Deserialize string to primitive type
If obj is None, return None.
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 list, santize each element in the list.
If obj is dict, return the dict.
If obj is swagger model, return the properties dict.
:param data: str
:param klass: class literal
:param obj: The data to serialize.
:return: The serialized form of data.
"""
if isinstance(obj, type(None)):
return None
elif isinstance(obj, (str, int, float, bool, tuple)):
return obj
elif isinstance(obj, list):
return [self.sanitize_for_serialization(sub_obj)
for sub_obj in obj]
elif isinstance(obj, (datetime, date)):
return obj.isoformat()
else:
if isinstance(obj, dict):
obj_dict = obj
else:
# Convert model obj to dict except
# attributes `swagger_types`, `attribute_map`
# and attributes which value is not None.
# Convert attribute name to json key in
# model definition for request.
obj_dict = {obj.attribute_map[key[1:]]: val
for key, val in iteritems(obj.__dict__)
if key != 'swagger_types'
and key != 'attribute_map'
and val is not None}
:return: int, float, str, bool
"""
try:
value = klass(data)
except UnicodeEncodeError:
value = unicode(data)
except TypeError:
value = data
return value
return {key: self.sanitize_for_serialization(val)
for key, val in iteritems(obj_dict)}
def __deserialize_object(self):
"""
Deserialize empty object
"""
return object()
def deserialize(self, response, response_type):
"""
Deserializes response into an object.
def __deserialize_date(self, string):
"""
Deserialize string to date
:param response: RESTResponse object to be deserialized.
:param response_type: class literal for
deserialzied object, or string of class name.
:param string: str
:return: date
"""
try:
from dateutil.parser import parse
return parse(string).date()
except ImportError:
return string
except ValueError:
raise ApiException(status=0, reason="Failed to parse `{0}` into a date object".format(string))
def __deserialize_datatime(self, string):
"""
Deserialize string to datetime.
:return: deserialized object.
"""
# handle file downloading
# save response body into a tmp file and return the instance
if "file" == response_type:
return self.__deserialize_file(response)
The string should be in iso8601 datetime format.
# fetch data from response object
try:
data = json.loads(response.data)
except ValueError:
data = response.data
:param string: str
:return: datetime
"""
try:
from dateutil.parser import parse
return parse(string)
except ImportError:
return string
except ValueError:
raise ApiException(status=0, reason="Failed to parse `{0}` into a datetime object".format(string))
return self.__deserialize(data, response_type)
def __deserialize_model(self, data, klass):
"""
Deserialize list or dict to model
def __deserialize(self, data, klass):
"""
Deserializes dict, list, str into an object.
:param data: dict, list
:param klass: class literal
"""
instance = klass()
:param data: dict, list or str.
:param klass: class literal, or string of class name.
for attr, attr_type in iteritems(instance.swagger_types):
if data is not None \
and instance.attribute_map[attr] in data\
and isinstance(data, (list, dict)):
value = data[instance.attribute_map[attr]]
setattr(instance, attr, self.__deserialize(value, attr_type))
:return: object.
"""
if data is None:
return None
return instance
if type(klass) == str:
if klass.startswith('list['):
sub_kls = re.match('list\[(.*)\]', klass).group(1)
return [self.__deserialize(sub_data, sub_kls)
for sub_data in data]
if klass.startswith('dict('):
sub_kls = re.match('dict\(([^,]*), (.*)\)', klass).group(2)
return {k: self.__deserialize(v, sub_kls)
for k, v in iteritems(data)}
# convert str to class
# for native types
if klass in ['int', 'float', 'str', 'bool',
"date", 'datetime', "object"]:
klass = eval(klass)
# for model types
else:
klass = eval('models.' + klass)
if klass in [int, float, str, bool]:
return self.__deserialize_primitive(data, klass)
elif klass == object:
return self.__deserialize_object()
elif klass == date:
return self.__deserialize_date(data)
elif klass == datetime:
return self.__deserialize_datatime(data)
else:
return self.__deserialize_model(data, klass)
def call_api(self, resource_path, method,
path_params=None, query_params=None, header_params=None,
body=None, post_params=None, files=None,
response_type=None, auth_settings=None, callback=None):
"""
Makes the HTTP request and return the deserialized data.
:param resource_path: Path to method endpoint.
:param method: Method to call.
:param path_params: Path 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 body: Request body.
: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 response: Response data type.
:param files dict: key -> filename, value -> filepath,
for `multipart/form-data`.
:param callback function: Callback function for asynchronous request.
If provide this parameter,
the request will be called asynchronously.
:return:
If provide parameter callback,
the request will be called asynchronously.
The method will return the request thread.
If parameter callback is None,
then the method will return the response directly.
"""
if callback is None:
return self.__call_api(resource_path, method,
path_params, query_params, header_params,
body, post_params, files,
response_type, auth_settings, callback)
else:
thread = threading.Thread(target=self.__call_api,
args=(resource_path, method,
path_params, query_params,
header_params, body,
post_params, files,
response_type, auth_settings,
callback))
thread.start()
return thread
def request(self, method, url, query_params=None, headers=None,
post_params=None, body=None):
"""
Makes the HTTP request using RESTClient.
"""
if method == "GET":
return RESTClient.GET(url,
query_params=query_params,
headers=headers)
elif method == "HEAD":
return RESTClient.HEAD(url,
query_params=query_params,
headers=headers)
elif method == "POST":
return RESTClient.POST(url,
headers=headers,
post_params=post_params,
body=body)
elif method == "PUT":
return RESTClient.PUT(url,
headers=headers,
post_params=post_params,
body=body)
elif method == "PATCH":
return RESTClient.PATCH(url,
headers=headers,
post_params=post_params,
body=body)
elif method == "DELETE":
return RESTClient.DELETE(url,
query_params=query_params,
headers=headers)
else:
raise ValueError(
"http method must be `GET`, `HEAD`,"
" `POST`, `PATCH`, `PUT` or `DELETE`."
)
def prepare_post_parameters(self, post_params=None, files=None):
"""
Builds form parameters.
:param post_params: Normal form parameters.
:param files: File parameters.
:return: Form parameters with files.
"""
params = {}
if post_params:
params.update(post_params)
if files:
for k, v in iteritems(files):
if not v:
continue
with open(v, 'rb') as f:
filename = os.path.basename(f.name)
filedata = f.read()
mimetype = mimetypes.\
guess_type(filename)[0] or 'application/octet-stream'
params[k] = tuple([filename, filedata, mimetype])
return params
def select_header_accept(self, accepts):
"""
Returns `Accept` based on an array of accepts provided.
:param accepts: List of headers.
:return: Accept (e.g. application/json).
"""
if not accepts:
return
accepts = list(map(lambda x: x.lower(), accepts))
if 'application/json' in accepts:
return 'application/json'
else:
return ', '.join(accepts)
def select_header_content_type(self, content_types):
"""
Returns `Content-Type` based on an array of content_types provided.
:param content_types: List of content-types.
:return: Content-Type (e.g. application/json).
"""
if not content_types:
return 'application/json'
content_types = list(map(lambda x: x.lower(), content_types))
if 'application/json' in content_types:
return 'application/json'
else:
return content_types[0]
def update_params_for_auth(self, headers, querys, auth_settings):
"""
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()
if not auth_settings:
return
for auth in auth_settings:
auth_setting = config.auth_settings().get(auth)
if auth_setting:
if auth_setting['in'] == 'header':
headers[auth_setting['key']] = auth_setting['value']
elif auth_setting['in'] == 'query':
querys[auth_setting['key']] = auth_setting['value']
else:
raise ValueError(
'Authentication token must be in `query` or `header`'
)
def __deserialize_file(self, response):
"""
Saves response body into a file in (the defined) temporary folder,
using the filename from the `Content-Disposition` header if provided,
otherwise a random filename.
:param response: RESTResponse.
:return: file path.
"""
config = Configuration()
fd, path = tempfile.mkstemp(dir=config.temp_folder_path)
os.close(fd)
os.remove(path)
content_disposition = response.getheader("Content-Disposition")
if content_disposition:
filename = re.\
search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', content_disposition).\
group(1)
path = os.path.join(os.path.dirname(path), filename)
with open(path, "w") as f:
f.write(response.data)
return path
def __deserialize_primitive(self, data, klass):
"""
Deserializes string to primitive type.
:param data: str.
:param klass: class literal.
:return: int, float, str, bool.
"""
try:
value = klass(data)
except UnicodeEncodeError:
value = unicode(data)
except TypeError:
value = data
return value
def __deserialize_object(self):
"""
Deserializes empty object.
:return: object.
"""
return object()
def __deserialize_date(self, string):
"""
Deserializes string to date.
:param string: str.
:return: date.
"""
try:
from dateutil.parser import parse
return parse(string).date()
except ImportError:
return string
except ValueError:
raise ApiException(
status=0,
reason="Failed to parse `{0}` into a date object"
.format(string)
)
def __deserialize_datatime(self, string):
"""
Deserializes string to datetime.
The string should be in iso8601 datetime format.
:param string: str.
:return: datetime.
"""
try:
from dateutil.parser import parse
return parse(string)
except ImportError:
return string
except ValueError:
raise ApiException(
status=0,
reason="Failed to parse `{0}` into a datetime object".
format(string)
)
def __deserialize_model(self, data, klass):
"""
Deserializes list or dict to model.
:param data: dict, list.
:param klass: class literal.
:return: model object.
"""
instance = klass()
for attr, attr_type in iteritems(instance.swagger_types):
if data is not None \
and instance.attribute_map[attr] in data\
and isinstance(data, (list, dict)):
value = data[instance.attribute_map[attr]]
setattr(instance, attr, self.__deserialize(value, attr_type))
return instance

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
import base64
import urllib3
import httplib
try:
import httplib
except ImportError:
# python3
import http.client as httplib
import sys
import logging
def singleton(cls, *args, **kw):
instances = {}
@ -17,24 +42,45 @@ def singleton(cls, *args, **kw):
@singleton
class Configuration(object):
"""
NOTE: This class is auto generated by the swagger code generator program.
https://github.com/swagger-api/swagger-codegen
Do not edit the class manually.
"""
def __init__(self):
"""
Constructor
"""
# Default Base url
self.host = "{{basePath}}"
# Default api client
self.api_client = None
# Temp file folder for download
self.temp_folder_path = None
# Authentication Settings
# dict to store API key(s)
self.api_key = {}
# dict to store API prefix (e.g. Bearer)
self.api_key_prefix = {}
# Username for HTTP basic authentication
self.username = ""
# Password for HTTP basic authentication
self.password = ""
# Logging Settings
self.logging_format = '%(asctime)s %(levelname)s %(message)s'
# Debug file location
self.__logging_file = None
# Debug switch
self.__debug = False
self.init_logger()
def init_logger(self):
"""
Initializes logger settings.
"""
self.logger = logging.getLogger()
formatter = logging.Formatter(self.logging_format)
stream_handler = logging.StreamHandler()
@ -79,43 +125,65 @@ class Configuration(object):
# setting log level to default `logging.WARNING`
self.logger.setLevel(logging.WARNING)
def get_api_key_with_prefix(self, key):
""" Return api key prepend prefix for key """
if self.api_key.get(key) and self.api_key_prefix.get(key):
return self.api_key_prefix[key] + ' ' + self.api_key[key]
elif self.api_key.get(key):
return self.api_key[key]
def get_api_key_with_prefix(self, identifier):
"""
Gets API key (with prefix if set).
:param identifier: The identifier of apiKey.
:return: The token for api key authentication.
"""
if self.api_key.get(identifier) and self.api_key_prefix.get(identifier):
return self.api_key_prefix[identifier] + ' ' + self.api_key[identifier]
elif self.api_key.get(identifier):
return self.api_key[identifier]
def get_basic_auth_token(self):
""" Return basic auth header string """
"""
Gets basic auth header string.
:return: The token for basic HTTP authentication.
"""
return urllib3.util.make_headers(basic_auth=self.username + ':' + self.password)\
.get('authorization')
def auth_settings(self):
""" Return Auth Settings for api client """
return { {{#authMethods}}{{#isApiKey}}
'{{name}}': {
'type': 'api_key',
'in': {{#isKeyInHeader}}'header'{{/isKeyInHeader}}{{#isKeyInQuery}}'query'{{/isKeyInQuery}},
'key': '{{keyParamName}}',
'value': self.get_api_key_with_prefix('{{keyParamName}}')
},
{{/isApiKey}}{{#isBasic}}
'{{name}}': {
'type': 'basic',
'in': 'header',
'key': 'Authorization',
'value': self.get_basic_auth_token()
},
{{/isBasic}}{{/authMethods}}
}
"""
Gets Auth Settings dict for api client.
:return: The Auth Settings information dict.
"""
return {
{{#authMethods}}
{{#isApiKey}}
'{{name}}':
{
'type': 'api_key',
'in': {{#isKeyInHeader}}'header'{{/isKeyInHeader}}{{#isKeyInQuery}}'query'{{/isKeyInQuery}},
'key': '{{keyParamName}}',
'value': self.get_api_key_with_prefix('{{keyParamName}}')
},
{{/isApiKey}}
{{#isBasic}}
'{{name}}':
{
'type': 'basic',
'in': 'header',
'key': 'Authorization',
'value': self.get_basic_auth_token()
},
{{/isBasic}}
{{/authMethods}}
}
def to_debug_report(self):
"""
Gets the essential information for debugging.
:return: The report for debugging.
"""
return "Python SDK Debug Report:\n"\
"OS: {env}\n"\
"Python Version: {pyversion}\n"\
"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
"""
@ -16,21 +15,26 @@ Copyright 2015 SmartBear Software
See the License for the specific language governing permissions and
limitations under the License.
"""
{{#models}}
{{#model}}
from pprint import pformat
from six import iteritems
class {{classname}}(object):
"""
NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self):
"""
Swagger model
:param dict swaggerTypes: The key is attribute name and the value is attribute type.
:param dict attributeMap: The key is attribute name and the value is json key in definition.
:param dict swaggerTypes: The key is attribute name
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 = {
{{#vars}}'{{name}}': '{{{datatype}}}'{{#hasMore}},
@ -41,19 +45,72 @@ class {{classname}}(object):
{{#vars}}'{{name}}': '{{baseName}}'{{#hasMore}},
{{/hasMore}}{{/vars}}
}
{{#vars}}
{{#description}}# {{description}}{{/description}}
self.{{name}} = None # {{{datatype}}}
{{/vars}}
{{#vars}}
self._{{name}} = None
{{/vars}}
{{#vars}}
@property
def {{name}}(self):
"""
Gets the {{name}} of this {{classname}}.
{{#description}} {{{description}}}{{/description}}
:return: The {{name}} of this {{classname}}.
:rtype: {{datatype}}
"""
return self._{{name}}
@{{name}}.setter
def {{name}}(self, {{name}}):
"""
Sets the {{name}} of this {{classname}}.
{{#description}} {{{description}}}{{/description}}
:param {{name}}: The {{name}} of this {{classname}}.
:type: {{datatype}}
"""
{{#isEnum}}allowed_values = [{{#allowableValues}}{{#values}}"{{{this}}}"{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}]
if {{name}} not in allowed_values:
raise ValueError(
"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):
properties = []
for p in self.__dict__:
if p != 'swaggerTypes' and p != 'attributeMap':
properties.append('{prop}={val!r}'.format(prop=p, val=self.__dict__[p]))
return '<{name} {props}>'.format(name=__name__, props=' '.join(properties))
"""
For `print` and `pprint`
"""
return self.to_str()
{{/model}}
{{/models}}

View File

@ -1,6 +1,20 @@
# coding: utf-8
"""
Copyright 2015 SmartBear Software
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Credit: this file (rest.py) is modified based on rest.py in Dropbox Python SDK:
https://www.dropbox.com/developers/core/sdks/python
"""
@ -51,6 +65,7 @@ class RESTResponse(io.IOBase):
"""
return self.urllib3_response.getheader(name, default)
class RESTClientObject(object):
def __init__(self, pools_size=4):
@ -87,14 +102,17 @@ class RESTClientObject(object):
:param query_params: query parameters in the url
:param headers: http request headers
: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`
"""
method = method.upper()
assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', 'PATCH']
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 {}
headers = headers or {}
@ -144,22 +162,37 @@ class RESTClientObject(object):
return r
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):
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):
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):
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):
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):
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):
@ -183,13 +216,14 @@ class ApiException(Exception):
error_message = "({0})\n"\
"Reason: {1}\n".format(self.status, self.reason)
if self.headers:
error_message += "HTTP response headers: {0}".format(self.headers)
error_message += "HTTP response headers: {0}\n".format(self.headers)
if self.body:
error_message += "HTTP response body: {0}".format(self.body)
error_message += "HTTP response body: {0}\n".format(self.body)
return error_message
class RESTClient(object):
"""
A class with all class methods to perform JSON requests.

View File

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

View File

@ -18,13 +18,13 @@ from .models import *
class ApiClient:
"""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:
raise Exception('You must pass an apiKey when instantiating the '
'APIClient')
self.apiKey = apiKey
self.apiServer = apiServer
self.cookie = None
self.cookie = cookie
def callAPI(self, resourcePath, method, queryParams, postData,
headerParams=None):

View File

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

View File

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

View File

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

View File

@ -184,7 +184,8 @@ module {{moduleName}}
def build_request_body(header_params, form_params, body)
# http form
if header_params['Content-Type'] == 'application/x-www-form-urlencoded'
if header_params['Content-Type'] == 'application/x-www-form-urlencoded' ||
header_params['Content-Type'] == 'multipart/form-data'
data = form_params.dup
data.each do |key, value|
data[key] = value.to_s if value && !value.is_a?(File)

View File

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

View File

@ -6,13 +6,13 @@
import Foundation
class {{projectName}}API {
public class {{projectName}}API {
static let basePath = "{{basePath}}"
static var credential: NSURLCredential?
static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory()
}
class APIBase {
public class APIBase {
func toParameters(encodable: JSONEncodable?) -> [String: AnyObject]? {
let encoded: AnyObject? = encodable?.encodeToJSON()
@ -28,7 +28,7 @@ class APIBase {
}
}
class RequestBuilder<T> {
public class RequestBuilder<T> {
var credential: NSURLCredential?
var headers: [String:String] = [:]
let parameters: [String:AnyObject]?
@ -36,24 +36,24 @@ class RequestBuilder<T> {
let method: 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.URLString = URLString
self.parameters = parameters
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 {
headers[name] = value
}
return self
}
func addCredential() -> Self {
self.credential = OneteamAPI.credential
public func addCredential() -> Self {
self.credential = {{projectName}}API.credential
return self
}
}

View File

@ -29,7 +29,47 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
managerStore[managerId] = manager
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 {
request.authenticate(usingCredential: credential)
}
@ -66,7 +106,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
completion(response: response, erorr: nil)
return
}
completion(response: nil, erorr: NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"]))
}
}

View File

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

View File

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

View File

@ -10,18 +10,18 @@ protocol JSONEncodable {
func encodeToJSON() -> AnyObject
}
class Response<T> {
let statusCode: Int
let header: [String: String]
let body: T
public class Response<T> {
public let statusCode: Int
public let header: [String: String]
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.header = header
self.body = body
}
convenience init(response: NSHTTPURLResponse, body: T) {
public convenience init(response: NSHTTPURLResponse, body: T) {
let rawHeader = response.allHeaderFields
var header = [String:String]()
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 {
{{#description}}
/** {{description}} */{{/description}}
class {{classname}}: APIBase {
public class {{classname}}: APIBase {
{{#operation}}
/**
{{#summary}}
@ -32,20 +32,22 @@ extension {{projectName}}API {
: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}}
path = path.stringByReplacingOccurrencesOfString("{{=<% %>=}}{<%paramName%>}<%={{ }}=%>", withString: "\({{paramName}})", options: .LiteralSearch, range: nil){{/pathParams}}
let url = {{projectName}}API.basePath + path
let URLString = {{projectName}}API.basePath + path
{{#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}}
]{{/hasMore}}{{/queryParams}}
let parameters = APIHelper.rejectNil(nillableParameters){{/bodyParam}}
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}}
}

View File

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

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