mirror of
https://github.com/valitydev/openapi-generator.git
synced 2024-11-06 18:45:23 +00:00
Merge branch 'develop_2.0' into objc-dictionary-fix-dev2_0
Conflicts: modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/DefaultCodegen.java
This commit is contained in:
commit
37303745df
31
README.md
31
README.md
@ -13,12 +13,12 @@ The goal of Swagger™ is to define a standard, language-agnostic interface to R
|
||||
Check out [Swagger-Spec](https://github.com/swagger-api/swagger-spec) for additional information about the Swagger project, including additional libraries with support for other languages and more.
|
||||
|
||||
|
||||
## Compatibility
|
||||
The Swagger Specification has undergone 3 revisions since initial creation in 2010. The swagger-codegen project has the following compatibilities with the swagger specification:
|
||||
## Compatability
|
||||
The Swagger Specification has undergone 3 revisions since initial creation in 2010. The swagger-codegen project has the following compatibilies with the swagger specification:
|
||||
|
||||
Swagger Codegen Version | Release Date | Swagger Spec compatibility | Notes
|
||||
----------------------- | ------------ | -------------------------- | -----
|
||||
2.1.2-M1 (master) | 2015-02-23 | 1.0, 1.1, 1.2, 2.0 | [tag v2.1.0-M1](https://github.com/swagger-api/swagger-codegen)
|
||||
2.1.3-M1-SNAPSHOT | 2015-02-23 | 1.0, 1.1, 1.2, 2.0 | [tag v2.1.0-M1](https://github.com/swagger-api/swagger-codegen)
|
||||
2.0.17 | 2014-08-22 | 1.1, 1.2 | [tag v2.0.17](https://github.com/swagger-api/swagger-codegen/tree/v2.0.17)
|
||||
1.0.4 | 2012-04-12 | 1.0, 1.1 | [tag v1.0.4](https://github.com/swagger-api/swagger-codegen/tree/swagger-codegen_2.9.1-1.1)
|
||||
|
||||
@ -46,7 +46,7 @@ You can build a client against the swagger sample [petstore](http://petstore.swa
|
||||
This will run the generator with this command:
|
||||
|
||||
```
|
||||
java -jar modules/swagger-codegen-distribution/target/swagger-codegen-distribution-2.1.2-M1.jar \
|
||||
java -jar modules/swagger-codegen-distribution/target/swagger-codegen-distribution-2.1.3-M1-SNAPSHOT.jar \
|
||||
-i http://petstore.swagger.io/v2/swagger.json \
|
||||
-l java \
|
||||
-o samples/client/petstore/java
|
||||
@ -64,9 +64,9 @@ usage: Codegen
|
||||
-i,--input-spec <arg> location of the swagger spec, as URL or file
|
||||
-l,--lang <arg> client language to generate.
|
||||
Available languages include:
|
||||
[android, java, jaxrs, nodejs, objc, scalatra,
|
||||
scala, dynamic-html, html, swagger, tizen, php,
|
||||
python]
|
||||
[android, async-scala, java, jaxrs, nodejs,
|
||||
objc, scalatra, scala, dynamic-html, html,
|
||||
swagger, tizen, php, ruby, python]
|
||||
-o,--output <arg> where to write the generated files
|
||||
-t,--template-dir <arg> folder containing the template files
|
||||
```
|
||||
@ -93,6 +93,17 @@ Don't like the default swagger client syntax? Want a different language support
|
||||
|
||||
You can look at `modules/swagger-codegen/src/main/resources/${your-language}` for examples. To make your own templates, create your own files and use the `-t` flag to specify your tempalte folder. It actually is that easy.
|
||||
|
||||
### Making your own codegen modules
|
||||
If you're starting a project with a new language and don't see what you need, swagger-codegen can help you create a project to generate your own libraries:
|
||||
|
||||
```
|
||||
java -cp modules/swagger-codegen-distribution/target/swagger-codegen-distribution-2.1.3-M1-SNAPSHOT.jar \
|
||||
com.wordnik.swagger.codegen.MetaGenerator \
|
||||
-o output/myLibrary -n myClientCodegen -p com.my.company.codegen
|
||||
```
|
||||
|
||||
This will write, in the folder `output/myLibrary`, all the files you need to get started, including a README.md. Once modified and compiled, you can load your library with the codegen and generate clients with your own, custom-rolled logic.
|
||||
|
||||
### Where is Javascript???
|
||||
See our [javascript library](http://github.com/swagger-api/swagger-js)--it's completely dynamic and doesn't require
|
||||
static code generation.
|
||||
@ -189,7 +200,7 @@ You can also use the codegen to generate a server for a couple different framewo
|
||||
|
||||
### node.js
|
||||
```
|
||||
java -jar modules/swagger-codegen-distribution/target/swagger-codegen-distribution-2.1.2-M1.jar \
|
||||
java -jar modules/swagger-codegen-distribution/target/swagger-codegen-distribution-2.1.3-M1-SNAPSHOT.jar \
|
||||
-i http://petstore.swagger.io/v2/swagger.json \
|
||||
-l nodejs \
|
||||
-o samples/server/petstore/nodejs
|
||||
@ -201,7 +212,7 @@ java -jar modules/swagger-codegen-distribution/target/swagger-codegen-distributi
|
||||
|
||||
### scala scalatra
|
||||
```
|
||||
java -jar modules/swagger-codegen-distribution/target/swagger-codegen-distribution-2.1.2-M1.jar \
|
||||
java -jar modules/swagger-codegen-distribution/target/swagger-codegen-distribution-2.1.3-M1-SNAPSHOT.jar \
|
||||
-i http://petstore.swagger.io/v2/swagger.json \
|
||||
-l scalatra \
|
||||
-o samples/server/petstore/scalatra
|
||||
@ -210,7 +221,7 @@ java -jar modules/swagger-codegen-distribution/target/swagger-codegen-distributi
|
||||
### java jax-rs
|
||||
|
||||
```
|
||||
java -jar modules/swagger-codegen-distribution/target/swagger-codegen-distribution-2.1.2-M1.jar \
|
||||
java -jar modules/swagger-codegen-distribution/target/swagger-codegen-distribution-2.1.3-M1-SNAPSHOT.jar \
|
||||
-i http://petstore.swagger.io/v2/swagger.json \
|
||||
-l jaxrs \
|
||||
-o samples/server/petstore/jaxrs
|
||||
|
36
bin/ruby-petstore.sh
Executable file
36
bin/ruby-petstore.sh
Executable file
@ -0,0 +1,36 @@
|
||||
#!/bin/sh
|
||||
|
||||
SCRIPT="$0"
|
||||
|
||||
while [ -h "$SCRIPT" ] ; do
|
||||
ls=`ls -ld "$SCRIPT"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
SCRIPT="$link"
|
||||
else
|
||||
SCRIPT=`dirname "$SCRIPT"`/"$link"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ! -d "${APP_DIR}" ]; then
|
||||
APP_DIR=`dirname "$SCRIPT"`/..
|
||||
APP_DIR=`cd "${APP_DIR}"; pwd`
|
||||
fi
|
||||
|
||||
root=./modules/swagger-codegen-distribution/pom.xml
|
||||
|
||||
# gets version of swagger-codegen
|
||||
version=$(sed '/<project>/,/<\/project>/d;/<version>/!d;s/ *<\/\?version> *//g' $root | sed -n '2p' | sed -e 's,.*<version>\([^<]*\)</version>.*,\1,g')
|
||||
|
||||
executable="./modules/swagger-codegen-distribution/target/swagger-codegen-distribution-$version.jar"
|
||||
|
||||
if [ ! -f "$executable" ]
|
||||
then
|
||||
mvn clean package
|
||||
fi
|
||||
|
||||
# if you've executed sbt assembly previously it will use that instead.
|
||||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
ags="$@ -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l ruby -o samples/client/petstore/ruby"
|
||||
|
||||
java $JAVA_OPTS -jar $executable $ags
|
@ -2,7 +2,7 @@
|
||||
<parent>
|
||||
<groupId>com.wordnik</groupId>
|
||||
<artifactId>swagger-codegen-project</artifactId>
|
||||
<version>2.1.2-M1</version>
|
||||
<version>2.1.3-M1-SNAPSHOT</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@ -10,7 +10,7 @@
|
||||
<artifactId>swagger-codegen-distribution</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>swagger-codegen (executable)</name>
|
||||
<version>2.1.2-M1</version>
|
||||
<version>2.1.3-M1-SNAPSHOT</version>
|
||||
<build>
|
||||
<testSourceDirectory>src/test/scala</testSourceDirectory>
|
||||
<outputDirectory>target/classes</outputDirectory>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<parent>
|
||||
<groupId>com.wordnik</groupId>
|
||||
<artifactId>swagger-codegen-project</artifactId>
|
||||
<version>2.1.2-M1</version>
|
||||
<version>2.1.3-M1-SNAPSHOT</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@ -10,7 +10,7 @@
|
||||
<artifactId>swagger-codegen</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>swagger-codegen (core library)</name>
|
||||
<version>2.1.2-M1</version>
|
||||
<version>2.1.3-M1-SNAPSHOT</version>
|
||||
<build>
|
||||
<sourceDirectory>src/main/java</sourceDirectory>
|
||||
<defaultGoal>install</defaultGoal>
|
||||
|
@ -0,0 +1,60 @@
|
||||
package com.wordnik.swagger.codegen;
|
||||
|
||||
import com.samskivert.mustache.*;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
import java.io.*;
|
||||
|
||||
public abstract class AbstractGenerator {
|
||||
|
||||
public File writeToFile(String filename, String contents) throws IOException {
|
||||
System.out.println("writing file " + filename);
|
||||
File output = new File(filename);
|
||||
|
||||
if(output.getParent() != null && !new File(output.getParent()).exists()) {
|
||||
File parent = new File(output.getParent());
|
||||
parent.mkdirs();
|
||||
}
|
||||
Writer out = new BufferedWriter(new OutputStreamWriter(
|
||||
new FileOutputStream(output), "UTF-8"));
|
||||
|
||||
out.write(contents);
|
||||
out.close();
|
||||
return output;
|
||||
}
|
||||
|
||||
public String readTemplate(String name) {
|
||||
try{
|
||||
Reader reader = getTemplateReader(name);
|
||||
if(reader == null)
|
||||
throw new RuntimeException("no file found");
|
||||
java.util.Scanner s = new java.util.Scanner(reader).useDelimiter("\\A");
|
||||
return s.hasNext() ? s.next() : "";
|
||||
}
|
||||
catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new RuntimeException("can't load template " + name);
|
||||
}
|
||||
|
||||
public Reader getTemplateReader(String name) {
|
||||
try{
|
||||
InputStream is = this.getClass().getClassLoader().getResourceAsStream(getCPResourcePath(name));
|
||||
if(is == null)
|
||||
is = new FileInputStream(new File(name));
|
||||
if(is == null)
|
||||
throw new RuntimeException("no file found");
|
||||
return new InputStreamReader(is);
|
||||
}
|
||||
catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new RuntimeException("can't load template " + name);
|
||||
}
|
||||
|
||||
private String getCPResourcePath(String name) {
|
||||
if (!"/".equals(File.separator))
|
||||
return name.replaceAll(Pattern.quote(File.separator), "/");
|
||||
return name;
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package com.wordnik.swagger.codegen;
|
||||
|
||||
import com.wordnik.swagger.models.*;
|
||||
import com.wordnik.swagger.models.auth.SecuritySchemeDefinition;
|
||||
import com.wordnik.swagger.models.properties.*;
|
||||
|
||||
import java.util.*;
|
||||
@ -35,6 +36,8 @@ public interface CodegenConfig {
|
||||
|
||||
CodegenModel fromModel(String name, Model model);
|
||||
CodegenOperation fromOperation(String resourcePath, String httpMethod, Operation operation);
|
||||
List<CodegenSecurity> fromSecurity(Map<String, SecuritySchemeDefinition> schemes);
|
||||
|
||||
Set<String> defaultIncludes();
|
||||
Map<String, String> typeMapping();
|
||||
Map<String, String> instantiationTypes();
|
||||
|
@ -6,7 +6,8 @@ public enum CodegenModelType {
|
||||
OPERATION(CodegenOperation.class),
|
||||
PARAMETER(CodegenParameter.class),
|
||||
PROPERTY(CodegenProperty.class),
|
||||
RESPONSE(CodegenResponse.class);
|
||||
RESPONSE(CodegenResponse.class),
|
||||
SECURITY(CodegenSecurity.class);
|
||||
|
||||
private final Class<?> defaultImplementation;
|
||||
|
||||
|
@ -6,7 +6,8 @@ import java.util.*;
|
||||
|
||||
public class CodegenOperation {
|
||||
public Boolean hasConsumes, hasProduces, hasParams, returnTypeIsPrimitive,
|
||||
returnSimpleType, subresourceOperation, isMapContainer, isListContainer;
|
||||
returnSimpleType, subresourceOperation, isMapContainer, isListContainer,
|
||||
hasMore = Boolean.TRUE;
|
||||
public String path, operationId, returnType, httpMethod, returnBaseType,
|
||||
returnContainer, summary, notes, baseName, defaultResponse;
|
||||
|
||||
@ -18,6 +19,7 @@ public class CodegenOperation {
|
||||
public List<CodegenParameter> queryParams = new ArrayList<CodegenParameter>();
|
||||
public List<CodegenParameter> headerParams = new ArrayList<CodegenParameter>();
|
||||
public List<CodegenParameter> formParams = new ArrayList<CodegenParameter>();
|
||||
public List<CodegenSecurity> authMethods;
|
||||
public List<String> tags;
|
||||
public List<CodegenResponse> responses = new ArrayList<CodegenResponse>();
|
||||
public final List<CodegenProperty> responseHeaders = new ArrayList<CodegenProperty>();
|
||||
|
@ -4,6 +4,8 @@ public class CodegenParameter {
|
||||
public Boolean isFormParam, isQueryParam, isPathParam, isHeaderParam,
|
||||
isCookieParam, isBodyParam, isFile, notFile, hasMore, isContainer, secondaryParam;
|
||||
public String baseName, paramName, dataType, collectionFormat, description, baseType;
|
||||
public String jsonSchema;
|
||||
|
||||
/**
|
||||
* Determines whether this parameter is mandatory. If the parameter is in "path",
|
||||
* this property is required and its value MUST be true. Otherwise, the property
|
||||
@ -31,6 +33,7 @@ public class CodegenParameter {
|
||||
output.isCookieParam = this.isCookieParam;
|
||||
output.isBodyParam = this.isBodyParam;
|
||||
output.required = this.required;
|
||||
output.jsonSchema = this.jsonSchema;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ public class CodegenProperty {
|
||||
/** A free-form property to include an example of an instance for this schema. */
|
||||
public String example;
|
||||
|
||||
public String jsonSchema;
|
||||
public Double minimum, maximum, exclusiveMinimum, exclusiveMaximum;
|
||||
public Boolean hasMore = null, required = null, secondaryParam = null;
|
||||
public Boolean isPrimitiveType, isContainer, isNotContainer;
|
||||
|
@ -6,5 +6,12 @@ public class CodegenResponse {
|
||||
public String code, message;
|
||||
public Boolean hasMore;
|
||||
public List<Map<String, String>> examples;
|
||||
Object schema;
|
||||
public final List<CodegenProperty> headers = new ArrayList<CodegenProperty>();
|
||||
public String dataType, baseType, containerType;
|
||||
public Boolean simpleType;
|
||||
public Boolean primitiveType;
|
||||
public Boolean isMapContainer;
|
||||
public Boolean isListContainer;
|
||||
public Object schema;
|
||||
public String jsonSchema;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.wordnik.swagger.codegen;
|
||||
|
||||
public class CodegenSecurity {
|
||||
String name;
|
||||
String type;
|
||||
Boolean hasMore, isBasic, isOAuth, isApiKey;
|
||||
// ApiKey specific
|
||||
String keyParamName;
|
||||
Boolean isKeyInQuery, isKeyInHeader;
|
||||
|
||||
}
|
@ -1,17 +1,19 @@
|
||||
package com.wordnik.swagger.codegen;
|
||||
|
||||
import com.wordnik.swagger.models.*;
|
||||
import com.wordnik.swagger.models.auth.ApiKeyAuthDefinition;
|
||||
import com.wordnik.swagger.models.auth.BasicAuthDefinition;
|
||||
import com.wordnik.swagger.models.auth.In;
|
||||
import com.wordnik.swagger.models.auth.SecuritySchemeDefinition;
|
||||
import com.wordnik.swagger.models.parameters.*;
|
||||
import com.wordnik.swagger.models.properties.*;
|
||||
import com.wordnik.swagger.util.Json;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
public class DefaultCodegen {
|
||||
Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);
|
||||
@ -142,6 +144,8 @@ public class DefaultCodegen {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String toOperationId(String operationId) { return operationId; }
|
||||
|
||||
public String toVarName(String name) {
|
||||
if(reservedWords.contains(name))
|
||||
return escapeReservedWord(name);
|
||||
@ -156,6 +160,7 @@ public class DefaultCodegen {
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
public String escapeReservedWord(String name) {
|
||||
throw new RuntimeException("reserved word " + name + " not allowed");
|
||||
}
|
||||
@ -312,7 +317,7 @@ public class DefaultCodegen {
|
||||
}
|
||||
|
||||
public String snakeCase(String name) {
|
||||
return Character.toLowerCase(name.charAt(0)) + name.substring(1);
|
||||
return (name.length() > 0) ? (Character.toLowerCase(name.charAt(0)) + name.substring(1)) : "";
|
||||
}
|
||||
|
||||
public String initialCaps(String name) {
|
||||
@ -397,7 +402,14 @@ public class DefaultCodegen {
|
||||
LOGGER.warn("null property for " + key);
|
||||
}
|
||||
else {
|
||||
CodegenProperty cp = fromProperty(key, prop);
|
||||
CodegenProperty cp;
|
||||
try{
|
||||
cp = fromProperty(key, prop);
|
||||
}
|
||||
catch(Exception e) {
|
||||
System.out.println("failed to process model " + name);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
cp.required = false;
|
||||
if(impl.getRequired() != null) {
|
||||
for(String req : impl.getRequired()) {
|
||||
@ -439,6 +451,20 @@ public class DefaultCodegen {
|
||||
return m;
|
||||
}
|
||||
|
||||
public String getterAndSetterCapitalize(String name) {
|
||||
if (name == null || name.length() == 0) {
|
||||
return name;
|
||||
}
|
||||
name = toVarName(name);
|
||||
if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
|
||||
Character.isLowerCase(name.charAt(0))){
|
||||
return name;
|
||||
}
|
||||
char chars[] = name.toCharArray();
|
||||
chars[0] = Character.toUpperCase(chars[0]);
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
public CodegenProperty fromProperty(String name, Property p) {
|
||||
if(p == null) {
|
||||
LOGGER.error("unexpected missing property for name " + null);
|
||||
@ -449,13 +475,13 @@ public class DefaultCodegen {
|
||||
property.name = toVarName(name);
|
||||
property.baseName = name;
|
||||
property.description = escapeText(p.getDescription());
|
||||
property.getter = "get" + initialCaps(name);
|
||||
property.setter = "set" + initialCaps(name);
|
||||
property.getter = "get" + getterAndSetterCapitalize(name);
|
||||
property.setter = "set" + getterAndSetterCapitalize(name);
|
||||
property.example = p.getExample();
|
||||
property.defaultValue = toDefaultValue(p);
|
||||
property.jsonSchema = Json.pretty(p);
|
||||
|
||||
String type = getSwaggerType(p);
|
||||
|
||||
if(p instanceof AbstractNumericProperty) {
|
||||
AbstractNumericProperty np = (AbstractNumericProperty) p;
|
||||
property.minimum = np.getMinimum();
|
||||
@ -528,18 +554,29 @@ public class DefaultCodegen {
|
||||
property.isPrimitiveType = true;
|
||||
}
|
||||
else {
|
||||
setNonArrayMapProperty(property, type);
|
||||
}
|
||||
return property;
|
||||
}
|
||||
|
||||
protected void setNonArrayMapProperty(CodegenProperty property, String type) {
|
||||
property.isNotContainer = true;
|
||||
if(languageSpecificPrimitives().contains(type))
|
||||
property.isPrimitiveType = true;
|
||||
else
|
||||
property.complexType = property.baseType;
|
||||
}
|
||||
return property;
|
||||
}
|
||||
|
||||
private Response findMethodResponse(Map<String, Response> responses) {
|
||||
|
||||
String code = null;
|
||||
for(String responseCode : responses.keySet()) {
|
||||
if (responseCode.startsWith("2") || responseCode.equals("default")) {
|
||||
if (code == null || code.compareTo(responseCode) > 0) {
|
||||
code = responseCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (code == null)
|
||||
return null;
|
||||
return responses.get(code);
|
||||
}
|
||||
|
||||
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation){
|
||||
CodegenOperation op = CodegenModelFactory.newInstance(CodegenModelType.OPERATION);
|
||||
@ -570,13 +607,11 @@ public class DefaultCodegen {
|
||||
LOGGER.warn("generated operationId " + operationId);
|
||||
}
|
||||
op.path = path;
|
||||
op.operationId = operationId;
|
||||
op.operationId = toOperationId(operationId);
|
||||
op.summary = escapeText(operation.getSummary());
|
||||
op.notes = escapeText(operation.getDescription());
|
||||
op.tags = operation.getTags();
|
||||
|
||||
Response methodResponse = null;
|
||||
|
||||
if(operation.getConsumes() != null && operation.getConsumes().size() > 0) {
|
||||
List<Map<String, String>> c = new ArrayList<Map<String, String>>();
|
||||
int count = 0;
|
||||
@ -586,6 +621,8 @@ public class DefaultCodegen {
|
||||
count += 1;
|
||||
if (count < operation.getConsumes().size())
|
||||
mediaType.put("hasMore", "true");
|
||||
else
|
||||
mediaType.put("hasMore", null);
|
||||
c.add(mediaType);
|
||||
}
|
||||
op.consumes = c;
|
||||
@ -601,81 +638,52 @@ public class DefaultCodegen {
|
||||
count += 1;
|
||||
if (count < operation.getProduces().size())
|
||||
mediaType.put("hasMore", "true");
|
||||
else
|
||||
mediaType.put("hasMore", null);
|
||||
c.add(mediaType);
|
||||
}
|
||||
op.produces = c;
|
||||
op.hasProduces = true;
|
||||
}
|
||||
|
||||
if(operation.getResponses() != null) {
|
||||
for(String responseCode: new TreeSet<String>(operation.getResponses().keySet())) {
|
||||
Response response = operation.getResponses().get(responseCode);
|
||||
if (responseCode.startsWith("2")) {
|
||||
// use the first, i.e. the smallest 2xx response status as methodResponse
|
||||
methodResponse = response;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(methodResponse == null && operation.getResponses().keySet().contains("default")) {
|
||||
methodResponse = operation.getResponses().get("default");
|
||||
}
|
||||
for(String responseCode: operation.getResponses().keySet()) {
|
||||
Response response = operation.getResponses().get(responseCode);
|
||||
if(response != methodResponse) {
|
||||
CodegenResponse r = fromResponse(responseCode, response);
|
||||
if (operation.getResponses() != null && !operation.getResponses().isEmpty()) {
|
||||
Response methodResponse = findMethodResponse(operation.getResponses());
|
||||
CodegenResponse methodCodegenResponse = null;
|
||||
|
||||
for (Map.Entry<String, Response> entry : operation.getResponses().entrySet()) {
|
||||
Response response = entry.getValue();
|
||||
CodegenResponse r = fromResponse(entry.getKey(), response);
|
||||
r.hasMore = true;
|
||||
if(r.baseType != null &&
|
||||
!defaultIncludes.contains(r.baseType) &&
|
||||
!languageSpecificPrimitives.contains(r.baseType))
|
||||
imports.add(r.baseType);
|
||||
|
||||
if (response == methodResponse)
|
||||
methodCodegenResponse = r;
|
||||
op.responses.add(r);
|
||||
}
|
||||
for(int i = 0; i < op.responses.size() - 1; i++) {
|
||||
CodegenResponse r = op.responses.get(i);
|
||||
r.hasMore = new Boolean(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
op.responses.get(op.responses.size() - 1).hasMore = false;
|
||||
|
||||
if (methodResponse != null) {
|
||||
op.returnType = methodCodegenResponse.dataType;
|
||||
op.returnBaseType = methodCodegenResponse.baseType;
|
||||
op.returnSimpleType = methodCodegenResponse.simpleType;
|
||||
op.returnTypeIsPrimitive = methodCodegenResponse.primitiveType;
|
||||
op.returnContainer = methodCodegenResponse.containerType;
|
||||
op.isListContainer = methodCodegenResponse.isListContainer;
|
||||
op.isMapContainer = methodCodegenResponse.isMapContainer;
|
||||
if (methodResponse.getSchema() != null) {
|
||||
CodegenProperty cm = fromProperty("response", methodResponse.getSchema());
|
||||
|
||||
Property responseProperty = methodResponse.getSchema();
|
||||
|
||||
if(responseProperty instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) responseProperty;
|
||||
CodegenProperty innerProperty = fromProperty("response", ap.getItems());
|
||||
op.returnBaseType = innerProperty.baseType;
|
||||
}
|
||||
else {
|
||||
if(cm.complexType != null)
|
||||
op.returnBaseType = cm.complexType;
|
||||
else
|
||||
op.returnBaseType = cm.baseType;
|
||||
}
|
||||
responseProperty.setRequired(true);
|
||||
CodegenProperty cm = fromProperty("response", responseProperty);
|
||||
op.examples = toExamples(methodResponse.getExamples());
|
||||
op.defaultResponse = toDefaultValue(responseProperty);
|
||||
op.returnType = cm.datatype;
|
||||
if(cm.isContainer != null) {
|
||||
op.returnContainer = cm.containerType;
|
||||
if("map".equals(cm.containerType))
|
||||
op.isMapContainer = Boolean.TRUE;
|
||||
else if ("list".equalsIgnoreCase(cm.containerType))
|
||||
op.isListContainer = Boolean.TRUE;
|
||||
}
|
||||
else
|
||||
op.returnSimpleType = true;
|
||||
if (languageSpecificPrimitives().contains(op.returnBaseType) || op.returnBaseType == null)
|
||||
op.returnTypeIsPrimitive = true;
|
||||
}
|
||||
addHeaders(methodResponse, op.responseHeaders);
|
||||
}
|
||||
|
||||
if(op.returnBaseType == null) {
|
||||
op.returnTypeIsPrimitive = true;
|
||||
op.returnSimpleType = true;
|
||||
}
|
||||
|
||||
if(op.returnBaseType != null &&
|
||||
!defaultIncludes.contains(op.returnBaseType) &&
|
||||
!languageSpecificPrimitives.contains(op.returnBaseType))
|
||||
imports.add(op.returnBaseType);
|
||||
}
|
||||
|
||||
List<Parameter> parameters = operation.getParameters();
|
||||
CodegenParameter bodyParam = null;
|
||||
@ -756,6 +764,42 @@ public class DefaultCodegen {
|
||||
r.message = response.getDescription();
|
||||
r.schema = response.getSchema();
|
||||
r.examples = toExamples(response.getExamples());
|
||||
r.jsonSchema = Json.pretty(response);
|
||||
addHeaders(response, r.headers);
|
||||
|
||||
if (r.schema != null) {
|
||||
Property responseProperty = response.getSchema();
|
||||
responseProperty.setRequired(true);
|
||||
CodegenProperty cm = fromProperty("response", responseProperty);
|
||||
|
||||
if(responseProperty instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) responseProperty;
|
||||
CodegenProperty innerProperty = fromProperty("response", ap.getItems());
|
||||
r.baseType = innerProperty.baseType;
|
||||
}
|
||||
else {
|
||||
if(cm.complexType != null)
|
||||
r.baseType = cm.complexType;
|
||||
else
|
||||
r.baseType = cm.baseType;
|
||||
}
|
||||
r.dataType = cm.datatype;
|
||||
if(cm.isContainer != null) {
|
||||
r.simpleType = false;
|
||||
r.containerType = cm.containerType;
|
||||
r.isMapContainer = "map".equals(cm.containerType);
|
||||
r.isListContainer = "list".equals(cm.containerType);
|
||||
}
|
||||
else
|
||||
r.simpleType = true;
|
||||
r.primitiveType = (r.baseType == null ||languageSpecificPrimitives().contains(r.baseType));
|
||||
}
|
||||
if (r.baseType == null) {
|
||||
r.isMapContainer = false;
|
||||
r.isListContainer = false;
|
||||
r.primitiveType = true;
|
||||
r.simpleType = true;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -764,6 +808,7 @@ public class DefaultCodegen {
|
||||
p.baseName = param.getName();
|
||||
p.description = param.getDescription();
|
||||
p.required = param.getRequired();
|
||||
p.jsonSchema = Json.pretty(param);
|
||||
|
||||
if(param instanceof SerializableParameter) {
|
||||
SerializableParameter qp = (SerializableParameter) param;
|
||||
@ -853,6 +898,38 @@ public class DefaultCodegen {
|
||||
return p;
|
||||
}
|
||||
|
||||
public List<CodegenSecurity> fromSecurity(Map<String, SecuritySchemeDefinition> schemes) {
|
||||
if(schemes == null)
|
||||
return null;
|
||||
|
||||
List<CodegenSecurity> secs = new ArrayList<CodegenSecurity>();
|
||||
for(Iterator entries = schemes.entrySet().iterator(); entries.hasNext(); ) {
|
||||
Map.Entry<String, SecuritySchemeDefinition> entry = (Map.Entry<String, SecuritySchemeDefinition>) entries.next();
|
||||
final SecuritySchemeDefinition schemeDefinition = entry.getValue();
|
||||
|
||||
CodegenSecurity sec = CodegenModelFactory.newInstance(CodegenModelType.SECURITY);
|
||||
sec.name = entry.getKey();
|
||||
sec.type = schemeDefinition.getType();
|
||||
|
||||
if (schemeDefinition instanceof ApiKeyAuthDefinition) {
|
||||
final ApiKeyAuthDefinition apiKeyDefinition = (ApiKeyAuthDefinition) schemeDefinition;
|
||||
sec.isBasic = sec.isOAuth = false;
|
||||
sec.isApiKey = true;
|
||||
sec.keyParamName = apiKeyDefinition.getName();
|
||||
sec.isKeyInHeader = apiKeyDefinition.getIn() == In.HEADER;
|
||||
sec.isKeyInQuery = !sec.isKeyInHeader;
|
||||
} else {
|
||||
sec.isKeyInHeader = sec.isKeyInQuery = sec.isApiKey = false;
|
||||
sec.isBasic = schemeDefinition instanceof BasicAuthDefinition;
|
||||
sec.isOAuth = !sec.isBasic;
|
||||
}
|
||||
|
||||
sec.hasMore = entries.hasNext();
|
||||
secs.add(sec);
|
||||
}
|
||||
return secs;
|
||||
}
|
||||
|
||||
protected List<Map<String, String>> toExamples(Map<String, String> examples) {
|
||||
if(examples == null)
|
||||
return null;
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.wordnik.swagger.codegen;
|
||||
|
||||
import com.wordnik.swagger.models.*;
|
||||
import com.wordnik.swagger.models.auth.SecuritySchemeDefinition;
|
||||
import com.wordnik.swagger.util.*;
|
||||
import com.samskivert.mustache.*;
|
||||
|
||||
@ -10,7 +11,7 @@ import java.util.*;
|
||||
import java.util.regex.*;
|
||||
import java.io.*;
|
||||
|
||||
public class DefaultGenerator implements Generator {
|
||||
public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
protected CodegenConfig config;
|
||||
protected ClientOptInput opts = null;
|
||||
protected Swagger swagger = null;
|
||||
@ -55,6 +56,9 @@ public class DefaultGenerator implements Generator {
|
||||
if(license.getUrl() != null)
|
||||
config.additionalProperties().put("licenseUrl", license.getUrl());
|
||||
}
|
||||
if(info.getVersion() != null) {
|
||||
config.additionalProperties().put("version", info.getVersion());
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder hostBuilder = new StringBuilder();
|
||||
@ -64,9 +68,18 @@ public class DefaultGenerator implements Generator {
|
||||
}
|
||||
else
|
||||
hostBuilder.append("https://");
|
||||
hostBuilder.append(swagger.getHost()).append(swagger.getBasePath());
|
||||
if(swagger.getHost() != null)
|
||||
hostBuilder.append(swagger.getHost());
|
||||
else
|
||||
hostBuilder.append("localhost");
|
||||
if(swagger.getBasePath() != null)
|
||||
hostBuilder.append(swagger.getBasePath());
|
||||
else
|
||||
hostBuilder.append("/");
|
||||
String contextPath = swagger.getBasePath() == null ? "/" : swagger.getBasePath();
|
||||
String basePath = hostBuilder.toString();
|
||||
|
||||
|
||||
List<Object> allOperations = new ArrayList<Object>();
|
||||
List<Object> allModels = new ArrayList<Object>();
|
||||
|
||||
@ -110,12 +123,20 @@ public class DefaultGenerator implements Generator {
|
||||
List<CodegenOperation> ops = paths.get(tag);
|
||||
Map<String, Object> operation = processOperations(config, tag, ops);
|
||||
operation.put("basePath", basePath);
|
||||
operation.put("contextPath", contextPath);
|
||||
operation.put("baseName", tag);
|
||||
operation.put("modelPackage", config.modelPackage());
|
||||
operation.putAll(config.additionalProperties());
|
||||
operation.put("classname", config.toApiName(tag));
|
||||
operation.put("classVarName", config.toApiVarName(tag));
|
||||
allOperations.add(operation);
|
||||
|
||||
allOperations.add(new HashMap<String, Object>(operation));
|
||||
for(int i = 0; i < allOperations.size(); i++) {
|
||||
Map<String, Object> oo = (Map<String, Object>) allOperations.get(i);
|
||||
if(i < (allOperations.size() -1))
|
||||
oo.put("hasMore", "true");
|
||||
}
|
||||
|
||||
for(String templateName : config.apiTemplateFiles().keySet()) {
|
||||
String suffix = config.apiTemplateFiles().get(templateName);
|
||||
String filename = config.apiFileFolder() +
|
||||
@ -149,9 +170,11 @@ public class DefaultGenerator implements Generator {
|
||||
|
||||
Map<String, Object> apis = new HashMap<String, Object>();
|
||||
apis.put("apis", allOperations);
|
||||
if(swagger.getBasePath() != null) {
|
||||
bundle.put("basePath", swagger.getBasePath());
|
||||
if(swagger.getHost() != null) {
|
||||
bundle.put("host", swagger.getHost());
|
||||
}
|
||||
bundle.put("basePath", basePath);
|
||||
bundle.put("contextPath", contextPath);
|
||||
bundle.put("apiInfo", apis);
|
||||
bundle.put("models", allModels);
|
||||
bundle.put("apiFolder", config.apiPackage().replace('.', File.separatorChar));
|
||||
@ -227,6 +250,18 @@ public class DefaultGenerator implements Generator {
|
||||
return ops;
|
||||
}
|
||||
|
||||
public SecuritySchemeDefinition fromSecurity(String name) {
|
||||
Map<String, SecuritySchemeDefinition> map = swagger.getSecurityDefinitions();
|
||||
if(map == null)
|
||||
return null;
|
||||
SecuritySchemeDefinition scheme = map.get(name);
|
||||
if(scheme == null)
|
||||
return null;
|
||||
return scheme;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void processOperation(String resourcePath, String httpMethod, Operation operation, Map<String, List<CodegenOperation>> operations) {
|
||||
if(operation != null) {
|
||||
List<String> tags = operation.getTags();
|
||||
@ -239,8 +274,25 @@ public class DefaultGenerator implements Generator {
|
||||
CodegenOperation co = config.fromOperation(resourcePath, httpMethod, operation);
|
||||
co.tags = new ArrayList<String>();
|
||||
co.tags.add(sanitizeTag(tag));
|
||||
|
||||
config.addOperationToGroup(sanitizeTag(tag), resourcePath, operation, co, operations);
|
||||
|
||||
List<Map<String, List<String>>> securities = operation.getSecurity();
|
||||
if(securities == null)
|
||||
continue;
|
||||
Map<String, SecuritySchemeDefinition> authMethods = new HashMap<String, SecuritySchemeDefinition>();
|
||||
for (Map<String, List<String>> security : securities) {
|
||||
if (security.size() != 1) {
|
||||
//Not sure what to do
|
||||
continue;
|
||||
}
|
||||
String securityName = security.keySet().iterator().next();
|
||||
SecuritySchemeDefinition securityDefinition = fromSecurity(securityName);
|
||||
if(securityDefinition != null)
|
||||
authMethods.put(securityName, securityDefinition);
|
||||
}
|
||||
if(!authMethods.isEmpty()) {
|
||||
co.authMethods = config.fromSecurity(authMethods);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -259,57 +311,6 @@ public class DefaultGenerator implements Generator {
|
||||
return buf.toString().replaceAll("[^a-zA-Z ]", "");
|
||||
}
|
||||
|
||||
public File writeToFile(String filename, String contents) throws IOException {
|
||||
System.out.println("writing file " + filename);
|
||||
File output = new File(filename);
|
||||
|
||||
if(output.getParent() != null && !new File(output.getParent()).exists()) {
|
||||
File parent = new File(output.getParent());
|
||||
parent.mkdirs();
|
||||
}
|
||||
Writer out = new BufferedWriter(new OutputStreamWriter(
|
||||
new FileOutputStream(output), "UTF-8"));
|
||||
|
||||
out.write(contents);
|
||||
out.close();
|
||||
return output;
|
||||
}
|
||||
|
||||
public String readTemplate(String name) {
|
||||
try{
|
||||
Reader reader = getTemplateReader(name);
|
||||
if(reader == null)
|
||||
throw new RuntimeException("no file found");
|
||||
java.util.Scanner s = new java.util.Scanner(reader).useDelimiter("\\A");
|
||||
return s.hasNext() ? s.next() : "";
|
||||
}
|
||||
catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new RuntimeException("can't load template " + name);
|
||||
}
|
||||
|
||||
public Reader getTemplateReader(String name) {
|
||||
try{
|
||||
InputStream is = this.getClass().getClassLoader().getResourceAsStream(getCPResourcePath(name));
|
||||
if(is == null)
|
||||
is = new FileInputStream(new File(name));
|
||||
if(is == null)
|
||||
throw new RuntimeException("no file found");
|
||||
return new InputStreamReader(is);
|
||||
}
|
||||
catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new RuntimeException("can't load template " + name);
|
||||
}
|
||||
|
||||
private String getCPResourcePath(String name) {
|
||||
if (!"/".equals(File.separator))
|
||||
return name.replaceAll(Pattern.quote(File.separator), "/");
|
||||
return name;
|
||||
}
|
||||
|
||||
public Map<String, Object> processOperations(CodegenConfig config, String tag, List<CodegenOperation> ops) {
|
||||
Map<String, Object> operations = new HashMap<String, Object>();
|
||||
Map<String, Object> objs = new HashMap<String, Object>();
|
||||
@ -337,6 +338,14 @@ public Map<String, Object> processOperations(CodegenConfig config, String tag, L
|
||||
|
||||
operations.put("imports", imports);
|
||||
config.postProcessOperations(operations);
|
||||
if(objs.size() > 0) {
|
||||
List<CodegenOperation> os = (List<CodegenOperation>) objs.get("operation");
|
||||
|
||||
if(os != null && os.size() > 0) {
|
||||
CodegenOperation op = os.get(os.size() - 1);
|
||||
op.hasMore = null;
|
||||
}
|
||||
}
|
||||
return operations;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,180 @@
|
||||
package com.wordnik.swagger.codegen;
|
||||
|
||||
import com.wordnik.swagger.codegen.languages.*;
|
||||
import com.wordnik.swagger.models.Swagger;
|
||||
import com.wordnik.swagger.models.auth.AuthorizationValue;
|
||||
import com.wordnik.swagger.util.*;
|
||||
|
||||
import io.swagger.parser.SwaggerParser;
|
||||
|
||||
import com.samskivert.mustache.*;
|
||||
|
||||
import org.apache.commons.cli.*;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Reader;
|
||||
import java.util.*;
|
||||
|
||||
public class MetaGenerator extends AbstractGenerator {
|
||||
static Map<String, CodegenConfig> configs = new HashMap<String, CodegenConfig>();
|
||||
static String configString;
|
||||
static {
|
||||
List<CodegenConfig> extensions = getExtensions();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for(CodegenConfig config : extensions) {
|
||||
if(sb.toString().length() != 0)
|
||||
sb.append(", ");
|
||||
sb.append(config.getName());
|
||||
configs.put(config.getName(), config);
|
||||
configString = sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new MetaGenerator().generate(args);
|
||||
}
|
||||
|
||||
protected void generate(String[] args) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String targetLanguage = null;
|
||||
String outputFolder = null;
|
||||
String name = null;
|
||||
String targetPackage = "com.wordnik.swagger.codegen";
|
||||
final String templateDir = "codegen";
|
||||
|
||||
Options options = new Options();
|
||||
options.addOption("h", "help", false, "shows this message");
|
||||
options.addOption("l", "lang", false, "client language to generate.\nAvailable languages include:\n\t[" + configString + "]");
|
||||
options.addOption("o", "output", true, "where to write the generated files");
|
||||
options.addOption("n", "name", true, "the human-readable name of the generator");
|
||||
options.addOption("p", "package", true, "the package to put the main class into (defaults to com.wordnik.swagger.codegen");
|
||||
|
||||
ClientOptInput clientOptInput = new ClientOptInput();
|
||||
Swagger swagger = null;
|
||||
CommandLine cmd = null;
|
||||
try {
|
||||
CommandLineParser parser = new BasicParser();
|
||||
|
||||
cmd = parser.parse(options, args);
|
||||
if (cmd.hasOption("h")) {
|
||||
usage(options);
|
||||
return;
|
||||
}
|
||||
if (cmd.hasOption("n"))
|
||||
name = cmd.getOptionValue("n");
|
||||
else {
|
||||
System.out.println("name is required");
|
||||
usage(options);
|
||||
return;
|
||||
}
|
||||
if (cmd.hasOption("l"))
|
||||
targetLanguage = cmd.getOptionValue("l");
|
||||
if (cmd.hasOption("p"))
|
||||
targetPackage = cmd.getOptionValue("p");
|
||||
if (cmd.hasOption("o"))
|
||||
outputFolder = cmd.getOptionValue("o");
|
||||
else {
|
||||
System.out.println("output folder is required");
|
||||
usage(options);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
usage(options);
|
||||
return;
|
||||
}
|
||||
System.out.println("writing to folder " + outputFolder);
|
||||
File outputFolderLocation = new File(outputFolder);
|
||||
if(!outputFolderLocation.exists())
|
||||
outputFolderLocation.mkdirs();
|
||||
File sourceFolder = new File(outputFolder + File.separator + "src/main/java/" + targetPackage.replace('.', File.separatorChar));
|
||||
if(!sourceFolder.exists())
|
||||
sourceFolder.mkdirs();
|
||||
File resourcesFolder = new File(outputFolder + File.separator + "src/main/resources/META-INF/services");
|
||||
if(!resourcesFolder.exists())
|
||||
resourcesFolder.mkdirs();
|
||||
|
||||
String mainClass = Character.toUpperCase(name.charAt(0)) + name.substring(1) + "Generator";
|
||||
|
||||
List<SupportingFile> supportingFiles = new ArrayList<SupportingFile>();
|
||||
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
|
||||
supportingFiles.add(new SupportingFile("generatorClass.mustache",
|
||||
"src/main/java/" + File.separator + targetPackage.replace('.', File.separatorChar),
|
||||
mainClass + ".java"));
|
||||
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||
supportingFiles.add(new SupportingFile("api.template", "src/main/resources" + File.separator + name, "api.mustache"));
|
||||
supportingFiles.add(new SupportingFile("model.template", "src/main/resources" + File.separator + name, "model.mustache"));
|
||||
|
||||
supportingFiles.add(new SupportingFile("services.mustache", "src/main/resources/META-INF/services", "com.wordnik.swagger.codegen.CodegenConfig"));
|
||||
|
||||
List<File> files = new ArrayList<File>();
|
||||
|
||||
Map<String, Object> data = new HashMap<String, Object>();
|
||||
data.put("generatorPackage", targetPackage);
|
||||
data.put("generatorClass", mainClass);
|
||||
data.put("name", name);
|
||||
data.put("fullyQualifiedGeneratorClass", targetPackage + "." + mainClass);
|
||||
|
||||
for(SupportingFile support : supportingFiles) {
|
||||
try {
|
||||
String destinationFolder = outputFolder;
|
||||
if(support.folder != null && !"".equals(support.folder))
|
||||
destinationFolder += File.separator + support.folder;
|
||||
File of = new File(destinationFolder);
|
||||
if(!of.isDirectory())
|
||||
of.mkdirs();
|
||||
String outputFilename = destinationFolder + File.separator + support.destinationFilename;
|
||||
|
||||
if(support.templateFile.endsWith("mustache")) {
|
||||
String template = readTemplate(templateDir + File.separator + support.templateFile);
|
||||
Template tmpl = Mustache.compiler()
|
||||
.withLoader(new Mustache.TemplateLoader() {
|
||||
public Reader getTemplate (String name) {
|
||||
return getTemplateReader(templateDir + File.separator + name + ".mustache");
|
||||
};
|
||||
})
|
||||
.defaultValue("")
|
||||
.compile(template);
|
||||
|
||||
writeToFile(outputFilename, tmpl.execute(data));
|
||||
files.add(new File(outputFilename));
|
||||
}
|
||||
else {
|
||||
String template = readTemplate(templateDir + File.separator + support.templateFile);
|
||||
FileUtils.writeStringToFile(new File(outputFilename), template);
|
||||
System.out.println("copying file to " + outputFilename);
|
||||
files.add(new File(outputFilename));
|
||||
}
|
||||
}
|
||||
catch (java.io.IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<CodegenConfig> getExtensions() {
|
||||
ServiceLoader<CodegenConfig> loader = ServiceLoader.load(CodegenConfig.class);
|
||||
List<CodegenConfig> output = new ArrayList<CodegenConfig>();
|
||||
Iterator<CodegenConfig> itr = loader.iterator();
|
||||
while(itr.hasNext()) {
|
||||
output.add(itr.next());
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
static void usage(Options options) {
|
||||
HelpFormatter formatter = new HelpFormatter();
|
||||
formatter.printHelp( "MetaGenerator. Generator for creating a new template set " +
|
||||
"and configuration for Codegen. The output will be based on the language you " +
|
||||
"specify, and includes default templates to include.", options );
|
||||
}
|
||||
|
||||
public static CodegenConfig getConfig(String name) {
|
||||
if(configs.containsKey(name)) {
|
||||
return configs.get(name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
#---------------------------------------------------------------------
|
||||
# Global settings
|
||||
#---------------------------------------------------------------------
|
||||
global
|
||||
log 127.0.0.1 local2
|
||||
chroot /var/lib/haproxy
|
||||
pidfile /var/run/haproxy.pid
|
||||
maxconn 4000
|
||||
user haproxy
|
||||
group haproxy
|
||||
daemon
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# common defaults that all the 'listen' and 'backend' sections will
|
||||
# use if not designated in their block
|
||||
#---------------------------------------------------------------------
|
||||
defaults
|
||||
mode http
|
||||
log global
|
||||
option dontlognull
|
||||
option httpclose
|
||||
option httplog
|
||||
option forwardfor
|
||||
option redispatch
|
||||
timeout connect 10000 # default 10 second time out if a backend is not found
|
||||
timeout client 300000
|
||||
timeout server 300000
|
||||
maxconn 60000
|
||||
retries 3
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# main frontend which proxys to the backends
|
||||
#---------------------------------------------------------------------
|
||||
frontend main *:80
|
||||
default_backend app
|
||||
|
||||
acl is_swagger_online hdr_beg(host) -i online.swagger.io
|
||||
acl is_swagger_io hdr_beg(host) -i swagger.io
|
||||
acl is_old hdr_beg(host) -i swagger.wordnik.com
|
||||
acl is_old_editor hdr_beg(host) -i editor.swagger.wordnik.com
|
||||
acl is_validator_swagger path_beg /swagger.json
|
||||
|
||||
# online spec validator
|
||||
reqrep ([^\ ]*)\ /validator/(.*) \1\ /validator/validator/\2 if is_swagger_online
|
||||
|
||||
# something that didn't work
|
||||
reqrep ([^\ ]*)\ /swagger.json(.*) \1\ /validator/swagger.json if is_validator_swagger
|
||||
|
||||
# swagger schema
|
||||
reqrep ^([^\ :]*)\ /v2/schema.json(.*) \1\ /swagger-api/swagger-spec/master/schemas/v2.0/schema.json\2
|
||||
acl is_swagger_spec path_beg /swagger-api/swagger-spec
|
||||
|
||||
# swagger docs
|
||||
reqrep ^([^\ :]*)\ /swagger-core/documentation/annotations/apidocs/current(.*) \1\ /swagger-core/apidocs/\2
|
||||
acl is_swagger_docs path_beg /swagger-core/apidocs
|
||||
|
||||
use_backend github_swagger_io if is_swagger_docs
|
||||
use_backend validator if is_swagger_online
|
||||
use_backend validator if is_validator_swagger
|
||||
use_backend github_swagger_io if is_swagger_io !is_swagger_spec
|
||||
use_backend github_swagger_spec if is_swagger_spec
|
||||
|
||||
redirect location http://editor.swagger.io if is_old_editor
|
||||
redirect location http://swagger.io if is_old
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# round robin balancing between the various backends
|
||||
#---------------------------------------------------------------------
|
||||
backend github_swagger_io
|
||||
balance roundrobin
|
||||
server gh1 swagger-api.github.io:80 check
|
||||
|
||||
backend github_swagger_spec
|
||||
http-request set-header Host raw.githubusercontent.com
|
||||
rspirep ^Content-type:(.*) Content-Type:\ application/json
|
||||
rspirep ^Access-Control-Allow-Origin:(.*) Access-Control-Allow-Origin:*
|
||||
balance roundrobin
|
||||
server gh2 raw.githubusercontent.com:443 check ssl verify none
|
||||
|
||||
backend validator
|
||||
balance roundrobin
|
||||
server app1 127.0.0.1:8000 check
|
||||
|
||||
backend app
|
||||
balance roundrobin
|
||||
server app1 127.0.0.1:8000 check
|
@ -34,6 +34,17 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
|
||||
apiPackage = "io.swagger.client.api";
|
||||
modelPackage = "io.swagger.client.model";
|
||||
|
||||
reservedWords = new HashSet<String> (
|
||||
Arrays.asList(
|
||||
"abstract", "continue", "for", "new", "switch", "assert",
|
||||
"default", "if", "package", "synchronized", "boolean", "do", "goto", "private",
|
||||
"this", "break", "double", "implements", "protected", "throw", "byte", "else",
|
||||
"import", "public", "throws", "case", "enum", "instanceof", "return", "transient",
|
||||
"catch", "extends", "int", "short", "try", "char", "final", "interface", "static",
|
||||
"void", "class", "finally", "long", "strictfp", "volatile", "const", "float",
|
||||
"native", "super", "while")
|
||||
);
|
||||
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
|
@ -87,6 +87,15 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
if(reservedWords.contains(name))
|
||||
return escapeReservedWord(name);
|
||||
else {
|
||||
return name.replaceAll("-", "_");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeDeclaration(Property p) {
|
||||
if(p instanceof ArrayProperty) {
|
||||
|
@ -1,110 +1,170 @@
|
||||
package com.wordnik.swagger.codegen.languages;
|
||||
|
||||
import com.wordnik.swagger.codegen.*;
|
||||
import com.wordnik.swagger.models.Model;
|
||||
import com.wordnik.swagger.models.properties.*;
|
||||
import com.wordnik.swagger.util.Json;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.*;
|
||||
import com.wordnik.swagger.models.properties.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
|
||||
public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
protected String invokerPackage = "com.wordnik.client";
|
||||
protected String groupId = "com.wordnik";
|
||||
protected String artifactId = "swagger-client";
|
||||
protected String artifactVersion = "1.0.0";
|
||||
protected String apiVersion = "1.0.0";
|
||||
protected int serverPort = 8080;
|
||||
protected String projectName = "swagger-server";
|
||||
|
||||
public String apiPackage() {
|
||||
return "controllers";
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the type of generator.
|
||||
*
|
||||
* @return the CodegenType for this generator
|
||||
* @see com.wordnik.swagger.codegen.CodegenType
|
||||
*/
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.SERVER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a friendly name for the generator. This will be used by the generator
|
||||
* to select the library with the -l flag.
|
||||
*
|
||||
* @return the friendly name for the generator
|
||||
*/
|
||||
public String getName() {
|
||||
return "nodejs";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns human-friendly help for the generator. Provide the consumer with help
|
||||
* tips, parameters here
|
||||
*
|
||||
* @return A string value for the help message
|
||||
*/
|
||||
public String getHelp() {
|
||||
return "Generates a node.js server application compatible with the 1.2 swagger specification.";
|
||||
return "Generates a nodejs server library.";
|
||||
}
|
||||
|
||||
public NodeJSServerCodegen() {
|
||||
super();
|
||||
|
||||
// set the output folder here
|
||||
outputFolder = "generated-code/nodejs";
|
||||
apiTemplateFiles.put("api.mustache", ".js");
|
||||
|
||||
/**
|
||||
* Models. You can write model files using the modelTemplateFiles map.
|
||||
* if you want to create one template for file, you can do so here.
|
||||
* for multiple files for model, just put another entry in the `modelTemplateFiles` with
|
||||
* a different extension
|
||||
*/
|
||||
modelTemplateFiles.clear();
|
||||
|
||||
/**
|
||||
* Api classes. You can write classes for each Api file with the apiTemplateFiles map.
|
||||
* as with models, add multiple entries with different extensions for multiple files per
|
||||
* class
|
||||
*/
|
||||
apiTemplateFiles.put(
|
||||
"controller.mustache", // the template to use
|
||||
".js"); // the extension for each file to write
|
||||
|
||||
/**
|
||||
* Template Location. This is the location which templates will be read from. The generator
|
||||
* will use the resource stream to attempt to read the templates.
|
||||
*/
|
||||
templateDir = "nodejs";
|
||||
apiPackage = "app.apis";
|
||||
modelPackage = "app";
|
||||
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
|
||||
supportingFiles.add(new SupportingFile("package.mustache", "", "package.json"));
|
||||
supportingFiles.add(new SupportingFile("models.mustache", modelPackage, "models.js"));
|
||||
supportingFiles.add(new SupportingFile("main.mustache", "", "main.js"));
|
||||
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||
|
||||
languageSpecificPrimitives = new HashSet<String>(
|
||||
/**
|
||||
* Reserved words. Override this with reserved words specific to your language
|
||||
*/
|
||||
reservedWords = new HashSet<String> (
|
||||
Arrays.asList(
|
||||
"String",
|
||||
"boolean",
|
||||
"Boolean",
|
||||
"Double",
|
||||
"Integer",
|
||||
"Long",
|
||||
"Float")
|
||||
"break", "case", "class", "catch", "const", "continue", "debugger",
|
||||
"default", "delete", "do", "else", "export", "extends", "finally",
|
||||
"for", "function", "if", "import", "in", "instanceof", "let", "new",
|
||||
"return", "super", "switch", "this", "throw", "try", "typeof", "var",
|
||||
"void", "while", "with", "yield")
|
||||
);
|
||||
|
||||
/**
|
||||
* Additional Properties. These values can be passed to the templates and
|
||||
* are available in models, apis, and supporting files
|
||||
*/
|
||||
additionalProperties.put("apiVersion", apiVersion);
|
||||
additionalProperties.put("serverPort", serverPort);
|
||||
|
||||
/**
|
||||
* Supporting Files. You can write single files for the generator with the
|
||||
* entire object tree available. If the input file has a suffix of `.mustache
|
||||
* it will be processed by the template engine. Otherwise, it will be copied
|
||||
*/
|
||||
// supportingFiles.add(new SupportingFile("controller.mustache",
|
||||
// "controllers",
|
||||
// "controller.js")
|
||||
// );
|
||||
supportingFiles.add(new SupportingFile("swagger.mustache",
|
||||
"api",
|
||||
"swagger.json")
|
||||
);
|
||||
supportingFiles.add(new SupportingFile("index.mustache",
|
||||
"",
|
||||
"index.js")
|
||||
);
|
||||
supportingFiles.add(new SupportingFile("package.mustache",
|
||||
"",
|
||||
"package.json")
|
||||
);
|
||||
typeMapping.put("array", "array");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiName(String name) {
|
||||
if(name.length() == 0)
|
||||
return "DefaultController";
|
||||
return initialCaps(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiFilename(String name) {
|
||||
return toApiName(name);
|
||||
}
|
||||
/**
|
||||
* Escapes a reserved word as defined in the `reservedWords` array. Handle escaping
|
||||
* those terms here. This logic is only called if a variable matches the reseved words
|
||||
*
|
||||
* @return the escaped term
|
||||
*/
|
||||
@Override
|
||||
public String escapeReservedWord(String name) {
|
||||
return "_" + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
|
||||
List<Map<String, Object>> o = (List<Map<String, Object>>)objs.get("models");
|
||||
|
||||
for(Map<String, Object> modelMap : o) {
|
||||
try {
|
||||
CodegenModel m = (CodegenModel) modelMap.get("model");
|
||||
ObjectNode on = (ObjectNode) Json.mapper().readTree(m.modelJson);
|
||||
// inject the id field
|
||||
on.put("id", m.name);
|
||||
|
||||
// remove the definitions qualifier with this nasty hack
|
||||
m.modelJson = Json.pretty(on).replaceAll("\"#/definitions/", "\"");
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// skip conversion
|
||||
}
|
||||
}
|
||||
return objs;
|
||||
return "_" + name; // add an underscore to the name
|
||||
}
|
||||
|
||||
/**
|
||||
* Location to write api files. You can use the apiPackage() as defined when the class is
|
||||
* instantiated
|
||||
*/
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return outputFolder + File.separator + apiPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
public String modelFileFolder() {
|
||||
return outputFolder + File.separator + modelPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSwaggerType(Property p) {
|
||||
String swaggerType = super.getSwaggerType(p);
|
||||
String type = null;
|
||||
if(typeMapping.containsKey(swaggerType)) {
|
||||
return typeMapping.get(swaggerType);
|
||||
}
|
||||
else
|
||||
type = swaggerType;
|
||||
return toModelName(type);
|
||||
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
|
||||
Map<String, Object> objectMap = (Map<String, Object>)objs.get("operations");
|
||||
List<CodegenOperation> operations = (List<CodegenOperation>)objectMap.get("operation");
|
||||
for(CodegenOperation operation : operations) {
|
||||
operation.httpMethod = operation.httpMethod.toLowerCase();
|
||||
List<CodegenParameter> params = operation.allParams;
|
||||
if(params != null && params.size() == 0)
|
||||
operation.allParams = null;
|
||||
List<CodegenResponse> responses = operation.responses;
|
||||
if(responses != null) {
|
||||
for(CodegenResponse resp : responses) {
|
||||
if("0".equals(resp.code))
|
||||
resp.code = "default";
|
||||
}
|
||||
}
|
||||
}
|
||||
return objs;
|
||||
}
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
package com.wordnik.swagger.codegen.languages;
|
||||
|
||||
import com.wordnik.swagger.codegen.*;
|
||||
import com.wordnik.swagger.util.Json;
|
||||
import com.wordnik.swagger.models.properties.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
|
||||
public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
protected String invokerPackage = "com.wordnik.client";
|
||||
protected String groupId = "com.wordnik";
|
||||
protected String artifactId = "swagger-client";
|
||||
protected String artifactVersion = "1.0.0";
|
||||
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.CLIENT;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "ruby";
|
||||
}
|
||||
|
||||
public String getHelp() {
|
||||
return "Generates a Ruby client library.";
|
||||
}
|
||||
|
||||
public RubyClientCodegen() {
|
||||
super();
|
||||
modelPackage = "models";
|
||||
apiPackage = "lib";
|
||||
outputFolder = "generated-code/ruby";
|
||||
modelTemplateFiles.put("model.mustache", ".rb");
|
||||
apiTemplateFiles.put("api.mustache", ".rb");
|
||||
templateDir = "ruby";
|
||||
|
||||
typeMapping.clear();
|
||||
languageSpecificPrimitives.clear();
|
||||
|
||||
reservedWords = new HashSet<String> (
|
||||
Arrays.asList(
|
||||
"int")
|
||||
);
|
||||
|
||||
additionalProperties.put("invokerPackage", invokerPackage);
|
||||
additionalProperties.put("groupId", groupId);
|
||||
additionalProperties.put("artifactId", artifactId);
|
||||
additionalProperties.put("artifactVersion", artifactVersion);
|
||||
|
||||
languageSpecificPrimitives.add("int");
|
||||
languageSpecificPrimitives.add("array");
|
||||
languageSpecificPrimitives.add("map");
|
||||
languageSpecificPrimitives.add("string");
|
||||
languageSpecificPrimitives.add("DateTime");
|
||||
|
||||
typeMapping.put("long", "int");
|
||||
typeMapping.put("integer", "int");
|
||||
typeMapping.put("Array", "array");
|
||||
typeMapping.put("String", "string");
|
||||
typeMapping.put("List", "array");
|
||||
typeMapping.put("map", "map");
|
||||
|
||||
supportingFiles.add(new SupportingFile("swagger.mustache", "", "lib/swagger.rb"));
|
||||
supportingFiles.add(new SupportingFile("monkey.mustache", "", "lib/monkey.rb"));
|
||||
supportingFiles.add(new SupportingFile("swagger/request.mustache", "", "lib/swagger/request.rb"));
|
||||
supportingFiles.add(new SupportingFile("swagger/response.mustache", "", "lib/swagger/response.rb"));
|
||||
supportingFiles.add(new SupportingFile("swagger/version.mustache", "", "lib/swagger/version.rb"));
|
||||
supportingFiles.add(new SupportingFile("swagger/configuration.mustache", "", "lib/swagger/configuration.rb"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeReservedWord(String name) {
|
||||
return "_" + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return outputFolder + "/" + apiPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
public String modelFileFolder() {
|
||||
return outputFolder + "/" + modelPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeDeclaration(Property p) {
|
||||
if(p instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) p;
|
||||
Property inner = ap.getItems();
|
||||
return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]";
|
||||
}
|
||||
else if (p instanceof MapProperty) {
|
||||
MapProperty mp = (MapProperty) p;
|
||||
Property inner = mp.getAdditionalProperties();
|
||||
return getSwaggerType(p) + "[string," + getTypeDeclaration(inner) + "]";
|
||||
}
|
||||
return super.getTypeDeclaration(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSwaggerType(Property p) {
|
||||
String swaggerType = super.getSwaggerType(p);
|
||||
String type = null;
|
||||
if(typeMapping.containsKey(swaggerType)) {
|
||||
type = typeMapping.get(swaggerType);
|
||||
if(languageSpecificPrimitives.contains(type)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
else
|
||||
type = swaggerType;
|
||||
if(type == null)
|
||||
return null;
|
||||
return type;
|
||||
}
|
||||
|
||||
public String toDefaultValue(Property p) {
|
||||
return "null";
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ public class ScalaClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
protected String groupId = "com.wordnik";
|
||||
protected String artifactId = "swagger-client";
|
||||
protected String artifactVersion = "1.0.0";
|
||||
protected String sourceFolder = "src/main/java";
|
||||
protected String sourceFolder = "src/main/scala";
|
||||
protected String authScheme = "";
|
||||
protected boolean authPreemptive = false;
|
||||
protected boolean asyncHttpClient = !authScheme.isEmpty();
|
||||
|
@ -23,7 +23,10 @@ public class SwaggerGenerator extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
public SwaggerGenerator() {
|
||||
super();
|
||||
templateDir = "swagger";
|
||||
outputFolder = "generated-code/swagger";
|
||||
|
||||
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,44 @@
|
||||
package com.wordnik.swagger.codegen.languages;
|
||||
|
||||
import com.wordnik.swagger.codegen.*;
|
||||
import com.wordnik.swagger.util.*;
|
||||
import com.wordnik.swagger.models.Swagger;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class SwaggerYamlGenerator extends DefaultCodegen implements CodegenConfig {
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.DOCUMENTATION;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "swagger-yaml";
|
||||
}
|
||||
|
||||
public String getHelp() {
|
||||
return "Creates a static swagger.yaml file.";
|
||||
}
|
||||
|
||||
public SwaggerYamlGenerator() {
|
||||
super();
|
||||
templateDir = "swagger";
|
||||
outputFolder = "generated-code/swagger";
|
||||
|
||||
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processSwagger(Swagger swagger) {
|
||||
try{
|
||||
String swaggerString = Yaml.mapper().writeValueAsString(swagger);
|
||||
String outputFile = outputFolder + File.separator + "swagger.yaml";
|
||||
FileUtils.writeStringToFile(new File(outputFile), swaggerString);
|
||||
System.out.println("wrote file to " + outputFile);
|
||||
}
|
||||
catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -58,10 +58,10 @@ public class {{classname}} {
|
||||
Map<String, String> headerParams = new HashMap<String, String>();
|
||||
Map<String, String> formParams = new HashMap<String, String>();
|
||||
|
||||
{{#queryParams}}if(!"null".equals(String.valueOf({{paramName}})))
|
||||
queryParams.put("{{baseName}}", String.valueOf({{paramName}}));
|
||||
{{#queryParams}}if ({{paramName}} != null)
|
||||
queryParams.put("{{baseName}}", ApiInvoker.parameterToString({{paramName}}));
|
||||
{{/queryParams}}
|
||||
{{#headerParams}}headerParams.put("{{baseName}}", {{paramName}});
|
||||
{{#headerParams}}headerParams.put("{{baseName}}", ApiInvoker.parameterToString({{paramName}}));
|
||||
{{/headerParams}}
|
||||
String[] contentTypes = {
|
||||
{{#consumes}}"{{mediaType}}"{{#hasMore}},{{/hasMore}}{{/consumes}}
|
||||
@ -74,7 +74,7 @@ public class {{classname}} {
|
||||
FormDataMultiPart mp = new FormDataMultiPart();
|
||||
{{#formParams}}{{#notFile}}
|
||||
hasFields = true;
|
||||
mp.field("{{baseName}}", {{paramName}}, MediaType.MULTIPART_FORM_DATA_TYPE);
|
||||
mp.field("{{baseName}}", ApiInvoker.parameterToString({{paramName}}), MediaType.MULTIPART_FORM_DATA_TYPE);
|
||||
{{/notFile}}{{#isFile}}
|
||||
hasFields = true;
|
||||
mp.field("{{baseName}}", {{paramName}}, MediaType.MULTIPART_FORM_DATA_TYPE);
|
||||
@ -83,7 +83,7 @@ public class {{classname}} {
|
||||
postBody = mp;
|
||||
}
|
||||
else {
|
||||
{{#formParams}}{{#notFile}}formParams.put("{{baseName}}", {{paramName}});{{/notFile}}
|
||||
{{#formParams}}{{#notFile}}formParams.put("{{baseName}}", ApiInvoker.parameterToString({{paramName}}));{{/notFile}}
|
||||
{{/formParams}}
|
||||
}
|
||||
|
||||
|
@ -19,16 +19,75 @@ import javax.ws.rs.core.MediaType;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.text.ParseException;
|
||||
|
||||
public class ApiInvoker {
|
||||
private static ApiInvoker INSTANCE = new ApiInvoker();
|
||||
private Map<String, Client> hostMap = new HashMap<String, Client>();
|
||||
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
|
||||
private boolean isDebug = false;
|
||||
|
||||
/**
|
||||
* ISO 8601 date time format.
|
||||
* @see https://en.wikipedia.org/wiki/ISO_8601
|
||||
*/
|
||||
public static final SimpleDateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
|
||||
|
||||
/**
|
||||
* ISO 8601 date format.
|
||||
* @see https://en.wikipedia.org/wiki/ISO_8601
|
||||
*/
|
||||
public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
|
||||
|
||||
static {
|
||||
// Use UTC as the default time zone.
|
||||
DATE_TIME_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
}
|
||||
|
||||
public static Date parseDateTime(String str) {
|
||||
try {
|
||||
return DATE_TIME_FORMAT.parse(str);
|
||||
} catch (java.text.ParseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Date parseDate(String str) {
|
||||
try {
|
||||
return DATE_FORMAT.parse(str);
|
||||
} catch (java.text.ParseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String formatDateTime(Date datetime) {
|
||||
return DATE_TIME_FORMAT.format(datetime);
|
||||
}
|
||||
|
||||
public static String formatDate(Date date) {
|
||||
return DATE_FORMAT.format(date);
|
||||
}
|
||||
|
||||
public static String parameterToString(Object param) {
|
||||
if (param == null) {
|
||||
return "";
|
||||
} else if (param instanceof Date) {
|
||||
return formatDateTime((Date) param);
|
||||
} else {
|
||||
return String.valueOf(param);
|
||||
}
|
||||
}
|
||||
|
||||
public void enableDebug() {
|
||||
isDebug = true;
|
||||
}
|
||||
|
@ -2,7 +2,8 @@ package {{package}};
|
||||
|
||||
import {{modelPackage}}.*;
|
||||
|
||||
import com.wordnik.swagger.annotations.*;
|
||||
import com.wordnik.swagger.annotations.ApiParam;
|
||||
|
||||
import com.sun.jersey.multipart.FormDataParam;
|
||||
|
||||
{{#imports}}import {{import}};
|
||||
@ -20,7 +21,7 @@ import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.*;
|
||||
|
||||
@Path("/{{baseName}}")
|
||||
@Api(value = "/{{baseName}}", description = "the {{baseName}} API")
|
||||
@com.wordnik.swagger.annotations.Api(value = "/{{baseName}}", description = "the {{baseName}} API")
|
||||
{{#operations}}
|
||||
public class {{classname}} {
|
||||
{{#operation}}
|
||||
@ -28,10 +29,9 @@ public class {{classname}} {
|
||||
{{#subresourceOperation}}@Path("{{path}}"){{/subresourceOperation}}
|
||||
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} }){{/hasConsumes}}
|
||||
{{#hasProduces}}@Produces({ {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }){{/hasProduces}}
|
||||
// {{returnType}}
|
||||
@ApiOperation(value = "{{{summary}}}", notes = "{{{notes}}}", response = {{{returnType}}}.class{{#returnContainer}}, responseContainer = "{{{returnContainer}}}"{{/returnContainer}})
|
||||
@ApiResponses(value = { {{#responses}}
|
||||
@ApiResponse(code = {{{code}}}, message = "{{{message}}}"){{#hasMore}},
|
||||
@com.wordnik.swagger.annotations.ApiOperation(value = "{{{summary}}}", notes = "{{{notes}}}", response = {{{returnType}}}.class{{#returnContainer}}, responseContainer = "{{{returnContainer}}}"{{/returnContainer}})
|
||||
@com.wordnik.swagger.annotations.ApiResponses(value = { {{#responses}}
|
||||
@com.wordnik.swagger.annotations.ApiResponse(code = {{{code}}}, message = "{{{message}}}"){{#hasMore}},
|
||||
{{/hasMore}}{{/responses}} })
|
||||
|
||||
public Response {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},
|
||||
|
@ -31,7 +31,7 @@
|
||||
<version>${jetty-version}</version>
|
||||
<configuration>
|
||||
<webAppConfig>
|
||||
<contextPath>{{^basePath}}/{{/basePath}}{{#basePath}}{{basePath}}{{/basePath}}</contextPath>
|
||||
<contextPath>{{^contextPath}}/{{/contextPath}}{{#contextPath}}{{contextPath}}{{/contextPath}}</contextPath>
|
||||
</webAppConfig>
|
||||
<webAppSourceDirectory>target/${project.artifactId}-${project.version}</webAppSourceDirectory>
|
||||
<webDefaultXml>${project.basedir}/conf/jetty/webdefault.xml</webDefaultXml>
|
||||
@ -123,8 +123,17 @@
|
||||
<version>${servlet-api-version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>sonatype-snapshots</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
<properties>
|
||||
<swagger-core-version>1.5.1-M1</swagger-core-version>
|
||||
<swagger-core-version>1.5.3-M1-SNAPSHOT</swagger-core-version>
|
||||
<jetty-version>8.1.11.v20130520</jetty-version>
|
||||
<jersey-version>1.13</jersey-version>
|
||||
<slf4j-version>1.6.3</slf4j-version>
|
||||
|
@ -9,6 +9,8 @@ com.wordnik.swagger.codegen.languages.ScalaClientCodegen
|
||||
com.wordnik.swagger.codegen.languages.StaticDocCodegen
|
||||
com.wordnik.swagger.codegen.languages.StaticHtmlGenerator
|
||||
com.wordnik.swagger.codegen.languages.SwaggerGenerator
|
||||
com.wordnik.swagger.codegen.languages.SwaggerYamlGenerator
|
||||
com.wordnik.swagger.codegen.languages.TizenClientCodegen
|
||||
com.wordnik.swagger.codegen.languages.PhpClientCodegen
|
||||
com.wordnik.swagger.codegen.languages.RubyClientCodegen
|
||||
com.wordnik.swagger.codegen.languages.PythonClientCodegen
|
||||
|
@ -0,0 +1,74 @@
|
||||
# Swagger Codegen for the {{name}} library
|
||||
|
||||
## Overview
|
||||
This is a boiler-plate project to generate your own client library with Swagger. It's goal is
|
||||
to get you started with the basic plumbing so you can put in your own logic. It won't work without
|
||||
your changes applied.
|
||||
|
||||
## What's Swagger?
|
||||
The goal of Swagger™ is to define a standard, language-agnostic interface to REST APIs which allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection. When properly defined via Swagger, a consumer can understand and interact with the remote service with a minimal amount of implementation logic. Similar to what interfaces have done for lower-level programming, Swagger removes the guesswork in calling the service.
|
||||
|
||||
|
||||
Check out [Swagger-Spec](https://github.com/swagger-api/swagger-spec) for additional information about the Swagger project, including additional libraries with support for other languages and more.
|
||||
|
||||
## How do I use this?
|
||||
At this point, you've likely generated a client setup. It will include something along these lines:
|
||||
|
||||
```
|
||||
.
|
||||
|- README.md // this file
|
||||
|- pom.xml // build script
|
||||
|-- src
|
||||
|--- main
|
||||
|---- java
|
||||
|----- {{generatorPackage}}.{{generatorClass}}.java // generator file
|
||||
|---- resources
|
||||
|----- {{name}} // template files
|
||||
|----- META-INF
|
||||
|------ services
|
||||
|------- com.wordnik.swagger.codegen.CodegenConfig
|
||||
```
|
||||
|
||||
You _will_ need to make changes in at least the following:
|
||||
|
||||
`{{generatorClass}}.java`
|
||||
|
||||
Templates in this folder:
|
||||
|
||||
`src/main/resources/{{name}}`
|
||||
|
||||
Once modified, you can run this:
|
||||
|
||||
```
|
||||
mvn package
|
||||
```
|
||||
|
||||
In your generator project. A single jar file will be produced in `target`. You can now use that with codegen:
|
||||
|
||||
```
|
||||
java -cp /path/to/swagger-codegen-distribution:/path/to/your/jar com.wordnik.swagger.codegen.Codegen -l {{name}} -o ./test
|
||||
```
|
||||
|
||||
Now your templates are available to the client generator and you can write output values
|
||||
|
||||
## But how do I modify this?
|
||||
The `{{generatorClass}}.java` has comments in it--lots of comments. There is no good substitute
|
||||
for reading the code more, though. See how the `{{generatorClass}}` implements `CodegenConfig`.
|
||||
That class has the signature of all values that can be overridden.
|
||||
|
||||
For the templates themselves, you have a number of values available to you for generation.
|
||||
You can execute the `java` command from above while passing different debug flags to show
|
||||
the object you have available during client generation:
|
||||
|
||||
```
|
||||
# The following additional debug options are available for all codegen targets:
|
||||
# -DdebugSwagger prints the swagger specification as interpreted by the codegen
|
||||
# -DdebugModels prints models passed to the template engine
|
||||
# -DdebugOperations prints operations passed to the template engine
|
||||
# -DdebugSupportingFiles prints additional data passed to the template engine
|
||||
|
||||
java -DdebugOperations -cp /path/to/swagger-codegen-distribution:/path/to/your/jar com.wordnik.swagger.codegen.Codegen -l {{name}} -o ./test
|
||||
```
|
||||
|
||||
Will, for example, output the debug info for operations. You can use this info
|
||||
in the `api.mustache` file.
|
@ -0,0 +1,28 @@
|
||||
|
||||
# This is a sample api mustache template. It is representing a ficticous
|
||||
# language and won't be usable or compile to anything without lots of changes.
|
||||
# Use it as an example. You can access the variables in the generator object
|
||||
# like such:
|
||||
|
||||
# use the package from the `apiPackage` variable
|
||||
package: {{package}}
|
||||
|
||||
# operations block
|
||||
{{#operations}}
|
||||
classname: {{classname}}
|
||||
|
||||
# loop over each operation in the API:
|
||||
{{#operation}}
|
||||
|
||||
# each operation has a `nickname`:
|
||||
nickname: {{nickname}}
|
||||
|
||||
# and parameters:
|
||||
{{#allParams}}
|
||||
{{paramName}}: {{dataType}}
|
||||
{{/allParams}}
|
||||
|
||||
{{/operation}}
|
||||
|
||||
# end of operations block
|
||||
{{/operations}}
|
@ -0,0 +1,191 @@
|
||||
package {{generatorPackage}};
|
||||
|
||||
import com.wordnik.swagger.codegen.*;
|
||||
import com.wordnik.swagger.models.properties.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
|
||||
public class {{generatorClass}} extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
// source folder where to write the files
|
||||
protected String sourceFolder = "src";
|
||||
protected String apiVersion = "1.0.0";
|
||||
|
||||
/**
|
||||
* Configures the type of generator.
|
||||
*
|
||||
* @return the CodegenType for this generator
|
||||
* @see com.wordnik.swagger.codegen.CodegenType
|
||||
*/
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.CLIENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a friendly name for the generator. This will be used by the generator
|
||||
* to select the library with the -l flag.
|
||||
*
|
||||
* @return the friendly name for the generator
|
||||
*/
|
||||
public String getName() {
|
||||
return "{{name}}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns human-friendly help for the generator. Provide the consumer with help
|
||||
* tips, parameters here
|
||||
*
|
||||
* @return A string value for the help message
|
||||
*/
|
||||
public String getHelp() {
|
||||
return "Generates a {{name}} client library.";
|
||||
}
|
||||
|
||||
public {{generatorClass}}() {
|
||||
super();
|
||||
|
||||
// set the output folder here
|
||||
outputFolder = "generated-code/{{name}}";
|
||||
|
||||
/**
|
||||
* Models. You can write model files using the modelTemplateFiles map.
|
||||
* if you want to create one template for file, you can do so here.
|
||||
* for multiple files for model, just put another entry in the `modelTemplateFiles` with
|
||||
* a different extension
|
||||
*/
|
||||
modelTemplateFiles.put(
|
||||
"model.mustache", // the template to use
|
||||
".sample"); // the extension for each file to write
|
||||
|
||||
/**
|
||||
* Api classes. You can write classes for each Api file with the apiTemplateFiles map.
|
||||
* as with models, add multiple entries with different extensions for multiple files per
|
||||
* class
|
||||
*/
|
||||
apiTemplateFiles.put(
|
||||
"api.mustache", // the template to use
|
||||
".sample"); // the extension for each file to write
|
||||
|
||||
/**
|
||||
* Template Location. This is the location which templates will be read from. The generator
|
||||
* will use the resource stream to attempt to read the templates.
|
||||
*/
|
||||
templateDir = "{{name}}";
|
||||
|
||||
/**
|
||||
* Api Package. Optional, if needed, this can be used in templates
|
||||
*/
|
||||
apiPackage = "io.swagger.client.api";
|
||||
|
||||
/**
|
||||
* Model Package. Optional, if needed, this can be used in templates
|
||||
*/
|
||||
modelPackage = "io.swagger.client.model";
|
||||
|
||||
/**
|
||||
* Reserved words. Override this with reserved words specific to your language
|
||||
*/
|
||||
reservedWords = new HashSet<String> (
|
||||
Arrays.asList(
|
||||
"sample1", // replace with static values
|
||||
"sample2")
|
||||
);
|
||||
|
||||
/**
|
||||
* Additional Properties. These values can be passed to the templates and
|
||||
* are available in models, apis, and supporting files
|
||||
*/
|
||||
additionalProperties.put("apiVersion", apiVersion);
|
||||
|
||||
/**
|
||||
* Supporting Files. You can write single files for the generator with the
|
||||
* entire object tree available. If the input file has a suffix of `.mustache
|
||||
* it will be processed by the template engine. Otherwise, it will be copied
|
||||
*/
|
||||
supportingFiles.add(new SupportingFile("myFile.mustache", // the input template or file
|
||||
"", // the destination folder, relative `outputFolder`
|
||||
"myFile.sample") // the output file
|
||||
);
|
||||
|
||||
/**
|
||||
* Language Specific Primitives. These types will not trigger imports by
|
||||
* the client generator
|
||||
*/
|
||||
languageSpecificPrimitives = new HashSet<String>(
|
||||
Arrays.asList(
|
||||
"Type1", // replace these with your types
|
||||
"Type2")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes a reserved word as defined in the `reservedWords` array. Handle escaping
|
||||
* those terms here. This logic is only called if a variable matches the reseved words
|
||||
*
|
||||
* @return the escaped term
|
||||
*/
|
||||
@Override
|
||||
public String escapeReservedWord(String name) {
|
||||
return "_" + name; // add an underscore to the name
|
||||
}
|
||||
|
||||
/**
|
||||
* Location to write model files. You can use the modelPackage() as defined when the class is
|
||||
* instantiated
|
||||
*/
|
||||
public String modelFileFolder() {
|
||||
return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Location to write api files. You can use the apiPackage() as defined when the class is
|
||||
* instantiated
|
||||
*/
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional - type declaration. This is a String which is used by the templates to instantiate your
|
||||
* types. There is typically special handling for different property types
|
||||
*
|
||||
* @return a string value used as the `dataType` field for model templates, `returnType` for api templates
|
||||
*/
|
||||
@Override
|
||||
public String getTypeDeclaration(Property p) {
|
||||
if(p instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) p;
|
||||
Property inner = ap.getItems();
|
||||
return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]";
|
||||
}
|
||||
else if (p instanceof MapProperty) {
|
||||
MapProperty mp = (MapProperty) p;
|
||||
Property inner = mp.getAdditionalProperties();
|
||||
return getSwaggerType(p) + "[String, " + getTypeDeclaration(inner) + "]";
|
||||
}
|
||||
return super.getTypeDeclaration(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional - swagger type conversion. This is used to map swagger types in a `Property` into
|
||||
* either language specific types via `typeMapping` or into complex models if there is not a mapping.
|
||||
*
|
||||
* @return a string value of the type or complex model for this property
|
||||
* @see com.wordnik.swagger.models.properties.Property
|
||||
*/
|
||||
@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 toModelName(type);
|
||||
}
|
||||
else
|
||||
type = swaggerType;
|
||||
return toModelName(type);
|
||||
}
|
||||
}
|
102
modules/swagger-codegen/src/main/resources/codegen/pom.mustache
Normal file
102
modules/swagger-codegen/src/main/resources/codegen/pom.mustache
Normal file
@ -0,0 +1,102 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>{{name}}-swagger-codegen</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>{{name}}-swagger-codegen</name>
|
||||
<version>1.0.0</version>
|
||||
<prerequisites>
|
||||
<maven>2.2.0</maven>
|
||||
</prerequisites>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.12</version>
|
||||
<configuration>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>loggerPath</name>
|
||||
<value>conf/log4j.properties</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
<argLine>-Xms512m -Xmx1500m</argLine>
|
||||
<parallel>methods</parallel>
|
||||
<forkMode>pertest</forkMode>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- attach test jar -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add_sources</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>src/main/java</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>add_test_sources</id>
|
||||
<phase>generate-test-sources</phase>
|
||||
<goals>
|
||||
<goal>add-test-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>src/test/java</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.3.2</version>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.wordnik</groupId>
|
||||
<artifactId>swagger-codegen</artifactId>
|
||||
<version>${swagger-codegen-version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<swagger-codegen-version>2.1.2-M1</swagger-codegen-version>
|
||||
<maven-plugin-version>1.0.0</maven-plugin-version>
|
||||
<junit-version>4.8.1</junit-version>
|
||||
</properties>
|
||||
</project>
|
@ -0,0 +1 @@
|
||||
{{fullyQualifiedGeneratorClass}}
|
@ -9,6 +9,7 @@
|
||||
<div class="app-desc">{{{appDescription}}} for {{partner}}</div>
|
||||
{{#infoUrl}}<div class="app-desc">More information: <a href="{{{infoUrl}}}">{{{infoUrl}}}</a></div>{{/infoUrl}}
|
||||
{{#infoEmail}}<div class="app-desc">Contact Info: <a href="{{{infoEmail}}}">{{{infoEmail}}}</a></div>{{/infoEmail}}
|
||||
{{#version}}<div class="app-desc">Version: {{{version}}}</div>{{/version}}
|
||||
<div class="license-info">{{{licenseInfo}}}</div>
|
||||
<div class="license-url">{{{licenseUrl}}}</div>
|
||||
<h2>Access</h2>
|
||||
|
@ -6,3 +6,19 @@ This server was generated by the [swagger-codegen](https://github.com/swagger-ap
|
||||
This example uses the [expressjs](http://expressjs.com/) framework. To see how to make this your own, look here:
|
||||
|
||||
[README](https://github.com/wordnik/swagger-codegen/README.md)
|
||||
|
||||
### Running the server
|
||||
To run the server, follow these simple steps:
|
||||
|
||||
```
|
||||
npm install
|
||||
node .
|
||||
```
|
||||
|
||||
To view the Swagger UI interface:
|
||||
|
||||
```
|
||||
open http://localhost:8080/docs
|
||||
```
|
||||
|
||||
This project leverages the mega-awesome [swagger-tools](https://github.com/apigee-127/swagger-tools) middleware which does most all the work.
|
@ -1,62 +0,0 @@
|
||||
var swagger = require("swagger-node-express");
|
||||
var url = require("url");
|
||||
var errors = swagger.errors;
|
||||
var params = swagger.params;
|
||||
|
||||
/* add model includes */
|
||||
|
||||
function writeResponse (response, data) {
|
||||
response.header('Access-Control-Allow-Origin', "*");
|
||||
response.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
|
||||
response.header("Access-Control-Allow-Headers", "Content-Type");
|
||||
response.header("Content-Type", "application/json; charset=utf-8");
|
||||
response.send(JSON.stringify(data));
|
||||
}
|
||||
|
||||
exports.models = models = require("../models.js");
|
||||
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
exports.{{nickname}} = {
|
||||
'spec': {
|
||||
"description" : "Operations about pets",
|
||||
"path" : "{{path}}",
|
||||
"notes" : "{{{notes}}}",
|
||||
"summary" : "{{{summary}}}",
|
||||
"method": "{{httpMethod}}",
|
||||
"params" : [{{#queryParams}}
|
||||
params.query("{{paramName}}", "{{description}}", "{{swaggerDataType}}", {{#required}}true{{/required}}{{^required}}false{{/required}}, {{#allowMultiple}}true{{/allowMultiple}}{{^allowMultiple}}false{{/allowMultiple}}, "{{{allowableValues}}}"{{#defaultValue}}, {{{defaultValue}}}{{/defaultValue}}){{#hasMore}},{{/hasMore}}
|
||||
{{/queryParams}}].concat([{{#pathParams}}
|
||||
params.path("{{paramName}}", "{{description}}"){{#hasMore}},{{/hasMore}}
|
||||
{{/pathParams}}]).concat([{{#headerParams}}
|
||||
params.header("{{paramName}}", "{{description}}"){{#hasMore}},{{/hasMore}}
|
||||
{{/headerParams}}]).concat([{{#bodyParams}}
|
||||
params.body("body", "{{swaggerDataType}}", "{{description}}", {{#required}}{{required}}{{/required}}{{^required}}false{{/required}})
|
||||
{{/bodyParams}}]),
|
||||
{{#returnContainer}}
|
||||
"type": "{{returnType}}",
|
||||
"items": {
|
||||
{{#returnTypeIsPrimitive}}"type": "{{returnContainer}}"{{/returnTypeIsPrimitive}}
|
||||
{{^returnTypeIsPrimitive}}"$ref": "{{returnContainer}}"{{/returnTypeIsPrimitive}}
|
||||
},
|
||||
// container
|
||||
{{/returnContainer}}
|
||||
{{^returnContainer}}
|
||||
"type" : "{{returnType}}",
|
||||
{{/returnContainer}}
|
||||
"responseMessages" : [errors.invalid('id'), errors.notFound('{{returnType}}')],
|
||||
"nickname" : "{{nickname}}"
|
||||
},
|
||||
'action': function (req,res) {
|
||||
{{#requiredParamCount}}
|
||||
{{#requiredParams}}
|
||||
if (!req.params.{{baseName}}) {
|
||||
throw errors.invalid('{{baseName}}');
|
||||
}
|
||||
{{/requiredParams}}
|
||||
{{/requiredParamCount}}
|
||||
writeResponse(res, {message: "how about implementing {{nickname}} as a {{httpMethod}} method?"});
|
||||
}
|
||||
};
|
||||
{{/operation}}
|
||||
{{/operations}}
|
@ -0,0 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
var url = require('url');
|
||||
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
|
||||
module.exports.{{nickname}} = function {{nickname}} (req, res, next) {
|
||||
{{#allParams}}var {{paramName}} = req.swagger.params['{{baseName}}'].value;
|
||||
{{/allParams}}
|
||||
|
||||
console.log('do some magic!');
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end();
|
||||
};
|
||||
{{/operation}}
|
||||
{{/operations}}
|
@ -0,0 +1,38 @@
|
||||
'use strict';
|
||||
|
||||
var app = require('connect')();
|
||||
var http = require('http');
|
||||
var swaggerTools = require('swagger-tools');
|
||||
|
||||
var serverPort = {{serverPort}};
|
||||
|
||||
// swaggerRouter configuration
|
||||
var options = {
|
||||
swaggerUi: '/swagger.json',
|
||||
controllers: './controllers',
|
||||
useStubs: process.env.NODE_ENV === 'development' ? true : false // Conditionally turn on stubs (mock mode)
|
||||
};
|
||||
|
||||
// The Swagger document (require it, build it programmatically, fetch it from a URL, ...)
|
||||
var swaggerDoc = require('./api/swagger.json');
|
||||
|
||||
// Initialize the Swagger middleware
|
||||
swaggerTools.initializeMiddleware(swaggerDoc, function (middleware) {
|
||||
// Interpret Swagger resources and attach metadata to request - must be first in swagger-tools middleware chain
|
||||
app.use(middleware.swaggerMetadata());
|
||||
|
||||
// Validate Swagger requests
|
||||
app.use(middleware.swaggerValidator());
|
||||
|
||||
// Route validated requests to appropriate controller
|
||||
app.use(middleware.swaggerRouter(options));
|
||||
|
||||
// Serve the Swagger documents and Swagger UI
|
||||
app.use(middleware.swaggerUi());
|
||||
|
||||
// Start the server
|
||||
http.createServer(app).listen({{serverPort}}, function () {
|
||||
console.log('Your server is listening on port %d (http://localhost:%d)', {{serverPort}}, {{serverPort}});
|
||||
console.log('Swagger-ui is available on http://localhost:%d/docs', {{serverPort}});
|
||||
});
|
||||
});
|
@ -1,53 +0,0 @@
|
||||
var express = require("express")
|
||||
, url = require("url")
|
||||
, cors = require("cors")
|
||||
, app = express()
|
||||
, swagger = require("swagger-node-express")
|
||||
, db = false
|
||||
|
||||
|
||||
var corsOptions = {
|
||||
credentials: true,
|
||||
origin: function(origin,callback) {
|
||||
if(origin===undefined) {
|
||||
callback(null,false);
|
||||
} else {
|
||||
callback(null,true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded());
|
||||
app.use(cors(corsOptions));
|
||||
|
||||
{{#basePath}}
|
||||
var subpath = express();
|
||||
|
||||
app.use("{{{basePath}}}", subpath);
|
||||
|
||||
swagger.setAppHandler(subpath);
|
||||
{{/basePath}}
|
||||
{{^basePath}}
|
||||
swagger.setAppHandler(app);
|
||||
{{/basePath}}
|
||||
|
||||
swagger.configureSwaggerPaths("", "api-docs", "")
|
||||
|
||||
var models = require("./app/models.js");
|
||||
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
var {{classname}} = require("./{{apiFolder}}/{{classname}}.js");
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
|
||||
swagger.addModels(models)
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}.add{{httpMethod}}({{classname}}.{{nickname}})
|
||||
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}};
|
||||
|
||||
// configures the app
|
||||
swagger.configure("http://localhost:8002{{basePath}}", "0.1");
|
||||
|
||||
// start the server
|
||||
app.listen(8002);
|
@ -1,3 +0,0 @@
|
||||
exports.models = {
|
||||
{{#models}}{{#model}}"{{classVarName}}": {{{modelJson}}}{{#hasMoreModels}},{{/hasMoreModels}}{{/model}}{{/models}}
|
||||
}
|
23
modules/swagger-codegen/src/main/resources/nodejs/package.mustache
Executable file → Normal file
23
modules/swagger-codegen/src/main/resources/nodejs/package.mustache
Executable file → Normal file
@ -1,16 +1,15 @@
|
||||
{
|
||||
"name": "{{{artifactId}}}",
|
||||
"description": "Wordnik node.js server generator",
|
||||
"version": "{{{artifactVersion}}}",
|
||||
"homepage": "{{{homepage}}}",
|
||||
"main": "./main.js",
|
||||
"engines": {
|
||||
"node": ">= 0.8.x"
|
||||
},
|
||||
"name": "{{projectName}}",
|
||||
"version": "{{appVersion}}",
|
||||
"description": "{{appDescription}}",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"swagger"
|
||||
],
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"swagger-node-express": ">= 2.0.x",
|
||||
"connect": ">= 1.8.x",
|
||||
"cors": "2.1.1",
|
||||
"express": "3.x"
|
||||
"connect": "^3.2.0",
|
||||
"swagger-tools": "0.8.*"
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"title": "{{appName}}",
|
||||
"description": "{{appDescription}}",
|
||||
"version": "{{apiVersion}}"
|
||||
},
|
||||
{{#apiInfo}}
|
||||
"produces": ["application/json"],
|
||||
"host": "{{host}}",
|
||||
"basePath": "{{contextPath}}",
|
||||
"paths": {
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
"{{{path}}}": {
|
||||
"{{httpMethod}}": {
|
||||
"x-swagger-router-controller": "{{classname}}",
|
||||
"tags": ["{{baseName}}"],
|
||||
"operationId": "{{operationId}}",{{#hasParams}}
|
||||
"parameters": [
|
||||
{{#allParams}}
|
||||
{{{jsonSchema}}}{{#hasMore}},{{/hasMore}}
|
||||
{{/allParams}}
|
||||
],{{/hasParams}}
|
||||
"responses": {
|
||||
{{#responses}}
|
||||
"{{code}}": {{{jsonSchema}}}
|
||||
{{#hasMore}},{{/hasMore}}
|
||||
{{/responses}}
|
||||
}
|
||||
}
|
||||
} {{#hasMore}},{{/hasMore}}
|
||||
{{/operation}}
|
||||
{{#hasMore}},{{/hasMore}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
}, "definitions": {
|
||||
{{#models}}{{#model}}"{{classVarName}}": {{{modelJson}}}{{#hasMoreModels}},{{/hasMoreModels}}{{/model}}{{/models}}
|
||||
}
|
||||
}
|
@ -48,6 +48,18 @@ class APIClient {
|
||||
$this->headerValue = $headerValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user agent of the API client
|
||||
*
|
||||
* @param string $user_agent The user agent of the API client
|
||||
*/
|
||||
public function setUserAgent($user_agent) {
|
||||
if (!is_string($user_agent)) {
|
||||
throw new Exception('User-agent must be a string.');
|
||||
}
|
||||
$this->user_agent= $user_agent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $seconds Number of seconds before timing out [set to 0 for no timeout]
|
||||
*/
|
||||
@ -58,7 +70,6 @@ class APIClient {
|
||||
$this->curl_timout = $seconds;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $resourcePath path to method endpoint
|
||||
* @param string $method method to call
|
||||
@ -107,6 +118,9 @@ class APIClient {
|
||||
if ($method == self::$POST) {
|
||||
curl_setopt($curl, CURLOPT_POST, true);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
|
||||
} else if ($method == self::$PATCH) {
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PATCH");
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
|
||||
} else if ($method == self::$PUT) {
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
|
||||
@ -118,25 +132,35 @@ class APIClient {
|
||||
}
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
|
||||
// Set user agent
|
||||
if ($this->user_agent) {
|
||||
curl_setopt($curl, CURLOPT_USERAGENT, $this->user_agent);
|
||||
} else { // use PHP-Swagger as the default user agent
|
||||
curl_setopt($curl, CURLOPT_USERAGENT, 'PHP-Swagger');
|
||||
}
|
||||
|
||||
// Make the request
|
||||
$response = curl_exec($curl);
|
||||
$response_info = curl_getinfo($curl);
|
||||
|
||||
// Handle the response
|
||||
if ($response_info['http_code'] == 0) {
|
||||
throw new Exception("TIMEOUT: api call to " . $url .
|
||||
" took more than 5s to return" );
|
||||
} else if ($response_info['http_code'] == 200) {
|
||||
throw new APIClientException("TIMEOUT: api call to " . $url .
|
||||
" took more than 5s to return", 0, $response_info, $response);
|
||||
} else if ($response_info['http_code'] >= 200 && $response_info['http_code'] <= 299 ) {
|
||||
$data = json_decode($response);
|
||||
if (json_last_error() > 0) { // if response is a string
|
||||
$data = $response;
|
||||
}
|
||||
} else if ($response_info['http_code'] == 401) {
|
||||
throw new Exception("Unauthorized API request to " . $url .
|
||||
": ".json_decode($response)->message );
|
||||
throw new APIClientException("Unauthorized API request to " . $url .
|
||||
": " . serialize($response), 0, $response_info, $response);
|
||||
} else if ($response_info['http_code'] == 404) {
|
||||
$data = null;
|
||||
} else {
|
||||
throw new Exception("Can't connect to the api: " . $url .
|
||||
throw new APIClientException("Can't connect to the api: " . $url .
|
||||
" response code: " .
|
||||
$response_info['http_code']);
|
||||
$response_info['http_code'], 0, $response_info, $response);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
@ -175,7 +199,7 @@ class APIClient {
|
||||
* @return string the serialized object
|
||||
*/
|
||||
public static function toPathValue($value) {
|
||||
return rawurlencode($value);
|
||||
return rawurlencode(toString($value));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,19 +214,47 @@ class APIClient {
|
||||
if (is_array($object)) {
|
||||
return implode(',', $object);
|
||||
} else {
|
||||
return $object;
|
||||
return toString($object);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Just pass through the header value for now. Placeholder in case we
|
||||
* find out we need to do something with header values.
|
||||
* Take value and turn it into a string suitable for inclusion in
|
||||
* the header. If it's a string, pass through unchanged
|
||||
* If it's a datetime object, format it in ISO8601
|
||||
* @param string $value a string which will be part of the header
|
||||
* @return string the header string
|
||||
*/
|
||||
public static function toHeaderValue($value) {
|
||||
return toString($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Take value and turn it into a string suitable for inclusion in
|
||||
* the http body (form parameter). If it's a string, pass through unchanged
|
||||
* If it's a datetime object, format it in ISO8601
|
||||
* @param string $value the value of the form parameter
|
||||
* @return string the form string
|
||||
*/
|
||||
public static function toFormValue($value) {
|
||||
return toString($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Take value and turn it into a string suitable for inclusion in
|
||||
* the parameter. If it's a string, pass through unchanged
|
||||
* If it's a datetime object, format it in ISO8601
|
||||
* @param string $value the value of the parameter
|
||||
* @return string the header string
|
||||
*/
|
||||
public static function toString($value) {
|
||||
if ($value instanceof \DateTime) { // datetime in ISO8601 format
|
||||
return $value->format(\DateTime::ISO8601);
|
||||
}
|
||||
else {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize a JSON string into an object
|
||||
@ -220,13 +272,14 @@ class APIClient {
|
||||
$inner = substr($class, 4, -1);
|
||||
$values = array();
|
||||
if(strrpos($inner, ",") !== false) {
|
||||
$subClass = explode(',', $inner, 2)[1];
|
||||
$subClass_array = explode(',', $inner, 2);
|
||||
$subClass = $subClass_array[1];
|
||||
foreach ($data as $key => $value) {
|
||||
$values[] = array($key => self::deserialize($value, $subClass));
|
||||
}
|
||||
}
|
||||
$deserialized = $values;
|
||||
} elseif (substr($class, 0, 6) == 'array[') {
|
||||
} elseif (strcasecmp(substr($class, 0, 6),'array[') == 0) {
|
||||
$subClass = substr($class, 6, -1);
|
||||
$values = array();
|
||||
foreach ($data as $key => $value) {
|
||||
@ -253,3 +306,20 @@ class APIClient {
|
||||
|
||||
}
|
||||
|
||||
class APIClientException extends Exception {
|
||||
protected $response, $response_info;
|
||||
|
||||
public function __construct($message="", $code=0, $response_info=null, $response=null) {
|
||||
parent::__construct($message, $code);
|
||||
$this->response_info = $response_info;
|
||||
$this->response = $response;
|
||||
}
|
||||
|
||||
public function getResponse() {
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
public function getResponseInfo() {
|
||||
return $this->response_info;
|
||||
}
|
||||
}
|
||||
|
@ -50,20 +50,20 @@ class {{classname}} {
|
||||
|
||||
{{#queryParams}}// query params
|
||||
if(${{paramName}} !== null) {
|
||||
$queryParams['{{paramName}}'] = $this->apiClient->toQueryValue(${{paramName}});
|
||||
$queryParams['{{baseName}}'] = $this->apiClient->toQueryValue(${{paramName}});
|
||||
}{{/queryParams}}
|
||||
{{#headerParams}}// header params
|
||||
if(${{paramName}} !== null) {
|
||||
$headerParams['{{paramName}}'] = $this->apiClient->toHeaderValue(${{paramName}});
|
||||
$headerParams['{{baseName}}'] = $this->apiClient->toHeaderValue(${{paramName}});
|
||||
}{{/headerParams}}
|
||||
{{#pathParams}}// path params
|
||||
if(${{paramName}} !== null) {
|
||||
$resourcePath = str_replace("{" . "{{paramName}}" . "}",
|
||||
$resourcePath = str_replace("{" . "{{baseName}}" . "}",
|
||||
$this->apiClient->toPathValue(${{paramName}}), $resourcePath);
|
||||
}{{/pathParams}}
|
||||
{{#formParams}}
|
||||
{{#formParams}}// form params
|
||||
if (${{paramName}} !== null) {
|
||||
$formParams[{{paramName}}] = {{#isFile}}'@' . {{/isFile}}${{paramName}};
|
||||
$formParams['{{baseName}}'] = {{#isFile}}'@' . {{/isFile}}$this->apiClient->toFormValue(${{paramName}});
|
||||
}{{/formParams}}
|
||||
{{#bodyParams}}// body params
|
||||
$body = null;
|
||||
@ -71,6 +71,7 @@ class {{classname}} {
|
||||
$body = ${{paramName}};
|
||||
}{{/bodyParams}}
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
|
@ -24,7 +24,7 @@
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
|
||||
class {{classname}} {
|
||||
class {{classname}} implements ArrayAccess {
|
||||
static $swaggerTypes = array(
|
||||
{{#vars}}'{{name}}' => '{{{datatype}}}'{{#hasMore}},
|
||||
{{/hasMore}}{{/vars}}
|
||||
@ -35,6 +35,27 @@ class {{classname}} {
|
||||
* {{{description}}}
|
||||
*/{{/description}}
|
||||
public ${{name}}; /* {{{datatype}}} */{{/vars}}
|
||||
|
||||
public function __construct(array $data) {
|
||||
{{#vars}}$this->{{name}} = $data["{{name}}"];{{#hasMore}}
|
||||
{{/hasMore}}{{/vars}}
|
||||
}
|
||||
|
||||
public function offsetExists($offset) {
|
||||
return isset($this->$offset);
|
||||
}
|
||||
|
||||
public function offsetGet($offset) {
|
||||
return $this->$offset;
|
||||
}
|
||||
|
||||
public function offsetSet($offset, $value) {
|
||||
$this->$offset = $value;
|
||||
}
|
||||
|
||||
public function offsetUnset($offset) {
|
||||
unset($this->$offset);
|
||||
}
|
||||
}
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
|
@ -43,7 +43,6 @@ class ApiClient:
|
||||
|
||||
data = None
|
||||
|
||||
|
||||
if queryParams:
|
||||
# Need to remove None values, these should not be sent
|
||||
sentQueryParams = {}
|
||||
@ -57,7 +56,7 @@ class ApiClient:
|
||||
#Options to add statements later on and for compatibility
|
||||
pass
|
||||
|
||||
elif method in ['POST', 'PUT', 'DELETE']:
|
||||
elif method in ['PATCH', 'POST', 'PUT', 'DELETE']:
|
||||
|
||||
if postData:
|
||||
headers['Content-type'] = 'application/json'
|
||||
@ -119,6 +118,39 @@ class ApiClient:
|
||||
for (key, val) in objDict.items()
|
||||
if key != 'swaggerTypes'}
|
||||
|
||||
def _iso8601Format(self, timesep, microsecond, offset, zulu):
|
||||
"""Format for parsing a datetime string with given properties.
|
||||
|
||||
Args:
|
||||
timesep -- string separating time from date ('T' or 't')
|
||||
microsecond -- microsecond portion of time ('.XXX')
|
||||
offset -- time offset (+/-XX:XX) or None
|
||||
zulu -- 'Z' or 'z' for UTC, or None for time offset (+/-XX:XX)
|
||||
|
||||
Returns:
|
||||
str - format string for datetime.strptime"""
|
||||
|
||||
return '%Y-%m-%d{}%H:%M:%S{}{}'.format(
|
||||
timesep,
|
||||
'.%f' if microsecond else '',
|
||||
zulu or ('%z' if offset else ''))
|
||||
|
||||
# http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14
|
||||
_iso8601Regex = re.compile(
|
||||
r'^\d\d\d\d-\d\d-\d\d([Tt])\d\d:\d\d:\d\d(\.\d+)?(([Zz])|(\+|-)\d\d:?\d\d)?$')
|
||||
|
||||
def _parseDatetime(self, d):
|
||||
if d is None:
|
||||
return None
|
||||
m = ApiClient._iso8601Regex.match(d)
|
||||
if not m:
|
||||
raise Exception('datetime regex match failed "%s"' % d)
|
||||
timesep, microsecond, offset, zulu, plusminus = m.groups()
|
||||
format = self._iso8601Format(timesep, microsecond, offset, zulu)
|
||||
if offset and not zulu:
|
||||
d = d.rsplit(sep=plusminus, maxsplit=1)[0] + offset.replace(':', '')
|
||||
return datetime.datetime.strptime(d, format)
|
||||
|
||||
def deserialize(self, obj, objClass):
|
||||
"""Derialize a JSON string into an object.
|
||||
|
||||
@ -145,11 +177,7 @@ class ApiClient:
|
||||
if objClass in [int, float, dict, list, str, bool]:
|
||||
return objClass(obj)
|
||||
elif objClass == datetime:
|
||||
# Server will always return a time stamp in UTC, but with
|
||||
# trailing +0000 indicating no offset from UTC. So don't process
|
||||
# last 5 characters.
|
||||
return datetime.datetime.strptime(obj[:-5],
|
||||
"%Y-%m-%dT%H:%M:%S.%f")
|
||||
return self._parseDatetime(obj)
|
||||
|
||||
instance = objClass()
|
||||
|
||||
@ -167,8 +195,7 @@ class ApiClient:
|
||||
value = value
|
||||
setattr(instance, attr, value)
|
||||
elif (attrType == 'datetime'):
|
||||
setattr(instance, attr, datetime.datetime.strptime(value[:-5],
|
||||
"%Y-%m-%dT%H:%M:%S.%f"))
|
||||
setattr(instance, attr, self._parseDatetime(value))
|
||||
elif 'list[' in attrType:
|
||||
match = re.match('list\[(.*)\]', attrType)
|
||||
subClass = match.group(1)
|
||||
@ -182,7 +209,7 @@ class ApiClient:
|
||||
setattr(instance, attr, subValues)
|
||||
else:
|
||||
setattr(instance, attr, self.deserialize(value,
|
||||
objClass))
|
||||
attrType))
|
||||
|
||||
return instance
|
||||
|
||||
|
@ -23,9 +23,7 @@ class {{classname}}
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
{{#allParams}}
|
||||
:{{paramName}} => {{paramName}}{{#hasMore}},
|
||||
{{/hasMore}}
|
||||
{{#allParams}}:'{{paramName}}' => {{paramName}}{{#hasMore}},{{/hasMore}}
|
||||
{{/allParams}}
|
||||
}.merge(opts)
|
||||
|
||||
@ -38,13 +36,12 @@ class {{classname}}
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
{{#headerParams}}headers = {
|
||||
{{{paramName}}}: {{{paramName}}},
|
||||
}
|
||||
{{/headerParams}}
|
||||
{{^headerParams}}headers = nil
|
||||
{{/headerParams}}
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
{{#headerParams}}{{#optional}}headers[:'{{{baseName}}}'] = options[:'{{{paramName}}}'] if options[:'{{{paramName}}}']{{/optional}}{{/headerParams}}
|
||||
{{#headerParams}}{{^optional}}headers[:'{{{baseName}}}'] = {{{paramName}}}{{/optional}}{{/headerParams}}
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
{{#bodyParam}}
|
||||
if body != nil
|
||||
@ -69,13 +66,18 @@ class {{classname}}
|
||||
end
|
||||
{{/bodyParam}}
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
{{#formParams}}{{#optional}}form_parameter_hash["{{baseName}}"] = options[:'{{paramName}}'] if options[:'{{paramName}}']{{/optional}}
|
||||
{{^optional}}form_parameter_hash["{{baseName}}"] = {{paramName}}{{/optional}}{{/formParams}}
|
||||
|
||||
{{#returnType}}
|
||||
response = Swagger::Request.new(:{{httpMethod}}, path, {:params=>queryopts,:headers=>headers, :body=>post_body }).make.body
|
||||
response = Swagger::Request.new(:{{httpMethod}}, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make.body
|
||||
{{#returnContainer}}
|
||||
response.map {|response|{{/returnContainer}} {{returnBaseType}}.new(response){{#returnContainer}} }{{/returnContainer}}
|
||||
{{/returnType}}
|
||||
{{^returnType}}
|
||||
Swagger::Request.new(:{{httpMethod}}, path, {:params=>queryopts,:headers=>headers, :body=>post_body}).make
|
||||
Swagger::Request.new(:{{httpMethod}}, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make
|
||||
{{/returnType}}
|
||||
{{newline}}
|
||||
end
|
||||
|
@ -6,10 +6,8 @@ class {{classname}}
|
||||
# :internal => :external
|
||||
def self.attribute_map
|
||||
{
|
||||
{{#vars}}
|
||||
:{{{name}}} => :{{{baseName}}}{{#hasMore}},
|
||||
{{/hasMore}}
|
||||
{{/vars}}{{newline}}
|
||||
{{#vars}}:{{{name}}} => :'{{{baseName}}}'{{#hasMore}},{{/hasMore}}
|
||||
{{/vars}}
|
||||
}
|
||||
end
|
||||
|
||||
@ -18,15 +16,11 @@ class {{classname}}
|
||||
# Morph attribute keys into undescored rubyish style
|
||||
{{#vars}}
|
||||
if self.class.attribute_map[:"{{{name}}}"]
|
||||
{{#isContainer}}
|
||||
if (value = attributes["{{{baseName}}}"]).is_a?(Array)
|
||||
@{{{name}}} = value{{#complexType}}.map{ |v| {{complexType}}.new(v) }{{/complexType}}{{newline}}
|
||||
{{#isContainer}}if (value = attributes["{{{baseName}}}"]).is_a?(Array)
|
||||
@{{{name}}} = value{{#complexType}}.map{ |v| {{complexType}}.new(v) }{{/complexType}}
|
||||
end{{/isContainer}}{{^isContainer}}@{{{name}}} = attributes["{{{baseName}}}"]{{/isContainer}}
|
||||
end
|
||||
{{/isContainer}}{{^isContainer}}
|
||||
@{{{name}}} = attributes["{{{baseName}}}"]
|
||||
{{/isContainer}}
|
||||
end
|
||||
{{/vars}}{{newline}}
|
||||
{{/vars}}
|
||||
end
|
||||
|
||||
def to_body
|
||||
|
@ -6,7 +6,7 @@ module Swagger
|
||||
require 'typhoeus'
|
||||
require "swagger/version"
|
||||
|
||||
attr_accessor :host, :path, :format, :params, :body, :http_method, :headers
|
||||
attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params
|
||||
|
||||
|
||||
# All requests must have an HTTP method and a path
|
||||
@ -115,9 +115,18 @@ module Swagger
|
||||
end
|
||||
|
||||
# If body is an object, JSONify it before making the actual request.
|
||||
#
|
||||
# For form parameters, remove empty value
|
||||
def outgoing_body
|
||||
body.is_a?(String) ? body : body.to_json
|
||||
# http form
|
||||
if @body.nil? && @form_params && !@form_params.empty?
|
||||
data = form_params.dup
|
||||
data.each do |key, value|
|
||||
data[key] = value.to_s if value && !value.is_a?(File) # remove emtpy form parameter
|
||||
end
|
||||
data
|
||||
else # http body is JSON
|
||||
@body.is_a?(String) ? @body : @body.to_json
|
||||
end
|
||||
end
|
||||
|
||||
# Construct a query string from the query-string-type params
|
||||
@ -163,6 +172,13 @@ module Swagger
|
||||
:headers => self.headers.stringify_keys,
|
||||
)
|
||||
|
||||
when :patch,:PATCH
|
||||
Typhoeus::Request.patch(
|
||||
self.url,
|
||||
:body => self.outgoing_body,
|
||||
:headers => self.headers.stringify_keys,
|
||||
)
|
||||
|
||||
when :put,:PUT
|
||||
Typhoeus::Request.put(
|
||||
self.url,
|
||||
|
@ -17,6 +17,7 @@ import scala.collection.JavaConverters._
|
||||
import scala.collection.mutable.HashMap
|
||||
|
||||
import com.fasterxml.jackson.module.scala.DefaultScalaModule
|
||||
import com.fasterxml.jackson.datatype.joda.JodaModule
|
||||
import com.fasterxml.jackson.core.JsonGenerator.Feature
|
||||
import com.fasterxml.jackson.databind._
|
||||
import com.fasterxml.jackson.annotation._
|
||||
@ -26,6 +27,7 @@ object ScalaJsonUtil {
|
||||
def getJsonMapper = {
|
||||
val mapper = new ObjectMapper()
|
||||
mapper.registerModule(new DefaultScalaModule())
|
||||
mapper.registerModule(new JodaModule());
|
||||
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
mapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT)
|
||||
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
|
||||
|
@ -0,0 +1,2 @@
|
||||
# Swagger JSON
|
||||
This is a swagger JSON built by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project.
|
@ -0,0 +1,139 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"description": "This is a sample server Petstore server. You can find out more about Swagger at <a href=\"http://swagger.io\">http://swagger.io</a> or on irc.freenode.net, #swagger. For this sample, you can use the api key \"special-key\" to test the authorization filters",
|
||||
"version": "1.0.0",
|
||||
"title": "Swagger Petstore",
|
||||
"termsOfService": "http://helloreverb.com/terms/",
|
||||
"contact": {
|
||||
"email": "apiteam@wordnik.com"
|
||||
},
|
||||
"license": {
|
||||
"name": "Apache 2.0",
|
||||
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
|
||||
}
|
||||
},
|
||||
"host": "petstore.swagger.io",
|
||||
"basePath": "/v2",
|
||||
"schemes": [
|
||||
"http"
|
||||
],
|
||||
"paths": {
|
||||
"/tests/withTwoHundredAndDefault": {
|
||||
"get": {
|
||||
"summary": "Operation with several unordered 2XX results and one default",
|
||||
"description": "",
|
||||
"operationId": "withTwoHundredAndDefault",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": "default response",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
},
|
||||
"100": {
|
||||
"description": "100 response",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
},
|
||||
"202": {
|
||||
"description": "201 response",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
},
|
||||
"203": {
|
||||
"description": "202 response",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "400 response",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
},
|
||||
"201": {
|
||||
"description": "200 response",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/tests/withoutTwoHundredButDefault": {
|
||||
"get": {
|
||||
"summary": "Operation with several unordered 2XX results and one default",
|
||||
"description": "",
|
||||
"operationId": "withoutTwoHundredButDefault",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": "default response",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"100": {
|
||||
"description": "100 response",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
},
|
||||
"301": {
|
||||
"description": "301 response",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"securityDefinitions": {
|
||||
"api_key": {
|
||||
"type": "apiKey",
|
||||
"name": "api_key",
|
||||
"in": "header"
|
||||
},
|
||||
"petstore_auth": {
|
||||
"type": "oauth2",
|
||||
"authorizationUrl": "http://petstore.swagger.io/api/oauth/dialog",
|
||||
"flow": "implicit",
|
||||
"scopes": {
|
||||
"write:pets": "modify pets in your account",
|
||||
"read:pets": "read your pets"
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"CustomModel": {
|
||||
"required": ["id"],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"example": "doggie"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -94,4 +94,31 @@ class CodegenTest extends FlatSpec with Matchers {
|
||||
statusParam.required should equal (false)
|
||||
statusParam.hasMore should be (null)
|
||||
}
|
||||
|
||||
it should "select main response from a 2.0 spec using the lowest 2XX code" in {
|
||||
val model = new SwaggerParser()
|
||||
.read("src/test/resources/2_0/responseSelectionTest.json")
|
||||
|
||||
val codegen = new DefaultCodegen()
|
||||
|
||||
val path = "/tests/withTwoHundredAndDefault"
|
||||
val p = model.getPaths().get(path).getGet()
|
||||
val op = codegen.fromOperation(path, "get", p)
|
||||
op.returnType should be("String")
|
||||
|
||||
}
|
||||
|
||||
it should "select main response from a 2.0 spec using the default keyword when no 2XX code" in {
|
||||
val model = new SwaggerParser()
|
||||
.read("src/test/resources/2_0/responseSelectionTest.json")
|
||||
|
||||
val codegen = new DefaultCodegen()
|
||||
|
||||
val path = "/tests/withoutTwoHundredButDefault"
|
||||
val p = model.getPaths().get(path).getGet()
|
||||
val op = codegen.fromOperation(path, "get", p)
|
||||
op.returnType should be("String")
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -14,7 +14,6 @@ import scala.collection.JavaConverters._
|
||||
|
||||
@RunWith(classOf[JUnitRunner])
|
||||
class JavaModelTest extends FlatSpec with Matchers {
|
||||
|
||||
it should "convert a simple java model" in {
|
||||
val model = new ModelImpl()
|
||||
.description("a sample model")
|
||||
@ -124,6 +123,37 @@ class JavaModelTest extends FlatSpec with Matchers {
|
||||
vars.get(0).isContainer should equal (true)
|
||||
}
|
||||
|
||||
|
||||
ignore should "convert a model with a map with complex list property" in {
|
||||
val model = new ModelImpl()
|
||||
.description("a sample model")
|
||||
.property("translations", new MapProperty()
|
||||
.additionalProperties(
|
||||
new ArrayProperty().items(new RefProperty("Pet")))
|
||||
)
|
||||
.required("id")
|
||||
|
||||
val codegen = new JavaClientCodegen()
|
||||
val cm = codegen.fromModel("sample", model)
|
||||
|
||||
cm.name should be ("sample")
|
||||
cm.classname should be ("Sample")
|
||||
cm.description should be ("a sample model")
|
||||
cm.vars.size should be (1)
|
||||
|
||||
val vars = cm.vars
|
||||
vars.get(0).baseName should be ("translations")
|
||||
vars.get(0).getter should be ("getTranslations")
|
||||
vars.get(0).setter should be ("setTranslations")
|
||||
vars.get(0).datatype should be ("Map<String, List<Pet>>")
|
||||
vars.get(0).name should be ("translations")
|
||||
vars.get(0).defaultValue should be ("new HashMap<String, List<Pet>>() ")
|
||||
vars.get(0).baseType should be ("Map")
|
||||
vars.get(0).containerType should be ("map")
|
||||
vars.get(0).required should equal (false)
|
||||
vars.get(0).isContainer should equal (true)
|
||||
}
|
||||
|
||||
it should "convert a model with complex properties" in {
|
||||
val model = new ModelImpl()
|
||||
.description("a sample model")
|
||||
@ -265,4 +295,44 @@ class JavaModelTest extends FlatSpec with Matchers {
|
||||
vars.get(0).required should equal (true)
|
||||
vars.get(0).isNotContainer should equal (true)
|
||||
}
|
||||
|
||||
it should "convert a model with a 2nd char upper-case property names" in {
|
||||
val model = new ModelImpl()
|
||||
.description("a model with a 2nd char upper-case property names")
|
||||
.property("pId", new StringProperty())
|
||||
.required("pId")
|
||||
|
||||
val codegen = new JavaClientCodegen()
|
||||
val cm = codegen.fromModel("sample", model)
|
||||
|
||||
cm.name should be ("sample")
|
||||
cm.classname should be ("Sample")
|
||||
cm.vars.size should be (1)
|
||||
|
||||
val vars = cm.vars
|
||||
vars.get(0).baseName should be ("pId")
|
||||
vars.get(0).getter should be ("getpId")
|
||||
vars.get(0).setter should be ("setpId")
|
||||
vars.get(0).datatype should be ("String")
|
||||
vars.get(0).name should be ("pId")
|
||||
vars.get(0).defaultValue should be ("null")
|
||||
vars.get(0).baseType should be ("String")
|
||||
vars.get(0).hasMore should equal (null)
|
||||
vars.get(0).required should equal (true)
|
||||
vars.get(0).isNotContainer should equal (true)
|
||||
}
|
||||
|
||||
it should "convert hyphens per issue 503" in {
|
||||
val model = new ModelImpl()
|
||||
.description("a sample model")
|
||||
.property("created-at", new DateTimeProperty())
|
||||
|
||||
val codegen = new JavaClientCodegen()
|
||||
val cm = codegen.fromModel("sample", model)
|
||||
val vars = cm.vars
|
||||
vars.get(0).baseName should be("created-at")
|
||||
vars.get(0).getter should be ("getCreated_at")
|
||||
vars.get(0).setter should be ("setCreated_at")
|
||||
vars.get(0).name should be ("created_at")
|
||||
}
|
||||
}
|
||||
|
@ -3,14 +3,14 @@
|
||||
<parent>
|
||||
<groupId>com.wordnik</groupId>
|
||||
<artifactId>swagger-codegen-project</artifactId>
|
||||
<version>2.1.2-M1</version>
|
||||
<version>2.1.3-M1-SNAPSHOT</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<groupId>com.wordnik</groupId>
|
||||
<artifactId>swagger-generator</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<name>swagger-generator</name>
|
||||
<version>1.0.0</version>
|
||||
<version>2.1.3-M1-SNAPSHOT</version>
|
||||
<build>
|
||||
<sourceDirectory>src/main/java</sourceDirectory>
|
||||
<plugins>
|
||||
@ -221,20 +221,12 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<felix-version>2.3.4</felix-version>
|
||||
<servlet-api-version>2.5</servlet-api-version>
|
||||
<logback-version>1.0.1</logback-version>
|
||||
<junit-version>4.8.1</junit-version>
|
||||
<maven-plugin-version>1.0.0</maven-plugin-version>
|
||||
<commons-lang-version>2.4</commons-lang-version>
|
||||
<slf4j-version>1.6.3</slf4j-version>
|
||||
<servlet-api-version>2.5</servlet-api-version>
|
||||
<zip-version>1.3.2</zip-version>
|
||||
<jetty-version>9.0.7.v20131107</jetty-version>
|
||||
<jersey2-version>2.4.1</jersey2-version>
|
||||
<swagger-core-version>1.5.1-M1</swagger-core-version>
|
||||
|
||||
<scala-maven-plugin-version>3.1.5</scala-maven-plugin-version>
|
||||
<scala-version>2.10.0</scala-version>
|
||||
</properties>
|
||||
</project>
|
||||
|
@ -66,6 +66,7 @@ public class Generator {
|
||||
List<File> files = new Codegen().opts(clientOptInput).generate();
|
||||
if(files.size() > 0) {
|
||||
List<File> filesToAdd = new ArrayList<File>();
|
||||
System.out.println("adding to " + outputFolder);
|
||||
filesToAdd.add(new File(outputFolder));
|
||||
ZipUtil zip = new ZipUtil();
|
||||
zip.compressFiles(filesToAdd, outputFilename);
|
||||
|
@ -34,9 +34,10 @@ public class SwaggerResource {
|
||||
|
||||
@GET
|
||||
@Path("/download/{fileId}")
|
||||
@Produces({"application/zip"})
|
||||
@Produces({MediaType.APPLICATION_OCTET_STREAM})
|
||||
@ApiOperation(value = "Downloads a pre-generated file",
|
||||
response = String.class)
|
||||
response = String.class,
|
||||
tags = {"clients", "servers"})
|
||||
public Response downloadFile(@PathParam("fileId") String fileId) throws Exception {
|
||||
Generated g = fileMap.get(fileId);
|
||||
System.out.println("looking for fileId " + fileId);
|
||||
@ -57,9 +58,10 @@ public class SwaggerResource {
|
||||
|
||||
@POST
|
||||
@Path("/clients/{language}")
|
||||
@Produces({"application/zip", "application/json"})
|
||||
@ApiOperation(
|
||||
value = "Generates a client library based on the config")
|
||||
value = "Generates a client library based on the config",
|
||||
response = ResponseCode.class,
|
||||
tags = "clients")
|
||||
public Response generateClient(
|
||||
@ApiParam(value = "The target language for the client library", allowableValues = "android,java,php,objc,docs", required = true) @PathParam("language") String language,
|
||||
@ApiParam(value = "Configuration for building the client library", required = true) GeneratorInput opts) throws Exception {
|
||||
@ -85,7 +87,8 @@ public class SwaggerResource {
|
||||
@Path("/clients")
|
||||
@ApiOperation(value = "Gets languages supported by the client generator",
|
||||
response = String.class,
|
||||
responseContainer = "List")
|
||||
responseContainer = "List",
|
||||
tags = "clients")
|
||||
public Response clientOptions() {
|
||||
String[] languages = new String[clients.size()];
|
||||
languages = clients.toArray(languages);
|
||||
@ -96,7 +99,8 @@ public class SwaggerResource {
|
||||
@Path("/servers")
|
||||
@ApiOperation(value = "Gets languages supported by the server generator",
|
||||
response = String.class,
|
||||
responseContainer = "List")
|
||||
responseContainer = "List",
|
||||
tags = "servers")
|
||||
public Response serverOptions() {
|
||||
String[] languages = new String[servers.size()];
|
||||
languages = servers.toArray(languages);
|
||||
@ -106,7 +110,8 @@ public class SwaggerResource {
|
||||
@POST
|
||||
@Path("/servers/{framework}")
|
||||
@ApiOperation(value = "Generates a server library for the supplied server framework",
|
||||
notes = "The model representing this is not accurate, it needs to contain a consolidated JSON structure")
|
||||
response = ResponseCode.class,
|
||||
tags = "servers")
|
||||
public Response generateServerForLanguage(
|
||||
@ApiParam(value = "framework", allowableValues = "jaxrs,nodejs", required = true) @PathParam("framework") String framework,
|
||||
@ApiParam(value = "parameters", required = true) GeneratorInput opts)
|
||||
|
6
pom.xml
6
pom.xml
@ -9,7 +9,7 @@
|
||||
<artifactId>swagger-codegen-project</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>swagger-codegen-project</name>
|
||||
<version>2.1.2-M1</version>
|
||||
<version>2.1.3-M1-SNAPSHOT</version>
|
||||
<url>https://github.com/swagger-api/swagger-codegen</url>
|
||||
<scm>
|
||||
<connection>scm:git:git@github.com:swagger-api/swagger-codegen.git</connection>
|
||||
@ -347,10 +347,10 @@
|
||||
</repository>
|
||||
</repositories>
|
||||
<properties>
|
||||
<swagger-parser-version>1.0.1</swagger-parser-version>
|
||||
<swagger-parser-version>1.0.3</swagger-parser-version>
|
||||
<scala-version>2.11.1</scala-version>
|
||||
<felix-version>2.3.4</felix-version>
|
||||
<swagger-core-version>1.5.2-M1</swagger-core-version>
|
||||
<swagger-core-version>1.5.3-M1-SNAPSHOT</swagger-core-version>
|
||||
<scala-test-version>2.1.4</scala-test-version>
|
||||
<commons-io-version>2.3</commons-io-version>
|
||||
<commons-cli-version>1.2</commons-cli-version>
|
||||
|
@ -19,16 +19,75 @@ import javax.ws.rs.core.MediaType;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.text.ParseException;
|
||||
|
||||
public class ApiInvoker {
|
||||
private static ApiInvoker INSTANCE = new ApiInvoker();
|
||||
private Map<String, Client> hostMap = new HashMap<String, Client>();
|
||||
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
|
||||
private boolean isDebug = false;
|
||||
|
||||
/**
|
||||
* ISO 8601 date time format.
|
||||
* @see https://en.wikipedia.org/wiki/ISO_8601
|
||||
*/
|
||||
public static final SimpleDateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
|
||||
|
||||
/**
|
||||
* ISO 8601 date format.
|
||||
* @see https://en.wikipedia.org/wiki/ISO_8601
|
||||
*/
|
||||
public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
|
||||
|
||||
static {
|
||||
// Use UTC as the default time zone.
|
||||
DATE_TIME_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
}
|
||||
|
||||
public static Date parseDateTime(String str) {
|
||||
try {
|
||||
return DATE_TIME_FORMAT.parse(str);
|
||||
} catch (java.text.ParseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Date parseDate(String str) {
|
||||
try {
|
||||
return DATE_FORMAT.parse(str);
|
||||
} catch (java.text.ParseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String formatDateTime(Date datetime) {
|
||||
return DATE_TIME_FORMAT.format(datetime);
|
||||
}
|
||||
|
||||
public static String formatDate(Date date) {
|
||||
return DATE_FORMAT.format(date);
|
||||
}
|
||||
|
||||
public static String parameterToString(Object param) {
|
||||
if (param == null) {
|
||||
return "";
|
||||
} else if (param instanceof Date) {
|
||||
return formatDateTime((Date) param);
|
||||
} else {
|
||||
return String.valueOf(param);
|
||||
}
|
||||
}
|
||||
|
||||
public void enableDebug() {
|
||||
isDebug = true;
|
||||
}
|
||||
|
@ -148,8 +148,8 @@ public class PetApi {
|
||||
Map<String, String> headerParams = new HashMap<String, String>();
|
||||
Map<String, String> formParams = new HashMap<String, String>();
|
||||
|
||||
if(!"null".equals(String.valueOf(status)))
|
||||
queryParams.put("status", String.valueOf(status));
|
||||
if (status != null)
|
||||
queryParams.put("status", ApiInvoker.parameterToString(status));
|
||||
|
||||
|
||||
String[] contentTypes = {
|
||||
@ -200,8 +200,8 @@ public class PetApi {
|
||||
Map<String, String> headerParams = new HashMap<String, String>();
|
||||
Map<String, String> formParams = new HashMap<String, String>();
|
||||
|
||||
if(!"null".equals(String.valueOf(tags)))
|
||||
queryParams.put("tags", String.valueOf(tags));
|
||||
if (tags != null)
|
||||
queryParams.put("tags", ApiInvoker.parameterToString(tags));
|
||||
|
||||
|
||||
String[] contentTypes = {
|
||||
@ -317,17 +317,17 @@ public class PetApi {
|
||||
FormDataMultiPart mp = new FormDataMultiPart();
|
||||
|
||||
hasFields = true;
|
||||
mp.field("name", name, MediaType.MULTIPART_FORM_DATA_TYPE);
|
||||
mp.field("name", ApiInvoker.parameterToString(name), MediaType.MULTIPART_FORM_DATA_TYPE);
|
||||
|
||||
hasFields = true;
|
||||
mp.field("status", status, MediaType.MULTIPART_FORM_DATA_TYPE);
|
||||
mp.field("status", ApiInvoker.parameterToString(status), MediaType.MULTIPART_FORM_DATA_TYPE);
|
||||
|
||||
if(hasFields)
|
||||
postBody = mp;
|
||||
}
|
||||
else {
|
||||
formParams.put("name", name);
|
||||
formParams.put("status", status);
|
||||
formParams.put("name", ApiInvoker.parameterToString(name));
|
||||
formParams.put("status", ApiInvoker.parameterToString(status));
|
||||
|
||||
}
|
||||
|
||||
@ -364,7 +364,7 @@ public class PetApi {
|
||||
Map<String, String> formParams = new HashMap<String, String>();
|
||||
|
||||
|
||||
headerParams.put("api_key", api_key);
|
||||
headerParams.put("api_key", ApiInvoker.parameterToString(api_key));
|
||||
|
||||
String[] contentTypes = {
|
||||
|
||||
@ -428,7 +428,7 @@ public class PetApi {
|
||||
FormDataMultiPart mp = new FormDataMultiPart();
|
||||
|
||||
hasFields = true;
|
||||
mp.field("additionalMetadata", additionalMetadata, MediaType.MULTIPART_FORM_DATA_TYPE);
|
||||
mp.field("additionalMetadata", ApiInvoker.parameterToString(additionalMetadata), MediaType.MULTIPART_FORM_DATA_TYPE);
|
||||
|
||||
hasFields = true;
|
||||
mp.field("file", file, MediaType.MULTIPART_FORM_DATA_TYPE);
|
||||
@ -437,7 +437,7 @@ public class PetApi {
|
||||
postBody = mp;
|
||||
}
|
||||
else {
|
||||
formParams.put("additionalMetadata", additionalMetadata);
|
||||
formParams.put("additionalMetadata", ApiInvoker.parameterToString(additionalMetadata));
|
||||
|
||||
|
||||
}
|
||||
|
@ -198,10 +198,10 @@ public class UserApi {
|
||||
Map<String, String> headerParams = new HashMap<String, String>();
|
||||
Map<String, String> formParams = new HashMap<String, String>();
|
||||
|
||||
if(!"null".equals(String.valueOf(username)))
|
||||
queryParams.put("username", String.valueOf(username));
|
||||
if(!"null".equals(String.valueOf(password)))
|
||||
queryParams.put("password", String.valueOf(password));
|
||||
if (username != null)
|
||||
queryParams.put("username", ApiInvoker.parameterToString(username));
|
||||
if (password != null)
|
||||
queryParams.put("password", ApiInvoker.parameterToString(password));
|
||||
|
||||
|
||||
String[] contentTypes = {
|
||||
|
@ -110,28 +110,6 @@ static NSString * basePath = @"http://petstore.swagger.io/v2";
|
||||
|
||||
|
||||
|
||||
// primitive response type
|
||||
|
||||
|
||||
// no return base type
|
||||
return [client stringWithCompletionBlock: requestUrl
|
||||
method: @"PUT"
|
||||
queryParams: queryParams
|
||||
body: bodyDictionary
|
||||
headerParams: headerParams
|
||||
requestContentType: requestContentType
|
||||
responseContentType: responseContentType
|
||||
completionBlock: ^(NSString *data, NSError *error) {
|
||||
if (error) {
|
||||
completionBlock(error);
|
||||
return;
|
||||
}
|
||||
completionBlock(nil);
|
||||
}];
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
-(NSNumber*) addPetWithCompletionBlock: (SWGPet*) body
|
||||
@ -193,28 +171,6 @@ static NSString * basePath = @"http://petstore.swagger.io/v2";
|
||||
|
||||
|
||||
|
||||
// primitive response type
|
||||
|
||||
|
||||
// no return base type
|
||||
return [client stringWithCompletionBlock: requestUrl
|
||||
method: @"POST"
|
||||
queryParams: queryParams
|
||||
body: bodyDictionary
|
||||
headerParams: headerParams
|
||||
requestContentType: requestContentType
|
||||
responseContentType: responseContentType
|
||||
completionBlock: ^(NSString *data, NSError *error) {
|
||||
if (error) {
|
||||
completionBlock(error);
|
||||
return;
|
||||
}
|
||||
completionBlock(nil);
|
||||
}];
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
-(NSNumber*) findPetsByStatusWithCompletionBlock: (NSArray*) status
|
||||
@ -443,28 +399,6 @@ static NSString * basePath = @"http://petstore.swagger.io/v2";
|
||||
|
||||
|
||||
|
||||
// primitive response type
|
||||
|
||||
|
||||
// no return base type
|
||||
return [client stringWithCompletionBlock: requestUrl
|
||||
method: @"POST"
|
||||
queryParams: queryParams
|
||||
body: bodyDictionary
|
||||
headerParams: headerParams
|
||||
requestContentType: requestContentType
|
||||
responseContentType: responseContentType
|
||||
completionBlock: ^(NSString *data, NSError *error) {
|
||||
if (error) {
|
||||
completionBlock(error);
|
||||
return;
|
||||
}
|
||||
completionBlock(nil);
|
||||
}];
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
-(NSNumber*) deletePetWithCompletionBlock: (NSString*) api_key
|
||||
@ -509,28 +443,6 @@ static NSString * basePath = @"http://petstore.swagger.io/v2";
|
||||
|
||||
|
||||
|
||||
// primitive response type
|
||||
|
||||
|
||||
// no return base type
|
||||
return [client stringWithCompletionBlock: requestUrl
|
||||
method: @"DELETE"
|
||||
queryParams: queryParams
|
||||
body: bodyDictionary
|
||||
headerParams: headerParams
|
||||
requestContentType: requestContentType
|
||||
responseContentType: responseContentType
|
||||
completionBlock: ^(NSString *data, NSError *error) {
|
||||
if (error) {
|
||||
completionBlock(error);
|
||||
return;
|
||||
}
|
||||
completionBlock(nil);
|
||||
}];
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
-(NSNumber*) uploadFileWithCompletionBlock: (NSNumber*) petId
|
||||
|
@ -303,28 +303,6 @@ static NSString * basePath = @"http://petstore.swagger.io/v2";
|
||||
|
||||
|
||||
|
||||
// primitive response type
|
||||
|
||||
|
||||
// no return base type
|
||||
return [client stringWithCompletionBlock: requestUrl
|
||||
method: @"DELETE"
|
||||
queryParams: queryParams
|
||||
body: bodyDictionary
|
||||
headerParams: headerParams
|
||||
requestContentType: requestContentType
|
||||
responseContentType: responseContentType
|
||||
completionBlock: ^(NSString *data, NSError *error) {
|
||||
if (error) {
|
||||
completionBlock(error);
|
||||
return;
|
||||
}
|
||||
completionBlock(nil);
|
||||
}];
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -554,28 +554,6 @@ static NSString * basePath = @"http://petstore.swagger.io/v2";
|
||||
|
||||
|
||||
|
||||
// primitive response type
|
||||
|
||||
|
||||
// no return base type
|
||||
return [client stringWithCompletionBlock: requestUrl
|
||||
method: @"PUT"
|
||||
queryParams: queryParams
|
||||
body: bodyDictionary
|
||||
headerParams: headerParams
|
||||
requestContentType: requestContentType
|
||||
responseContentType: responseContentType
|
||||
completionBlock: ^(NSString *data, NSError *error) {
|
||||
if (error) {
|
||||
completionBlock(error);
|
||||
return;
|
||||
}
|
||||
completionBlock(nil);
|
||||
}];
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
-(NSNumber*) deleteUserWithCompletionBlock: (NSString*) username
|
||||
@ -617,28 +595,6 @@ static NSString * basePath = @"http://petstore.swagger.io/v2";
|
||||
|
||||
|
||||
|
||||
// primitive response type
|
||||
|
||||
|
||||
// no return base type
|
||||
return [client stringWithCompletionBlock: requestUrl
|
||||
method: @"DELETE"
|
||||
queryParams: queryParams
|
||||
body: bodyDictionary
|
||||
headerParams: headerParams
|
||||
requestContentType: requestContentType
|
||||
responseContentType: responseContentType
|
||||
completionBlock: ^(NSString *data, NSError *error) {
|
||||
if (error) {
|
||||
completionBlock(error);
|
||||
return;
|
||||
}
|
||||
completionBlock(nil);
|
||||
}];
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -57,6 +57,7 @@ class PetApi {
|
||||
$body = $body;
|
||||
}
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
@ -102,6 +103,7 @@ class PetApi {
|
||||
$body = $body;
|
||||
}
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
@ -146,6 +148,7 @@ class PetApi {
|
||||
|
||||
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
@ -196,6 +199,7 @@ class PetApi {
|
||||
|
||||
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
@ -247,6 +251,7 @@ class PetApi {
|
||||
|
||||
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
@ -297,15 +302,16 @@ class PetApi {
|
||||
$resourcePath = str_replace("{" . "petId" . "}",
|
||||
$this->apiClient->toPathValue($petId), $resourcePath);
|
||||
}
|
||||
|
||||
// form params
|
||||
if ($name !== null) {
|
||||
$formParams[name] = $name;
|
||||
}
|
||||
$formParams['name'] = $this->apiClient->toFormValue($name);
|
||||
}// form params
|
||||
if ($status !== null) {
|
||||
$formParams[status] = $status;
|
||||
$formParams['status'] = $this->apiClient->toFormValue($status);
|
||||
}
|
||||
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
@ -355,6 +361,7 @@ class PetApi {
|
||||
|
||||
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
@ -399,15 +406,16 @@ class PetApi {
|
||||
$resourcePath = str_replace("{" . "petId" . "}",
|
||||
$this->apiClient->toPathValue($petId), $resourcePath);
|
||||
}
|
||||
|
||||
// form params
|
||||
if ($additionalMetadata !== null) {
|
||||
$formParams[additionalMetadata] = $additionalMetadata;
|
||||
}
|
||||
$formParams['additionalMetadata'] = $this->apiClient->toFormValue($additionalMetadata);
|
||||
}// form params
|
||||
if ($file !== null) {
|
||||
$formParams[file] = '@' . $file;
|
||||
$formParams['file'] = '@' . $this->apiClient->toFormValue($file);
|
||||
}
|
||||
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
|
@ -52,6 +52,7 @@ class StoreApi {
|
||||
|
||||
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
@ -103,6 +104,7 @@ class StoreApi {
|
||||
$body = $body;
|
||||
}
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
@ -154,6 +156,7 @@ class StoreApi {
|
||||
|
||||
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
@ -205,6 +208,7 @@ class StoreApi {
|
||||
|
||||
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
|
@ -48,6 +48,18 @@ class APIClient {
|
||||
$this->headerValue = $headerValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user agent of the API client
|
||||
*
|
||||
* @param string $user_agent The user agent of the API client
|
||||
*/
|
||||
public function setUserAgent($user_agent) {
|
||||
if (!is_string($user_agent)) {
|
||||
throw new Exception('User-agent must be a string.');
|
||||
}
|
||||
$this->user_agent= $user_agent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $seconds Number of seconds before timing out [set to 0 for no timeout]
|
||||
*/
|
||||
@ -58,7 +70,6 @@ class APIClient {
|
||||
$this->curl_timout = $seconds;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $resourcePath path to method endpoint
|
||||
* @param string $method method to call
|
||||
@ -107,6 +118,9 @@ class APIClient {
|
||||
if ($method == self::$POST) {
|
||||
curl_setopt($curl, CURLOPT_POST, true);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
|
||||
} else if ($method == self::$PATCH) {
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PATCH");
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
|
||||
} else if ($method == self::$PUT) {
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
|
||||
@ -118,25 +132,35 @@ class APIClient {
|
||||
}
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
|
||||
// Set user agent
|
||||
if ($this->user_agent) {
|
||||
curl_setopt($curl, CURLOPT_USERAGENT, $this->user_agent);
|
||||
} else { // use PHP-Swagger as the default user agent
|
||||
curl_setopt($curl, CURLOPT_USERAGENT, 'PHP-Swagger');
|
||||
}
|
||||
|
||||
// Make the request
|
||||
$response = curl_exec($curl);
|
||||
$response_info = curl_getinfo($curl);
|
||||
|
||||
// Handle the response
|
||||
if ($response_info['http_code'] == 0) {
|
||||
throw new Exception("TIMEOUT: api call to " . $url .
|
||||
" took more than 5s to return" );
|
||||
} else if ($response_info['http_code'] == 200) {
|
||||
throw new APIClientException("TIMEOUT: api call to " . $url .
|
||||
" took more than 5s to return", 0, $response_info, $response);
|
||||
} else if ($response_info['http_code'] >= 200 && $response_info['http_code'] <= 299 ) {
|
||||
$data = json_decode($response);
|
||||
if (json_last_error() > 0) { // if response is a string
|
||||
$data = $response;
|
||||
}
|
||||
} else if ($response_info['http_code'] == 401) {
|
||||
throw new Exception("Unauthorized API request to " . $url .
|
||||
": ".json_decode($response)->message );
|
||||
throw new APIClientException("Unauthorized API request to " . $url .
|
||||
": " . serialize($response), 0, $response_info, $response);
|
||||
} else if ($response_info['http_code'] == 404) {
|
||||
$data = null;
|
||||
} else {
|
||||
throw new Exception("Can't connect to the api: " . $url .
|
||||
throw new APIClientException("Can't connect to the api: " . $url .
|
||||
" response code: " .
|
||||
$response_info['http_code']);
|
||||
$response_info['http_code'], 0, $response_info, $response);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
@ -175,7 +199,7 @@ class APIClient {
|
||||
* @return string the serialized object
|
||||
*/
|
||||
public static function toPathValue($value) {
|
||||
return rawurlencode($value);
|
||||
return rawurlencode(toString($value));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,19 +214,47 @@ class APIClient {
|
||||
if (is_array($object)) {
|
||||
return implode(',', $object);
|
||||
} else {
|
||||
return $object;
|
||||
return toString($object);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Just pass through the header value for now. Placeholder in case we
|
||||
* find out we need to do something with header values.
|
||||
* Take value and turn it into a string suitable for inclusion in
|
||||
* the header. If it's a string, pass through unchanged
|
||||
* If it's a datetime object, format it in ISO8601
|
||||
* @param string $value a string which will be part of the header
|
||||
* @return string the header string
|
||||
*/
|
||||
public static function toHeaderValue($value) {
|
||||
return toString($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Take value and turn it into a string suitable for inclusion in
|
||||
* the http body (form parameter). If it's a string, pass through unchanged
|
||||
* If it's a datetime object, format it in ISO8601
|
||||
* @param string $value the value of the form parameter
|
||||
* @return string the form string
|
||||
*/
|
||||
public static function toFormValue($value) {
|
||||
return toString($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Take value and turn it into a string suitable for inclusion in
|
||||
* the parameter. If it's a string, pass through unchanged
|
||||
* If it's a datetime object, format it in ISO8601
|
||||
* @param string $value the value of the parameter
|
||||
* @return string the header string
|
||||
*/
|
||||
public static function toString($value) {
|
||||
if ($value instanceof \DateTime) { // datetime in ISO8601 format
|
||||
return $value->format(\DateTime::ISO8601);
|
||||
}
|
||||
else {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize a JSON string into an object
|
||||
@ -220,13 +272,14 @@ class APIClient {
|
||||
$inner = substr($class, 4, -1);
|
||||
$values = array();
|
||||
if(strrpos($inner, ",") !== false) {
|
||||
$subClass = explode(',', $inner, 2)[1];
|
||||
$subClass_array = explode(',', $inner, 2);
|
||||
$subClass = $subClass_array[1];
|
||||
foreach ($data as $key => $value) {
|
||||
$values[] = array($key => self::deserialize($value, $subClass));
|
||||
}
|
||||
}
|
||||
$deserialized = $values;
|
||||
} elseif (substr($class, 0, 6) == 'array[') {
|
||||
} elseif (strcasecmp(substr($class, 0, 6),'array[') == 0) {
|
||||
$subClass = substr($class, 6, -1);
|
||||
$values = array();
|
||||
foreach ($data as $key => $value) {
|
||||
@ -253,3 +306,20 @@ class APIClient {
|
||||
|
||||
}
|
||||
|
||||
class APIClientException extends Exception {
|
||||
protected $response, $response_info;
|
||||
|
||||
public function __construct($message="", $code=0, $response_info=null, $response=null) {
|
||||
parent::__construct($message, $code);
|
||||
$this->response_info = $response_info;
|
||||
$this->response = $response;
|
||||
}
|
||||
|
||||
public function getResponse() {
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
public function getResponseInfo() {
|
||||
return $this->response_info;
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ class UserApi {
|
||||
$body = $body;
|
||||
}
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
@ -102,6 +103,7 @@ class UserApi {
|
||||
$body = $body;
|
||||
}
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
@ -147,6 +149,7 @@ class UserApi {
|
||||
$body = $body;
|
||||
}
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
@ -195,6 +198,7 @@ class UserApi {
|
||||
|
||||
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
@ -241,6 +245,7 @@ class UserApi {
|
||||
|
||||
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
@ -286,6 +291,7 @@ class UserApi {
|
||||
|
||||
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
@ -342,6 +348,7 @@ class UserApi {
|
||||
$body = $body;
|
||||
}
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
@ -387,6 +394,7 @@ class UserApi {
|
||||
|
||||
|
||||
|
||||
// for HTTP post (form)
|
||||
$body = $body ?: $formParams;
|
||||
|
||||
if (strpos($headerParams['Content-Type'], "application/x-www-form-urlencoded") > -1) {
|
||||
|
@ -22,7 +22,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
class Category {
|
||||
class Category implements ArrayAccess {
|
||||
static $swaggerTypes = array(
|
||||
'id' => 'int',
|
||||
'name' => 'string'
|
||||
@ -31,4 +31,25 @@ class Category {
|
||||
|
||||
public $id; /* int */
|
||||
public $name; /* string */
|
||||
|
||||
public function __construct(array $data) {
|
||||
$this->id = $data["id"];
|
||||
$this->name = $data["name"];
|
||||
}
|
||||
|
||||
public function offsetExists($offset) {
|
||||
return isset($this->$offset);
|
||||
}
|
||||
|
||||
public function offsetGet($offset) {
|
||||
return $this->$offset;
|
||||
}
|
||||
|
||||
public function offsetSet($offset, $value) {
|
||||
$this->$offset = $value;
|
||||
}
|
||||
|
||||
public function offsetUnset($offset) {
|
||||
unset($this->$offset);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
class Order {
|
||||
class Order implements ArrayAccess {
|
||||
static $swaggerTypes = array(
|
||||
'id' => 'int',
|
||||
'petId' => 'int',
|
||||
@ -42,4 +42,29 @@ class Order {
|
||||
*/
|
||||
public $status; /* string */
|
||||
public $complete; /* boolean */
|
||||
|
||||
public function __construct(array $data) {
|
||||
$this->id = $data["id"];
|
||||
$this->petId = $data["petId"];
|
||||
$this->quantity = $data["quantity"];
|
||||
$this->shipDate = $data["shipDate"];
|
||||
$this->status = $data["status"];
|
||||
$this->complete = $data["complete"];
|
||||
}
|
||||
|
||||
public function offsetExists($offset) {
|
||||
return isset($this->$offset);
|
||||
}
|
||||
|
||||
public function offsetGet($offset) {
|
||||
return $this->$offset;
|
||||
}
|
||||
|
||||
public function offsetSet($offset, $value) {
|
||||
$this->$offset = $value;
|
||||
}
|
||||
|
||||
public function offsetUnset($offset) {
|
||||
unset($this->$offset);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
class Pet {
|
||||
class Pet implements ArrayAccess {
|
||||
static $swaggerTypes = array(
|
||||
'id' => 'int',
|
||||
'category' => 'Category',
|
||||
@ -42,4 +42,29 @@ class Pet {
|
||||
* pet status in the store
|
||||
*/
|
||||
public $status; /* string */
|
||||
|
||||
public function __construct(array $data) {
|
||||
$this->id = $data["id"];
|
||||
$this->category = $data["category"];
|
||||
$this->name = $data["name"];
|
||||
$this->photoUrls = $data["photoUrls"];
|
||||
$this->tags = $data["tags"];
|
||||
$this->status = $data["status"];
|
||||
}
|
||||
|
||||
public function offsetExists($offset) {
|
||||
return isset($this->$offset);
|
||||
}
|
||||
|
||||
public function offsetGet($offset) {
|
||||
return $this->$offset;
|
||||
}
|
||||
|
||||
public function offsetSet($offset, $value) {
|
||||
$this->$offset = $value;
|
||||
}
|
||||
|
||||
public function offsetUnset($offset) {
|
||||
unset($this->$offset);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
class Tag {
|
||||
class Tag implements ArrayAccess {
|
||||
static $swaggerTypes = array(
|
||||
'id' => 'int',
|
||||
'name' => 'string'
|
||||
@ -31,4 +31,25 @@ class Tag {
|
||||
|
||||
public $id; /* int */
|
||||
public $name; /* string */
|
||||
|
||||
public function __construct(array $data) {
|
||||
$this->id = $data["id"];
|
||||
$this->name = $data["name"];
|
||||
}
|
||||
|
||||
public function offsetExists($offset) {
|
||||
return isset($this->$offset);
|
||||
}
|
||||
|
||||
public function offsetGet($offset) {
|
||||
return $this->$offset;
|
||||
}
|
||||
|
||||
public function offsetSet($offset, $value) {
|
||||
$this->$offset = $value;
|
||||
}
|
||||
|
||||
public function offsetUnset($offset) {
|
||||
unset($this->$offset);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
class User {
|
||||
class User implements ArrayAccess {
|
||||
static $swaggerTypes = array(
|
||||
'id' => 'int',
|
||||
'username' => 'string',
|
||||
@ -46,4 +46,31 @@ class User {
|
||||
* User Status
|
||||
*/
|
||||
public $userStatus; /* int */
|
||||
|
||||
public function __construct(array $data) {
|
||||
$this->id = $data["id"];
|
||||
$this->username = $data["username"];
|
||||
$this->firstName = $data["firstName"];
|
||||
$this->lastName = $data["lastName"];
|
||||
$this->email = $data["email"];
|
||||
$this->password = $data["password"];
|
||||
$this->phone = $data["phone"];
|
||||
$this->userStatus = $data["userStatus"];
|
||||
}
|
||||
|
||||
public function offsetExists($offset) {
|
||||
return isset($this->$offset);
|
||||
}
|
||||
|
||||
public function offsetGet($offset) {
|
||||
return $this->$offset;
|
||||
}
|
||||
|
||||
public function offsetSet($offset, $value) {
|
||||
$this->$offset = $value;
|
||||
}
|
||||
|
||||
public function offsetUnset($offset) {
|
||||
unset($this->$offset);
|
||||
}
|
||||
}
|
||||
|
391
samples/client/petstore/ruby/lib/PetApi.rb
Normal file
391
samples/client/petstore/ruby/lib/PetApi.rb
Normal file
@ -0,0 +1,391 @@
|
||||
require "uri"
|
||||
|
||||
class PetApi
|
||||
basePath = "http://petstore.swagger.io/v2"
|
||||
# apiInvoker = APIInvoker
|
||||
|
||||
def self.escapeString(string)
|
||||
URI.encode(string.to_s)
|
||||
end
|
||||
|
||||
|
||||
def self.updatePet (body, opts={})
|
||||
query_param_keys = []
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
:body => body
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/pet".sub('{format}','json')
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
if body != nil
|
||||
if body.is_a?(Array)
|
||||
array = Array.new
|
||||
body.each do |item|
|
||||
if item.respond_to?("to_body".to_sym)
|
||||
array.push item.to_body
|
||||
else
|
||||
array.push item
|
||||
end
|
||||
end
|
||||
post_body = array
|
||||
|
||||
else
|
||||
if body.respond_to?("to_body".to_sym)
|
||||
post_body = body.to_body
|
||||
else
|
||||
post_body = body
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
|
||||
|
||||
|
||||
Swagger::Request.new(:PUT, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
def self.addPet (body, opts={})
|
||||
query_param_keys = []
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
:body => body
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/pet".sub('{format}','json')
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
if body != nil
|
||||
if body.is_a?(Array)
|
||||
array = Array.new
|
||||
body.each do |item|
|
||||
if item.respond_to?("to_body".to_sym)
|
||||
array.push item.to_body
|
||||
else
|
||||
array.push item
|
||||
end
|
||||
end
|
||||
post_body = array
|
||||
|
||||
else
|
||||
if body.respond_to?("to_body".to_sym)
|
||||
post_body = body.to_body
|
||||
else
|
||||
post_body = body
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
|
||||
|
||||
|
||||
Swagger::Request.new(:POST, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
def self.findPetsByStatus (status, opts={})
|
||||
query_param_keys = [:status]
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
:status => status
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/pet/findByStatus".sub('{format}','json')
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
|
||||
|
||||
response = Swagger::Request.new(:GET, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make.body
|
||||
|
||||
response.map {|response| Pet.new(response) }
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
def self.findPetsByTags (tags, opts={})
|
||||
query_param_keys = [:tags]
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
:tags => tags
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/pet/findByTags".sub('{format}','json')
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
|
||||
|
||||
response = Swagger::Request.new(:GET, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make.body
|
||||
|
||||
response.map {|response| Pet.new(response) }
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
def self.getPetById (petId, opts={})
|
||||
query_param_keys = []
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
:petId => petId
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/pet/{petId}".sub('{format}','json').sub('{' + 'petId' + '}', escapeString(petId))
|
||||
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
|
||||
|
||||
response = Swagger::Request.new(:GET, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make.body
|
||||
Pet.new(response)
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
def self.updatePetWithForm (petId,name,status, opts={})
|
||||
query_param_keys = []
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
:petId => petId,
|
||||
:name => name,
|
||||
:status => status
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/pet/{petId}".sub('{format}','json').sub('{' + 'petId' + '}', escapeString(petId))
|
||||
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
form_parameter_hash["name"] = name
|
||||
form_parameter_hash["status"] = status
|
||||
|
||||
|
||||
|
||||
Swagger::Request.new(:POST, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
def self.deletePet (api_key,petId, opts={})
|
||||
query_param_keys = []
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
:api_key => api_key,
|
||||
:petId => petId
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/pet/{petId}".sub('{format}','json').sub('{' + 'petId' + '}', escapeString(petId))
|
||||
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
headers[:'api_key'] = api_key
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
|
||||
|
||||
|
||||
Swagger::Request.new(:DELETE, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
def self.uploadFile (petId,additionalMetadata,file, opts={})
|
||||
query_param_keys = []
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
:petId => petId,
|
||||
:additionalMetadata => additionalMetadata,
|
||||
:file => file
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/pet/{petId}/uploadImage".sub('{format}','json').sub('{' + 'petId' + '}', escapeString(petId))
|
||||
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
form_parameter_hash["additionalMetadata"] = additionalMetadata
|
||||
form_parameter_hash["file"] = file
|
||||
|
||||
|
||||
|
||||
Swagger::Request.new(:POST, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
197
samples/client/petstore/ruby/lib/StoreApi.rb
Normal file
197
samples/client/petstore/ruby/lib/StoreApi.rb
Normal file
@ -0,0 +1,197 @@
|
||||
require "uri"
|
||||
|
||||
class StoreApi
|
||||
basePath = "http://petstore.swagger.io/v2"
|
||||
# apiInvoker = APIInvoker
|
||||
|
||||
def self.escapeString(string)
|
||||
URI.encode(string.to_s)
|
||||
end
|
||||
|
||||
|
||||
def self.getInventory ( opts={})
|
||||
query_param_keys = []
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/store/inventory".sub('{format}','json')
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
|
||||
|
||||
response = Swagger::Request.new(:GET, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make.body
|
||||
|
||||
response.map {|response| map.new(response) }
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
def self.placeOrder (body, opts={})
|
||||
query_param_keys = []
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
:body => body
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/store/order".sub('{format}','json')
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
if body != nil
|
||||
if body.is_a?(Array)
|
||||
array = Array.new
|
||||
body.each do |item|
|
||||
if item.respond_to?("to_body".to_sym)
|
||||
array.push item.to_body
|
||||
else
|
||||
array.push item
|
||||
end
|
||||
end
|
||||
post_body = array
|
||||
|
||||
else
|
||||
if body.respond_to?("to_body".to_sym)
|
||||
post_body = body.to_body
|
||||
else
|
||||
post_body = body
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
|
||||
|
||||
response = Swagger::Request.new(:POST, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make.body
|
||||
Order.new(response)
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
def self.getOrderById (orderId, opts={})
|
||||
query_param_keys = []
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
:orderId => orderId
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/store/order/{orderId}".sub('{format}','json').sub('{' + 'orderId' + '}', escapeString(orderId))
|
||||
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
|
||||
|
||||
response = Swagger::Request.new(:GET, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make.body
|
||||
Order.new(response)
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
def self.deleteOrder (orderId, opts={})
|
||||
query_param_keys = []
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
:orderId => orderId
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/store/order/{orderId}".sub('{format}','json').sub('{' + 'orderId' + '}', escapeString(orderId))
|
||||
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
|
||||
|
||||
|
||||
Swagger::Request.new(:DELETE, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
421
samples/client/petstore/ruby/lib/UserApi.rb
Normal file
421
samples/client/petstore/ruby/lib/UserApi.rb
Normal file
@ -0,0 +1,421 @@
|
||||
require "uri"
|
||||
|
||||
class UserApi
|
||||
basePath = "http://petstore.swagger.io/v2"
|
||||
# apiInvoker = APIInvoker
|
||||
|
||||
def self.escapeString(string)
|
||||
URI.encode(string.to_s)
|
||||
end
|
||||
|
||||
|
||||
def self.createUser (body, opts={})
|
||||
query_param_keys = []
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
:body => body
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/user".sub('{format}','json')
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
if body != nil
|
||||
if body.is_a?(Array)
|
||||
array = Array.new
|
||||
body.each do |item|
|
||||
if item.respond_to?("to_body".to_sym)
|
||||
array.push item.to_body
|
||||
else
|
||||
array.push item
|
||||
end
|
||||
end
|
||||
post_body = array
|
||||
|
||||
else
|
||||
if body.respond_to?("to_body".to_sym)
|
||||
post_body = body.to_body
|
||||
else
|
||||
post_body = body
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
|
||||
|
||||
|
||||
Swagger::Request.new(:POST, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
def self.createUsersWithArrayInput (body, opts={})
|
||||
query_param_keys = []
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
:body => body
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/user/createWithArray".sub('{format}','json')
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
if body != nil
|
||||
if body.is_a?(Array)
|
||||
array = Array.new
|
||||
body.each do |item|
|
||||
if item.respond_to?("to_body".to_sym)
|
||||
array.push item.to_body
|
||||
else
|
||||
array.push item
|
||||
end
|
||||
end
|
||||
post_body = array
|
||||
|
||||
else
|
||||
if body.respond_to?("to_body".to_sym)
|
||||
post_body = body.to_body
|
||||
else
|
||||
post_body = body
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
|
||||
|
||||
|
||||
Swagger::Request.new(:POST, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
def self.createUsersWithListInput (body, opts={})
|
||||
query_param_keys = []
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
:body => body
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/user/createWithList".sub('{format}','json')
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
if body != nil
|
||||
if body.is_a?(Array)
|
||||
array = Array.new
|
||||
body.each do |item|
|
||||
if item.respond_to?("to_body".to_sym)
|
||||
array.push item.to_body
|
||||
else
|
||||
array.push item
|
||||
end
|
||||
end
|
||||
post_body = array
|
||||
|
||||
else
|
||||
if body.respond_to?("to_body".to_sym)
|
||||
post_body = body.to_body
|
||||
else
|
||||
post_body = body
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
|
||||
|
||||
|
||||
Swagger::Request.new(:POST, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
def self.loginUser (username,password, opts={})
|
||||
query_param_keys = [:username,:password]
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
:username => username,
|
||||
:password => password
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/user/login".sub('{format}','json')
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
|
||||
|
||||
response = Swagger::Request.new(:GET, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make.body
|
||||
string.new(response)
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
def self.logoutUser ( opts={})
|
||||
query_param_keys = []
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/user/logout".sub('{format}','json')
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
|
||||
|
||||
|
||||
Swagger::Request.new(:GET, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
def self.getUserByName (username, opts={})
|
||||
query_param_keys = []
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
:username => username
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/user/{username}".sub('{format}','json').sub('{' + 'username' + '}', escapeString(username))
|
||||
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
|
||||
|
||||
response = Swagger::Request.new(:GET, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make.body
|
||||
User.new(response)
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
def self.updateUser (username,body, opts={})
|
||||
query_param_keys = []
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
:username => username,
|
||||
:body => body
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/user/{username}".sub('{format}','json').sub('{' + 'username' + '}', escapeString(username))
|
||||
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
if body != nil
|
||||
if body.is_a?(Array)
|
||||
array = Array.new
|
||||
body.each do |item|
|
||||
if item.respond_to?("to_body".to_sym)
|
||||
array.push item.to_body
|
||||
else
|
||||
array.push item
|
||||
end
|
||||
end
|
||||
post_body = array
|
||||
|
||||
else
|
||||
if body.respond_to?("to_body".to_sym)
|
||||
post_body = body.to_body
|
||||
else
|
||||
post_body = body
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
|
||||
|
||||
|
||||
Swagger::Request.new(:PUT, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
def self.deleteUser (username, opts={})
|
||||
query_param_keys = []
|
||||
|
||||
|
||||
|
||||
# set default values and merge with input
|
||||
options = {
|
||||
:username => username
|
||||
|
||||
}.merge(opts)
|
||||
|
||||
#resource path
|
||||
path = "/user/{username}".sub('{format}','json').sub('{' + 'username' + '}', escapeString(username))
|
||||
|
||||
|
||||
# pull querystring keys from options
|
||||
queryopts = options.select do |key,value|
|
||||
query_param_keys.include? key
|
||||
end
|
||||
|
||||
# header parameters, if any
|
||||
headers = {}
|
||||
|
||||
|
||||
|
||||
# http body (model)
|
||||
post_body = nil
|
||||
|
||||
|
||||
# form parameters
|
||||
form_parameter_hash = {}
|
||||
|
||||
|
||||
|
||||
|
||||
Swagger::Request.new(:DELETE, path, {:params=>queryopts,:headers=>headers, :body=>post_body, :form_params => form_parameter_hash }).make
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
@ -6,7 +6,7 @@ module Swagger
|
||||
require 'typhoeus'
|
||||
require "swagger/version"
|
||||
|
||||
attr_accessor :host, :path, :format, :params, :body, :http_method, :headers
|
||||
attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params
|
||||
|
||||
|
||||
# All requests must have an HTTP method and a path
|
||||
@ -115,9 +115,18 @@ module Swagger
|
||||
end
|
||||
|
||||
# If body is an object, JSONify it before making the actual request.
|
||||
#
|
||||
# For form parameters, remove empty value
|
||||
def outgoing_body
|
||||
body.is_a?(String) ? body : body.to_json
|
||||
# http form
|
||||
if @body.nil? && @form_params && !@form_params.empty?
|
||||
data = form_params.dup
|
||||
data.each do |key, value|
|
||||
data[key] = value.to_s if value && !value.is_a?(File) # remove emtpy form parameter
|
||||
end
|
||||
data
|
||||
else # http body is JSON
|
||||
@body.is_a?(String) ? @body : @body.to_json
|
||||
end
|
||||
end
|
||||
|
||||
# Construct a query string from the query-string-type params
|
||||
@ -163,6 +172,13 @@ module Swagger
|
||||
:headers => self.headers.stringify_keys,
|
||||
)
|
||||
|
||||
when :patch,:PATCH
|
||||
Typhoeus::Request.patch(
|
||||
self.url,
|
||||
:body => self.outgoing_body,
|
||||
:headers => self.headers.stringify_keys,
|
||||
)
|
||||
|
||||
when :put,:PUT
|
||||
Typhoeus::Request.put(
|
||||
self.url,
|
||||
|
@ -2,4 +2,3 @@ module Swagger
|
||||
VERSION = "4.06.08"
|
||||
end
|
||||
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
|
||||
class Category
|
||||
attr_accessor :id, :name
|
||||
|
||||
# :internal => :external
|
||||
def self.attribute_map
|
||||
{
|
||||
:id => :id,
|
||||
:name => :name
|
||||
:id => :'id',
|
||||
:name => :'name'
|
||||
|
||||
}
|
||||
end
|
||||
@ -13,14 +13,15 @@ class Category
|
||||
def initialize(attributes = {})
|
||||
return if attributes.empty?
|
||||
# Morph attribute keys into undescored rubyish style
|
||||
|
||||
if self.class.attribute_map[:"id"]
|
||||
@id = attributes["id"]
|
||||
end
|
||||
|
||||
if self.class.attribute_map[:"name"]
|
||||
@name = attributes["name"]
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
def to_body
|
||||
@ -31,4 +32,3 @@ class Category
|
||||
body
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,14 +1,15 @@
|
||||
class Order
|
||||
attr_accessor :id, :pet_id, :quantity, :status, :ship_date
|
||||
|
||||
class Order
|
||||
attr_accessor :id, :petId, :quantity, :shipDate, :status, :complete
|
||||
# :internal => :external
|
||||
def self.attribute_map
|
||||
{
|
||||
:id => :id,
|
||||
:pet_id => :petId,
|
||||
:quantity => :quantity,
|
||||
:status => :status,
|
||||
:ship_date => :shipDate
|
||||
:id => :'id',
|
||||
:petId => :'petId',
|
||||
:quantity => :'quantity',
|
||||
:shipDate => :'shipDate',
|
||||
:status => :'status',
|
||||
:complete => :'complete'
|
||||
|
||||
}
|
||||
end
|
||||
@ -16,22 +17,30 @@ class Order
|
||||
def initialize(attributes = {})
|
||||
return if attributes.empty?
|
||||
# Morph attribute keys into undescored rubyish style
|
||||
|
||||
if self.class.attribute_map[:"id"]
|
||||
@id = attributes["id"]
|
||||
end
|
||||
if self.class.attribute_map[:"pet_id"]
|
||||
@pet_id = attributes["petId"]
|
||||
|
||||
if self.class.attribute_map[:"petId"]
|
||||
@petId = attributes["petId"]
|
||||
end
|
||||
|
||||
if self.class.attribute_map[:"quantity"]
|
||||
@quantity = attributes["quantity"]
|
||||
end
|
||||
|
||||
if self.class.attribute_map[:"shipDate"]
|
||||
@shipDate = attributes["shipDate"]
|
||||
end
|
||||
|
||||
if self.class.attribute_map[:"status"]
|
||||
@status = attributes["status"]
|
||||
end
|
||||
if self.class.attribute_map[:"ship_date"]
|
||||
@ship_date = attributes["shipDate"]
|
||||
end
|
||||
|
||||
if self.class.attribute_map[:"complete"]
|
||||
@complete = attributes["complete"]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -43,4 +52,3 @@ class Order
|
||||
body
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
class Pet
|
||||
attr_accessor :id, :category, :name, :photo_urls, :tags, :status
|
||||
|
||||
class Pet
|
||||
attr_accessor :id, :category, :name, :photoUrls, :tags, :status
|
||||
# :internal => :external
|
||||
def self.attribute_map
|
||||
{
|
||||
:id => :id,
|
||||
:category => :category,
|
||||
:name => :name,
|
||||
:photo_urls => :photoUrls,
|
||||
:tags => :tags,
|
||||
:status => :status
|
||||
:id => :'id',
|
||||
:category => :'category',
|
||||
:name => :'name',
|
||||
:photoUrls => :'photoUrls',
|
||||
:tags => :'tags',
|
||||
:status => :'status'
|
||||
|
||||
}
|
||||
end
|
||||
@ -17,28 +17,35 @@ class Pet
|
||||
def initialize(attributes = {})
|
||||
return if attributes.empty?
|
||||
# Morph attribute keys into undescored rubyish style
|
||||
|
||||
if self.class.attribute_map[:"id"]
|
||||
@id = attributes["id"]
|
||||
end
|
||||
|
||||
if self.class.attribute_map[:"category"]
|
||||
@category = attributes["category"]
|
||||
end
|
||||
|
||||
if self.class.attribute_map[:"name"]
|
||||
@name = attributes["name"]
|
||||
end
|
||||
if self.class.attribute_map[:"photo_urls"]
|
||||
|
||||
if self.class.attribute_map[:"photoUrls"]
|
||||
if (value = attributes["photoUrls"]).is_a?(Array)
|
||||
@photo_urls = valueend
|
||||
@photoUrls = value
|
||||
end
|
||||
end
|
||||
|
||||
if self.class.attribute_map[:"tags"]
|
||||
if (value = attributes["tags"]).is_a?(Array)
|
||||
@tags = value.map{ |v| Tag.new(v) }end
|
||||
@tags = value.map{ |v| Tag.new(v) }
|
||||
end
|
||||
end
|
||||
|
||||
if self.class.attribute_map[:"status"]
|
||||
@status = attributes["status"]
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
def to_body
|
||||
@ -49,4 +56,3 @@ class Pet
|
||||
body
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
|
||||
class Tag
|
||||
attr_accessor :id, :name
|
||||
|
||||
# :internal => :external
|
||||
def self.attribute_map
|
||||
{
|
||||
:id => :id,
|
||||
:name => :name
|
||||
:id => :'id',
|
||||
:name => :'name'
|
||||
|
||||
}
|
||||
end
|
||||
@ -13,14 +13,15 @@ class Tag
|
||||
def initialize(attributes = {})
|
||||
return if attributes.empty?
|
||||
# Morph attribute keys into undescored rubyish style
|
||||
|
||||
if self.class.attribute_map[:"id"]
|
||||
@id = attributes["id"]
|
||||
end
|
||||
|
||||
if self.class.attribute_map[:"name"]
|
||||
@name = attributes["name"]
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
def to_body
|
||||
@ -31,4 +32,3 @@ class Tag
|
||||
body
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,17 +1,17 @@
|
||||
class User
|
||||
attr_accessor :id, :first_name, :username, :last_name, :email, :password, :phone, :user_status
|
||||
|
||||
class User
|
||||
attr_accessor :id, :username, :firstName, :lastName, :email, :password, :phone, :userStatus
|
||||
# :internal => :external
|
||||
def self.attribute_map
|
||||
{
|
||||
:id => :id,
|
||||
:first_name => :firstName,
|
||||
:username => :username,
|
||||
:last_name => :lastName,
|
||||
:email => :email,
|
||||
:password => :password,
|
||||
:phone => :phone,
|
||||
:user_status => :userStatus
|
||||
:id => :'id',
|
||||
:username => :'username',
|
||||
:firstName => :'firstName',
|
||||
:lastName => :'lastName',
|
||||
:email => :'email',
|
||||
:password => :'password',
|
||||
:phone => :'phone',
|
||||
:userStatus => :'userStatus'
|
||||
|
||||
}
|
||||
end
|
||||
@ -19,31 +19,38 @@ class User
|
||||
def initialize(attributes = {})
|
||||
return if attributes.empty?
|
||||
# Morph attribute keys into undescored rubyish style
|
||||
|
||||
if self.class.attribute_map[:"id"]
|
||||
@id = attributes["id"]
|
||||
end
|
||||
if self.class.attribute_map[:"first_name"]
|
||||
@first_name = attributes["firstName"]
|
||||
end
|
||||
|
||||
if self.class.attribute_map[:"username"]
|
||||
@username = attributes["username"]
|
||||
end
|
||||
if self.class.attribute_map[:"last_name"]
|
||||
@last_name = attributes["lastName"]
|
||||
|
||||
if self.class.attribute_map[:"firstName"]
|
||||
@firstName = attributes["firstName"]
|
||||
end
|
||||
|
||||
if self.class.attribute_map[:"lastName"]
|
||||
@lastName = attributes["lastName"]
|
||||
end
|
||||
|
||||
if self.class.attribute_map[:"email"]
|
||||
@email = attributes["email"]
|
||||
end
|
||||
|
||||
if self.class.attribute_map[:"password"]
|
||||
@password = attributes["password"]
|
||||
end
|
||||
|
||||
if self.class.attribute_map[:"phone"]
|
||||
@phone = attributes["phone"]
|
||||
end
|
||||
if self.class.attribute_map[:"user_status"]
|
||||
@user_status = attributes["userStatus"]
|
||||
end
|
||||
|
||||
if self.class.attribute_map[:"userStatus"]
|
||||
@userStatus = attributes["userStatus"]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -55,4 +62,3 @@ class User
|
||||
body
|
||||
end
|
||||
end
|
||||
|
||||
|
22
samples/client/petstore/ruby/swagger/configuration.rb
Normal file
22
samples/client/petstore/ruby/swagger/configuration.rb
Normal file
@ -0,0 +1,22 @@
|
||||
module Swagger
|
||||
|
||||
class Configuration
|
||||
require 'swagger/version'
|
||||
|
||||
attr_accessor :format, :api_key, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params
|
||||
|
||||
# Defaults go in here..
|
||||
def initialize
|
||||
@format = 'json'
|
||||
@scheme = 'http'
|
||||
@host = 'api.wordnik.com'
|
||||
@base_path = '/v4'
|
||||
@user_agent = "ruby-#{Swagger::VERSION}"
|
||||
@inject_format = true
|
||||
@force_ending_format = false
|
||||
@camelize_params = true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
199
samples/client/petstore/ruby/swagger/request.rb
Normal file
199
samples/client/petstore/ruby/swagger/request.rb
Normal file
@ -0,0 +1,199 @@
|
||||
module Swagger
|
||||
|
||||
class Request
|
||||
require 'uri'
|
||||
require 'addressable/uri'
|
||||
require 'typhoeus'
|
||||
require "swagger/version"
|
||||
|
||||
attr_accessor :host, :path, :format, :params, :body, :http_method, :headers
|
||||
|
||||
|
||||
# All requests must have an HTTP method and a path
|
||||
# Optionals parameters are :params, :headers, :body, :format, :host
|
||||
#
|
||||
def initialize(http_method, path, attributes={})
|
||||
attributes[:format] ||= Swagger.configuration.format
|
||||
attributes[:params] ||= {}
|
||||
|
||||
# Set default headers
|
||||
default_headers = {
|
||||
'Content-Type' => "application/#{attributes[:format].downcase}",
|
||||
:api_key => Swagger.configuration.api_key
|
||||
}
|
||||
|
||||
# api_key from headers hash trumps the default, even if its value is blank
|
||||
if attributes[:headers].present? && attributes[:headers].has_key?(:api_key)
|
||||
default_headers.delete(:api_key)
|
||||
end
|
||||
|
||||
# api_key from params hash trumps all others (headers and default_headers)
|
||||
if attributes[:params].present? && attributes[:params].has_key?(:api_key)
|
||||
default_headers.delete(:api_key)
|
||||
attributes[:headers].delete(:api_key) if attributes[:headers].present?
|
||||
end
|
||||
|
||||
# Merge argument headers into defaults
|
||||
attributes[:headers] = default_headers.merge(attributes[:headers] || {})
|
||||
|
||||
# Stick in the auth token if there is one
|
||||
if Swagger.authenticated?
|
||||
attributes[:headers].merge!({:auth_token => Swagger.configuration.auth_token})
|
||||
end
|
||||
|
||||
self.http_method = http_method.to_sym
|
||||
self.path = path
|
||||
attributes.each do |name, value|
|
||||
send("#{name.to_s.underscore.to_sym}=", value)
|
||||
end
|
||||
end
|
||||
|
||||
# Construct a base URL
|
||||
#
|
||||
def url(options = {})
|
||||
u = Addressable::URI.new(
|
||||
:scheme => Swagger.configuration.scheme,
|
||||
:host => Swagger.configuration.host,
|
||||
:path => self.interpreted_path,
|
||||
:query => self.query_string.sub(/\?/, '')
|
||||
).to_s
|
||||
|
||||
# Drop trailing question mark, if present
|
||||
u.sub! /\?$/, ''
|
||||
|
||||
# Obfuscate API key?
|
||||
u.sub! /api\_key=\w+/, 'api_key=YOUR_API_KEY' if options[:obfuscated]
|
||||
|
||||
u
|
||||
end
|
||||
|
||||
# Iterate over the params hash, injecting any path values into the path string
|
||||
#
|
||||
# e.g. /word.{format}/{word}/entries => /word.json/cat/entries
|
||||
def interpreted_path
|
||||
p = self.path.dup
|
||||
|
||||
# Fill in the path params
|
||||
self.params.each_pair do |key, value|
|
||||
p = p.gsub("{#{key}}", value.to_s)
|
||||
end
|
||||
|
||||
# Stick a .{format} placeholder into the path if there isn't
|
||||
# one already or an actual format like json or xml
|
||||
# e.g. /words/blah => /words.{format}/blah
|
||||
if Swagger.configuration.inject_format
|
||||
unless ['.json', '.xml', '{format}'].any? {|s| p.downcase.include? s }
|
||||
p = p.sub(/^(\/?\w+)/, "\\1.#{format}")
|
||||
end
|
||||
end
|
||||
|
||||
# Stick a .{format} placeholder on the end of the path if there isn't
|
||||
# one already or an actual format like json or xml
|
||||
# e.g. /words/blah => /words/blah.{format}
|
||||
if Swagger.configuration.force_ending_format
|
||||
unless ['.json', '.xml', '{format}'].any? {|s| p.downcase.include? s }
|
||||
p = "#{p}.#{format}"
|
||||
end
|
||||
end
|
||||
|
||||
p = p.sub("{format}", self.format.to_s)
|
||||
|
||||
URI.encode [Swagger.configuration.base_path, p].join("/").gsub(/\/+/, '/')
|
||||
end
|
||||
|
||||
# Massage the request body into a state of readiness
|
||||
# If body is a hash, camelize all keys then convert to a json string
|
||||
#
|
||||
def body=(value)
|
||||
if value.is_a?(Hash)
|
||||
value = value.inject({}) do |memo, (k,v)|
|
||||
memo[k.to_s.camelize(:lower).to_sym] = v
|
||||
memo
|
||||
end
|
||||
end
|
||||
@body = value
|
||||
end
|
||||
|
||||
# If body is an object, JSONify it before making the actual request.
|
||||
#
|
||||
def outgoing_body
|
||||
body.is_a?(String) ? body : body.to_json
|
||||
end
|
||||
|
||||
# Construct a query string from the query-string-type params
|
||||
def query_string
|
||||
|
||||
# Iterate over all params,
|
||||
# .. removing the ones that are part of the path itself.
|
||||
# .. stringifying values so Addressable doesn't blow up.
|
||||
query_values = {}
|
||||
self.params.each_pair do |key, value|
|
||||
next if self.path.include? "{#{key}}" # skip path params
|
||||
next if value.blank? && value.class != FalseClass # skip empties
|
||||
if Swagger.configuration.camelize_params
|
||||
key = key.to_s.camelize(:lower).to_sym unless key.to_sym == :api_key # api_key is not a camelCased param
|
||||
end
|
||||
query_values[key] = value.to_s
|
||||
end
|
||||
|
||||
# We don't want to end up with '?' as our query string
|
||||
# if there aren't really any params
|
||||
return "" if query_values.blank?
|
||||
|
||||
# Addressable requires query_values to be set after initialization..
|
||||
qs = Addressable::URI.new
|
||||
qs.query_values = query_values
|
||||
qs.to_s
|
||||
end
|
||||
|
||||
def make
|
||||
logger = Logger.new STDOUT
|
||||
logger.debug self.url
|
||||
response = case self.http_method.to_sym
|
||||
when :get,:GET
|
||||
Typhoeus::Request.get(
|
||||
self.url,
|
||||
:headers => self.headers.stringify_keys,
|
||||
)
|
||||
|
||||
when :post,:POST
|
||||
Typhoeus::Request.post(
|
||||
self.url,
|
||||
:body => self.outgoing_body,
|
||||
:headers => self.headers.stringify_keys,
|
||||
)
|
||||
|
||||
when :put,:PUT
|
||||
Typhoeus::Request.put(
|
||||
self.url,
|
||||
:body => self.outgoing_body,
|
||||
:headers => self.headers.stringify_keys,
|
||||
)
|
||||
|
||||
when :delete,:DELETE
|
||||
Typhoeus::Request.delete(
|
||||
self.url,
|
||||
:body => self.outgoing_body,
|
||||
:headers => self.headers.stringify_keys,
|
||||
)
|
||||
end
|
||||
Response.new(response)
|
||||
end
|
||||
|
||||
def response
|
||||
self.make
|
||||
end
|
||||
|
||||
def response_code_pretty
|
||||
return unless @response.present?
|
||||
@response.code.to_s
|
||||
end
|
||||
|
||||
def response_headers_pretty
|
||||
return unless @response.present?
|
||||
# JSON.pretty_generate(@response.headers).gsub(/\n/, '<br/>') # <- This was for RestClient
|
||||
@response.headers.gsub(/\n/, '<br/>') # <- This is for Typhoeus
|
||||
end
|
||||
|
||||
end
|
||||
end
|
70
samples/client/petstore/ruby/swagger/response.rb
Normal file
70
samples/client/petstore/ruby/swagger/response.rb
Normal file
@ -0,0 +1,70 @@
|
||||
module Swagger
|
||||
|
||||
class Response
|
||||
require 'json'
|
||||
|
||||
attr_accessor :raw
|
||||
|
||||
def initialize(raw)
|
||||
self.raw = raw
|
||||
|
||||
case self.code
|
||||
when 500..510 then raise(ServerError, self.error_message)
|
||||
when 299..426 then raise(ClientError, self.error_message)
|
||||
end
|
||||
end
|
||||
|
||||
def code
|
||||
raw.code
|
||||
end
|
||||
|
||||
# Account for error messages that take different forms...
|
||||
def error_message
|
||||
body['message']
|
||||
rescue
|
||||
body
|
||||
end
|
||||
|
||||
# If body is JSON, parse it
|
||||
# Otherwise return raw string
|
||||
def body
|
||||
JSON.parse raw.body
|
||||
rescue
|
||||
raw.body
|
||||
end
|
||||
|
||||
# `headers_hash` is a Typhoeus-specific extension of Hash,
|
||||
# so simplify it back into a regular old Hash.
|
||||
def headers
|
||||
h = {}
|
||||
raw.headers_hash.each {|k,v| h[k] = v }
|
||||
h
|
||||
end
|
||||
|
||||
# Extract the response format from the header hash
|
||||
# e.g. {'Content-Type' => 'application/json'}
|
||||
def format
|
||||
headers['Content-Type'].split("/").last.downcase
|
||||
end
|
||||
|
||||
def json?
|
||||
format == 'json'
|
||||
end
|
||||
|
||||
def xml?
|
||||
format == 'xml'
|
||||
end
|
||||
|
||||
def pretty_body
|
||||
return unless body.present?
|
||||
case format
|
||||
when 'json' then JSON.pretty_generate(body).gsub(/\n/, '<br/>')
|
||||
end
|
||||
end
|
||||
|
||||
def pretty_headers
|
||||
JSON.pretty_generate(headers).gsub(/\n/, '<br/>')
|
||||
end
|
||||
|
||||
end
|
||||
end
|
4
samples/client/petstore/ruby/swagger/version.rb
Normal file
4
samples/client/petstore/ruby/swagger/version.rb
Normal file
@ -0,0 +1,4 @@
|
||||
module Swagger
|
||||
VERSION = "4.06.08"
|
||||
end
|
||||
|
@ -1,5 +1,6 @@
|
||||
import com.wordnik.petstore.api._
|
||||
import com.wordnik.petstore.model._
|
||||
import io.swagger.client._
|
||||
import io.swagger.client.api._
|
||||
import io.swagger.client.model._
|
||||
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
@ -30,7 +31,7 @@ class PetApiTest extends FlatSpec with Matchers {
|
||||
Category(1, "sold"),
|
||||
"dragon",
|
||||
(for (i <- (1 to 10)) yield "http://foo.com/photo/" + i).toList,
|
||||
(for (i <- (1 to 5)) yield com.wordnik.petstore.model.Tag(i, "tag-" + i)).toList,
|
||||
(for (i <- (1 to 5)) yield io.swagger.client.model.Tag(i, "tag-" + i)).toList,
|
||||
"lost"
|
||||
)
|
||||
|
||||
@ -55,7 +56,7 @@ class PetApiTest extends FlatSpec with Matchers {
|
||||
Category(1, "sold"),
|
||||
"programmer",
|
||||
(for (i <- (1 to 10)) yield "http://foo.com/photo/" + i).toList,
|
||||
(for (i <- (1 to 5)) yield com.wordnik.petstore.model.Tag(i, "tag-" + i)).toList,
|
||||
(for (i <- (1 to 5)) yield io.swagger.client.model.Tag(i, "tag-" + i)).toList,
|
||||
"confused"
|
||||
)
|
||||
|
||||
@ -80,7 +81,7 @@ class PetApiTest extends FlatSpec with Matchers {
|
||||
}
|
||||
|
||||
it should "find pets by status" in {
|
||||
api.findPetsByStatus("available") match {
|
||||
api.findPetsByStatus(List("available")) match {
|
||||
case Some(pets) => {
|
||||
pets.foreach(pet => pet.status should be("available"))
|
||||
}
|
||||
@ -90,7 +91,7 @@ class PetApiTest extends FlatSpec with Matchers {
|
||||
|
||||
it should "find pets by tag" in {
|
||||
println("finding by tags")
|
||||
api.findPetsByTags("tag1,tag2") match {
|
||||
api.findPetsByTags(List("tag1", "tag2")) match {
|
||||
case Some(pets) => {
|
||||
pets.foreach(pet => {
|
||||
val tags = (for (tag <- pet.tags) yield tag.name).toSet
|
||||
|
@ -1,6 +1,6 @@
|
||||
import com.wordnik.client._
|
||||
import com.wordnik.petstore.api._
|
||||
import com.wordnik.petstore.model._
|
||||
import io.swagger.client._
|
||||
import io.swagger.client.api._
|
||||
import io.swagger.client.model._
|
||||
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
@ -30,13 +30,14 @@ class StoreApiTest extends FlatSpec with Matchers {
|
||||
}
|
||||
|
||||
it should "place an order" in {
|
||||
val now = new java.util.Date
|
||||
val now = new org.joda.time.DateTime
|
||||
val order = Order (
|
||||
10,
|
||||
1000,
|
||||
101,
|
||||
"pending",
|
||||
now)
|
||||
petId = 10,
|
||||
id = 1000,
|
||||
quantity = 101,
|
||||
status = "pending",
|
||||
shipDate = now,
|
||||
complete = true)
|
||||
|
||||
api.placeOrder(order)
|
||||
|
||||
@ -45,20 +46,21 @@ class StoreApiTest extends FlatSpec with Matchers {
|
||||
order.id should be(1000)
|
||||
order.petId should be(10)
|
||||
order.quantity should be(101)
|
||||
order.shipDate should be (now)
|
||||
order.shipDate.equals(now) should be (true)
|
||||
}
|
||||
case None =>
|
||||
}
|
||||
}
|
||||
|
||||
it should "delete an order" in {
|
||||
val now = new java.util.Date
|
||||
val now = new org.joda.time.DateTime
|
||||
val order = Order(
|
||||
1001,
|
||||
10,
|
||||
101,
|
||||
"pending",
|
||||
now)
|
||||
id = 1001,
|
||||
petId = 10,
|
||||
quantity = 101,
|
||||
status = "pending",
|
||||
shipDate = now,
|
||||
complete = true)
|
||||
|
||||
api.placeOrder(order)
|
||||
|
||||
@ -67,7 +69,7 @@ class StoreApiTest extends FlatSpec with Matchers {
|
||||
order.id should be(1001)
|
||||
order.petId should be(10)
|
||||
order.quantity should be(101)
|
||||
order.shipDate should be (now)
|
||||
order.shipDate.equals(now) should be (true)
|
||||
}
|
||||
case None =>
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import com.wordnik.petstore.api._
|
||||
import com.wordnik.petstore.model._
|
||||
import io.swagger.client._
|
||||
import io.swagger.client.api._
|
||||
import io.swagger.client.model._
|
||||
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user