mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-12-11 07:32:48 +00:00
Merge branch 'develop_2.0' into library-template-jersey2
Conflicts: modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java modules/swagger-codegen/src/main/resources/Java/api.mustache
This commit is contained in:
@@ -34,4 +34,108 @@ public class CodegenProperty {
|
||||
public boolean isEnum;
|
||||
public List<String> _enum;
|
||||
public Map<String, Object> allowableValues;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final CodegenProperty other = (CodegenProperty) obj;
|
||||
if ((this.baseName == null) ? (other.baseName != null) : !this.baseName.equals(other.baseName)) {
|
||||
return false;
|
||||
}
|
||||
if ((this.complexType == null) ? (other.complexType != null) : !this.complexType.equals(other.complexType)) {
|
||||
return false;
|
||||
}
|
||||
if ((this.getter == null) ? (other.getter != null) : !this.getter.equals(other.getter)) {
|
||||
return false;
|
||||
}
|
||||
if ((this.setter == null) ? (other.setter != null) : !this.setter.equals(other.setter)) {
|
||||
return false;
|
||||
}
|
||||
if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) {
|
||||
return false;
|
||||
}
|
||||
if ((this.datatype == null) ? (other.datatype != null) : !this.datatype.equals(other.datatype)) {
|
||||
return false;
|
||||
}
|
||||
if ((this.datatypeWithEnum == null) ? (other.datatypeWithEnum != null) : !this.datatypeWithEnum.equals(other.datatypeWithEnum)) {
|
||||
return false;
|
||||
}
|
||||
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
|
||||
return false;
|
||||
}
|
||||
if ((this.min == null) ? (other.min != null) : !this.min.equals(other.min)) {
|
||||
return false;
|
||||
}
|
||||
if ((this.max == null) ? (other.max != null) : !this.max.equals(other.max)) {
|
||||
return false;
|
||||
}
|
||||
if ((this.defaultValue == null) ? (other.defaultValue != null) : !this.defaultValue.equals(other.defaultValue)) {
|
||||
return false;
|
||||
}
|
||||
if ((this.baseType == null) ? (other.baseType != null) : !this.baseType.equals(other.baseType)) {
|
||||
return false;
|
||||
}
|
||||
if ((this.containerType == null) ? (other.containerType != null) : !this.containerType.equals(other.containerType)) {
|
||||
return false;
|
||||
}
|
||||
if (this.maxLength != other.maxLength && (this.maxLength == null || !this.maxLength.equals(other.maxLength))) {
|
||||
return false;
|
||||
}
|
||||
if (this.minLength != other.minLength && (this.minLength == null || !this.minLength.equals(other.minLength))) {
|
||||
return false;
|
||||
}
|
||||
if ((this.pattern == null) ? (other.pattern != null) : !this.pattern.equals(other.pattern)) {
|
||||
return false;
|
||||
}
|
||||
if ((this.example == null) ? (other.example != null) : !this.example.equals(other.example)) {
|
||||
return false;
|
||||
}
|
||||
if ((this.jsonSchema == null) ? (other.jsonSchema != null) : !this.jsonSchema.equals(other.jsonSchema)) {
|
||||
return false;
|
||||
}
|
||||
if (this.minimum != other.minimum && (this.minimum == null || !this.minimum.equals(other.minimum))) {
|
||||
return false;
|
||||
}
|
||||
if (this.maximum != other.maximum && (this.maximum == null || !this.maximum.equals(other.maximum))) {
|
||||
return false;
|
||||
}
|
||||
if (this.exclusiveMinimum != other.exclusiveMinimum && (this.exclusiveMinimum == null || !this.exclusiveMinimum.equals(other.exclusiveMinimum))) {
|
||||
return false;
|
||||
}
|
||||
if (this.exclusiveMaximum != other.exclusiveMaximum && (this.exclusiveMaximum == null || !this.exclusiveMaximum.equals(other.exclusiveMaximum))) {
|
||||
return false;
|
||||
}
|
||||
if (this.required != other.required && (this.required == null || !this.required.equals(other.required))) {
|
||||
return false;
|
||||
}
|
||||
if (this.secondaryParam != other.secondaryParam && (this.secondaryParam == null || !this.secondaryParam.equals(other.secondaryParam))) {
|
||||
return false;
|
||||
}
|
||||
if (this.isPrimitiveType != other.isPrimitiveType && (this.isPrimitiveType == null || !this.isPrimitiveType.equals(other.isPrimitiveType))) {
|
||||
return false;
|
||||
}
|
||||
if (this.isContainer != other.isContainer && (this.isContainer == null || !this.isContainer.equals(other.isContainer))) {
|
||||
return false;
|
||||
}
|
||||
if (this.isNotContainer != other.isNotContainer && (this.isNotContainer == null || !this.isNotContainer.equals(other.isNotContainer))) {
|
||||
return false;
|
||||
}
|
||||
if (this.isEnum != other.isEnum) {
|
||||
return false;
|
||||
}
|
||||
if (this._enum != other._enum && (this._enum == null || !this._enum.equals(other._enum))) {
|
||||
return false;
|
||||
}
|
||||
if (this.allowableValues != other.allowableValues && (this.allowableValues == null || !this.allowableValues.equals(other.allowableValues))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -64,7 +64,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>();
|
||||
|
||||
@@ -13,6 +13,7 @@ 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;
|
||||
@@ -387,12 +388,12 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
|
||||
for (String resourcePath : paths.keySet()) {
|
||||
Path path = paths.get(resourcePath);
|
||||
processOperation(resourcePath, "get", path.getGet(), ops);
|
||||
processOperation(resourcePath, "put", path.getPut(), ops);
|
||||
processOperation(resourcePath, "post", path.getPost(), ops);
|
||||
processOperation(resourcePath, "delete", path.getDelete(), ops);
|
||||
processOperation(resourcePath, "patch", path.getPatch(), ops);
|
||||
processOperation(resourcePath, "options", path.getOptions(), ops);
|
||||
processOperation(resourcePath, "get", path.getGet(), ops, path);
|
||||
processOperation(resourcePath, "put", path.getPut(), ops, path);
|
||||
processOperation(resourcePath, "post", path.getPost(), ops, path);
|
||||
processOperation(resourcePath, "delete", path.getDelete(), ops, path);
|
||||
processOperation(resourcePath, "patch", path.getPatch(), ops, path);
|
||||
processOperation(resourcePath, "options", path.getOptions(), ops, path);
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
@@ -405,14 +406,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());
|
||||
@@ -458,6 +480,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(" ");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,30 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import io.swagger.codegen.CliOption;
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenModel;
|
||||
import io.swagger.codegen.CodegenProperty;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
import io.swagger.codegen.SupportingFile;
|
||||
import io.swagger.models.ComposedModel;
|
||||
import io.swagger.models.Model;
|
||||
import io.swagger.models.ModelImpl;
|
||||
import io.swagger.models.RefModel;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.MapProperty;
|
||||
import io.swagger.models.properties.Property;
|
||||
import io.swagger.models.properties.StringProperty;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
@@ -21,7 +34,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
protected String artifactId = "swagger-java-client";
|
||||
protected String artifactVersion = "1.0.0";
|
||||
protected String sourceFolder = "src/main/java";
|
||||
|
||||
protected String localVariablePrefix = "";
|
||||
public JavaClientCodegen() {
|
||||
super();
|
||||
outputFolder = "generated-code/java";
|
||||
@@ -61,6 +74,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"));
|
||||
|
||||
supportedLibraries.put("<default>", "HTTP client: Jersey client 1.18. JSON processing: Jackson 2.4.2");
|
||||
supportedLibraries.put("jersey2", "HTTP client: Jersey client 2.6");
|
||||
@@ -115,6 +129,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"));
|
||||
@@ -254,6 +273,57 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
return camelize(operationId, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodegenModel fromModel(String name, Model model, Map<String, Model> allDefinitions) {
|
||||
CodegenModel codegenModel = super.fromModel(name, model, allDefinitions);
|
||||
|
||||
if (allDefinitions != null && codegenModel != null && codegenModel.parent != null && codegenModel.hasEnums) {
|
||||
final Model parentModel = allDefinitions.get(toModelName(codegenModel.parent));
|
||||
final CodegenModel parentCodegenModel = super.fromModel(codegenModel.parent, parentModel);
|
||||
codegenModel = this.reconcileInlineEnums(codegenModel, parentCodegenModel);
|
||||
}
|
||||
|
||||
return codegenModel;
|
||||
}
|
||||
|
||||
private CodegenModel reconcileInlineEnums(CodegenModel codegenModel, CodegenModel parentCodegenModel) {
|
||||
// This generator uses inline classes to define enums, which breaks when
|
||||
// dealing with models that have subTypes. To clean this up, we will analyze
|
||||
// the parent and child models, look for enums that match, and remove
|
||||
// them from the child models and leave them in the parent.
|
||||
// Because the child models extend the parents, the enums will be available via the parent.
|
||||
|
||||
// Only bother with reconciliation if the parent model has enums.
|
||||
if (parentCodegenModel.hasEnums) {
|
||||
|
||||
// Get the properties for the parent and child models
|
||||
final List<CodegenProperty> parentModelCodegenProperties = parentCodegenModel.vars;
|
||||
List<CodegenProperty> codegenProperties = codegenModel.vars;
|
||||
|
||||
// Iterate over all of the parent model properties
|
||||
for (CodegenProperty parentModelCodegenPropery : parentModelCodegenProperties) {
|
||||
// Look for enums
|
||||
if (parentModelCodegenPropery.isEnum) {
|
||||
// Now that we have found an enum in the parent class,
|
||||
// and search the child class for the same enum.
|
||||
Iterator<CodegenProperty> iterator = codegenProperties.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
CodegenProperty codegenProperty = iterator.next();
|
||||
if (codegenProperty.isEnum && codegenProperty.equals(parentModelCodegenPropery)) {
|
||||
// We found an enum in the child class that is
|
||||
// a duplicate of the one in the parent, so remove it.
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
codegenModel.vars = codegenProperties;
|
||||
}
|
||||
|
||||
return codegenModel;
|
||||
}
|
||||
|
||||
public void setInvokerPackage(String invokerPackage) {
|
||||
this.invokerPackage = invokerPackage;
|
||||
}
|
||||
@@ -273,4 +343,8 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
public void setSourceFolder(String sourceFolder) {
|
||||
this.sourceFolder = sourceFolder;
|
||||
}
|
||||
|
||||
public void setLocalVariablePrefix(String localVariablePrefix) {
|
||||
this.localVariablePrefix = localVariablePrefix;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -159,15 +159,17 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
// return the name in underscore style
|
||||
// PhoneNumber => phone_number
|
||||
name = underscore(name);
|
||||
|
||||
// parameter name starting with number won't compile
|
||||
// need to escape it by appending _ at the beginning
|
||||
if (name.matches("^[0-9]")) {
|
||||
if (name.matches("^\\d.*")) {
|
||||
name = "_" + name;
|
||||
}
|
||||
|
||||
// return the name in underscore style
|
||||
// PhoneNumber => phone_number
|
||||
return underscore(name);
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -79,12 +79,12 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
typeMapping.put("object", "object");
|
||||
typeMapping.put("DateTime", "\\DateTime");
|
||||
|
||||
cliOptions.add(new CliOption("invokerPackage", "The main namespace to use for all classes."));
|
||||
cliOptions.add(new CliOption("packagePath", "The main package name for classes."));
|
||||
cliOptions.add(new CliOption("invokerPackage", "The main namespace to use for all classes. e.g. Yay\\Pets"));
|
||||
cliOptions.add(new CliOption("packagePath", "The main package name for classes. e.g. GeneratedPetstore"));
|
||||
cliOptions.add(new CliOption("srcBasePath", "The directory under packagePath to serve as source root."));
|
||||
cliOptions.add(new CliOption("composerVendorName", "The vendor name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name."));
|
||||
cliOptions.add(new CliOption("composerProjectName", "The project name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name."));
|
||||
cliOptions.add(new CliOption("artifactVersion", "The version to use in the composer package version field."));
|
||||
cliOptions.add(new CliOption("composerVendorName", "The vendor name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. yaypets"));
|
||||
cliOptions.add(new CliOption("composerProjectName", "The project name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. petstore-client"));
|
||||
cliOptions.add(new CliOption("artifactVersion", "The version to use in the composer package version field. e.g. 1.2.3"));
|
||||
}
|
||||
|
||||
public String getPackagePath() {
|
||||
@@ -284,15 +284,17 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
// return the name in underscore style
|
||||
// PhoneNumber => phone_number
|
||||
name = underscore(name);
|
||||
|
||||
// parameter name starting with number won't compile
|
||||
// need to escape it by appending _ at the beginning
|
||||
if (name.matches("^[0-9]")) {
|
||||
if (name.matches("^\\d.*")) {
|
||||
name = "_" + name;
|
||||
}
|
||||
|
||||
// return the name in underscore style
|
||||
// PhoneNumber => phone_number
|
||||
return underscore(name);
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -19,22 +19,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}}
|
||||
@@ -45,7 +45,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) {
|
||||
@@ -54,42 +54,42 @@ 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, Object> formParams = new HashMap<String, Object>();
|
||||
List<Pair> {{localVariablePrefix}}queryParams = new ArrayList<Pair>();
|
||||
Map<String, String> {{localVariablePrefix}}headerParams = new HashMap<String, String>();
|
||||
Map<String, Object> {{localVariablePrefix}}formParams = new HashMap<String, Object>();
|
||||
|
||||
{{#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}}
|
||||
|
||||
{{#formParams}}if ({{paramName}} != null)
|
||||
formParams.put("{{baseName}}", {{paramName}});
|
||||
{{localVariablePrefix}}formParams.put("{{baseName}}", {{paramName}});
|
||||
{{/formParams}}
|
||||
|
||||
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);
|
||||
|
||||
String[] authNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
|
||||
String[] {{localVariablePrefix}}authNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
|
||||
{{#returnType}}
|
||||
TypeRef returnType = new TypeRef<{{{returnType}}}>() {};
|
||||
return apiClient.invokeAPI(path, "{{httpMethod}}", queryParams, postBody, headerParams, formParams, accept, contentType, authNames, returnType);
|
||||
TypeRef {{localVariablePrefix}}returnType = new TypeRef<{{{returnType}}}>() {};
|
||||
return {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, {{localVariablePrefix}}returnType);
|
||||
{{/returnType}}{{^returnType}}
|
||||
apiClient.invokeAPI(path, "{{httpMethod}}", queryParams, postBody, headerParams, formParams, accept, contentType, authNames, null);
|
||||
{{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, "{{httpMethod}}", {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, null);
|
||||
{{/returnType}}
|
||||
}
|
||||
{{/operation}}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
io.swagger.codegen.languages.AndroidClientCodegen
|
||||
io.swagger.codegen.languages.AsyncScalaClientCodegen
|
||||
io.swagger.codegen.languages.CSharpClientCodegen
|
||||
io.swagger.codegen.languages.FlashClientCodegen
|
||||
io.swagger.codegen.languages.JavaClientCodegen
|
||||
io.swagger.codegen.languages.JaxRSServerCodegen
|
||||
io.swagger.codegen.languages.JavaInflectorServerCodegen
|
||||
|
||||
@@ -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,341 +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;
|
||||
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", @"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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
{{#models}}{{#model}}#import "{{classname}}.h"
|
||||
{{/model}}{{/models}}
|
||||
|
||||
@class {{classPrefix}}Configuration;
|
||||
|
||||
/**
|
||||
* A key for `NSError` user info dictionaries.
|
||||
*
|
||||
@@ -29,22 +31,6 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
|
||||
@property(nonatomic, assign) NSTimeInterval timeoutInterval;
|
||||
@property(nonatomic, readonly) NSOperationQueue* queue;
|
||||
|
||||
/**
|
||||
* Gets the Api Client instance from pool
|
||||
*
|
||||
* @param baseUrl The base url of api client.
|
||||
*
|
||||
* @return The {{classPrefix}}ApiClient instance.
|
||||
*/
|
||||
+({{classPrefix}}ApiClient *)sharedClientFromPool:(NSString *)baseUrl;
|
||||
|
||||
/**
|
||||
* Gets the operations queue
|
||||
*
|
||||
* @return The `shardQueue` static variable.
|
||||
*/
|
||||
+(NSOperationQueue*) sharedQueue;
|
||||
|
||||
/**
|
||||
* Clears Cache
|
||||
*/
|
||||
@@ -116,11 +102,9 @@ extern NSString *const {{classPrefix}}ResponseObjectErrorKey;
|
||||
+(void) setReachabilityChangeBlock:(void(^)(int))changeBlock;
|
||||
|
||||
/**
|
||||
* Sets the client reachability strategy
|
||||
*
|
||||
* @param host The host of {{classPrefix}}ApiClient.
|
||||
* Sets the api client reachability strategy
|
||||
*/
|
||||
+(void) configureCacheReachibilityForHost:(NSString*)host;
|
||||
- (void)configureCacheReachibility;
|
||||
|
||||
/**
|
||||
* Detects Accept header from accepts NSArray
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
- (instancetype) init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.apiClient = nil;
|
||||
self.host = @"{{basePath}}";
|
||||
self.username = @"";
|
||||
self.password = @"";
|
||||
self.tempFolderPath = nil;
|
||||
|
||||
@@ -1,13 +1,26 @@
|
||||
#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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
-(void) addHeader:(NSString*)value forKey:(NSString*)key;
|
||||
-(unsigned long) requestQueueSize;
|
||||
+({{classname}}*) apiWithHeader:(NSString*)headerValue key:(NSString*)key;
|
||||
+(void) setBasePath:(NSString*)basePath;
|
||||
+(NSString*) getBasePath;
|
||||
{{#operation}}
|
||||
///
|
||||
///
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -247,12 +247,12 @@ class ApiClient(object):
|
||||
return None
|
||||
|
||||
if type(klass) == str:
|
||||
if 'list[' in klass:
|
||||
if klass.startswith('list['):
|
||||
sub_kls = re.match('list\[(.*)\]', klass).group(1)
|
||||
return [self.__deserialize(sub_data, sub_kls)
|
||||
for sub_data in data]
|
||||
|
||||
if 'dict(' in klass:
|
||||
if klass.startswith('dict('):
|
||||
sub_kls = re.match('dict\(([^,]*), (.*)\)', klass).group(2)
|
||||
return {k: self.__deserialize(v, sub_kls)
|
||||
for k, v in iteritems(data)}
|
||||
|
||||
@@ -19,7 +19,13 @@ Copyright 2015 SmartBear Software
|
||||
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
|
||||
|
||||
|
||||
@@ -216,10 +216,10 @@ class ApiException(Exception):
|
||||
error_message = "({0})\n"\
|
||||
"Reason: {1}\n".format(self.status, self.reason)
|
||||
if self.headers:
|
||||
error_message += "HTTP response headers: {0}".format(self.headers)
|
||||
error_message += "HTTP response headers: {0}\n".format(self.headers)
|
||||
|
||||
if self.body:
|
||||
error_message += "HTTP response body: {0}".format(self.body)
|
||||
error_message += "HTTP response body: {0}\n".format(self.body)
|
||||
|
||||
return error_message
|
||||
|
||||
|
||||
@@ -31,4 +31,55 @@ class JavaModelEnumTest extends FlatSpec with Matchers {
|
||||
enumVar.baseType should be("String")
|
||||
enumVar.isEnum should equal(true)
|
||||
}
|
||||
|
||||
it should "not override identical parent enums" in {
|
||||
|
||||
val identicalEnumProperty = new StringProperty()
|
||||
identicalEnumProperty.setEnum(List("VALUE1", "VALUE2", "VALUE3").asJava)
|
||||
|
||||
val subEnumProperty = new StringProperty()
|
||||
subEnumProperty.setEnum(List("SUB1", "SUB2", "SUB3").asJava)
|
||||
|
||||
// Add one enum ptoperty to the parent
|
||||
val parentProperties = new java.util.HashMap[String, Property]()
|
||||
parentProperties.put("sharedThing", identicalEnumProperty)
|
||||
|
||||
// Add TWO enums to the subType model; one of which is identical to the one in parent class
|
||||
val subProperties = new java.util.HashMap[String, Property]()
|
||||
subProperties.put("sharedThing", identicalEnumProperty)
|
||||
subProperties.put("unsharedThing", identicalEnumProperty)
|
||||
|
||||
val parentModel = new ModelImpl();
|
||||
parentModel.setProperties(parentProperties);
|
||||
parentModel.name("parentModel");
|
||||
|
||||
val subModel = new ModelImpl();
|
||||
subModel.setProperties(subProperties);
|
||||
subModel.name("subModel");
|
||||
|
||||
val model = new ComposedModel()
|
||||
.parent(new RefModel(parentModel.getName()))
|
||||
.child(subModel)
|
||||
.interfaces(new java.util.ArrayList[RefModel]())
|
||||
|
||||
val codegen = new JavaClientCodegen()
|
||||
val allModels = new java.util.HashMap[String, Model]()
|
||||
allModels.put(codegen.toModelName(parentModel.getName()), parentModel)
|
||||
allModels.put(codegen.toModelName(subModel.getName()), subModel)
|
||||
|
||||
val cm = codegen.fromModel("sample", model, allModels)
|
||||
|
||||
cm.name should be("sample")
|
||||
cm.classname should be("Sample")
|
||||
cm.parent should be("ParentModel")
|
||||
cm.imports.asScala should be(Set("ParentModel"))
|
||||
|
||||
// Assert that only the unshared/uninherited enum remains
|
||||
cm.vars.size should be (1)
|
||||
val enumVar = cm.vars.get(0)
|
||||
enumVar.baseName should be("unsharedThing")
|
||||
enumVar.datatype should be("String")
|
||||
enumVar.datatypeWithEnum should be("UnsharedThingEnum")
|
||||
enumVar.isEnum should equal(true)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user