mirror of
https://github.com/valitydev/openapi-generator.git
synced 2024-11-08 03:18:53 +00:00
Merge branch 'ruby-api-client' into ruby-apiclient
This commit is contained in:
commit
6d58d44542
47
.dockerignore
Normal file
47
.dockerignore
Normal 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
13
Dockerfile
Normal 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"]
|
19
README.md
19
README.md
@ -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
31
bin/csharp-dotnet2-petstore.sh
Executable 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
31
bin/flash-petstore.sh
Executable 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
|
31
bin/java-inflector-petstore-server.sh
Executable file
31
bin/java-inflector-petstore-server.sh
Executable 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
|
@ -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();
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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"));
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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.
|
||||
|
||||
|
||||
|
@ -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}}
|
||||
}
|
@ -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
|
@ -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}}
|
||||
}
|
@ -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>
|
@ -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;
|
||||
}
|
||||
|
@ -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}};
|
||||
|
@ -0,0 +1,8 @@
|
||||
# Swagger Inflector
|
||||
|
||||
Run with
|
||||
|
||||
```
|
||||
mvn package jetty:run
|
||||
``
|
||||
|
@ -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}}
|
||||
|
@ -0,0 +1 @@
|
||||
{{#isBodyParam}}{{{dataType}}} {{paramName}}{{/isBodyParam}}
|
@ -0,0 +1 @@
|
||||
{{#isFormParam}}{{#notFile}}{{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}FormDataContentDisposition fileDetail{{/isFile}}{{/isFormParam}}
|
@ -0,0 +1 @@
|
||||
{{#isHeaderParam}}{{{dataType}}} {{paramName}}{{/isHeaderParam}}
|
@ -0,0 +1,6 @@
|
||||
controllerPackage: {{invokerPackage}}
|
||||
modelPackage: {{modelPackage}}
|
||||
swaggerUrl: ./src/main/swagger/swagger.json
|
||||
modelMappings:
|
||||
{{#models}}{{#model}}{{classname}} : {{modelPackage}}.{{classname}}{{/model}}
|
||||
{{/models}}
|
@ -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}}
|
@ -0,0 +1 @@
|
||||
{{#isPathParam}}{{{dataType}}} {{paramName}}{{/isPathParam}}
|
@ -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>
|
@ -0,0 +1 @@
|
||||
{{#isQueryParam}}{{{dataType}}} {{paramName}}{{/isQueryParam}}
|
@ -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>
|
@ -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
|
||||
|
@ -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}}
|
||||
|
@ -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}}
|
||||
|
@ -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}}
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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}}
|
||||
|
@ -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}}
|
||||
}
|
||||
}
|
||||
|
@ -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}}
|
||||
|
||||
}
|
||||
|
@ -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}}
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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}}
|
||||
|
@ -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
|
||||
|
@ -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}}
|
||||
///
|
||||
///
|
||||
|
@ -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}}
|
||||
|
@ -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}}
|
||||
|
@ -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)
|
||||
|
@ -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}}
|
||||
|
@ -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}}
|
||||
|
@ -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}}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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}}
|
||||
|
||||
|
||||
|
@ -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.
|
||||
|
@ -1,3 +1,5 @@
|
||||
# coding: utf-8
|
||||
|
||||
import sys
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
@ -33,11 +35,3 @@ setup(
|
||||
)
|
||||
|
||||
{{/hasMore}}{{/apis}}{{/apiInfo}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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}}
|
||||
}
|
||||
|
@ -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}}
|
@ -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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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"]))
|
||||
}
|
||||
}
|
||||
|
@ -1,2 +1,2 @@
|
||||
github "Alamofire/Alamofire" >= 1.2
|
||||
github "Alamofire/Alamofire" >= 1.3
|
||||
github "mxcl/PromiseKit" >=1.5.3
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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
|
@ -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}}
|
||||
}
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user