Merge branch 'develop_2.0' into ruby-auth

This commit is contained in:
xhh
2015-06-03 11:19:40 +08:00
42 changed files with 2094 additions and 29 deletions

View File

@@ -0,0 +1,23 @@
package com.wordnik.swagger.codegen;
public class CliOption {
private final String opt;
private String description;
public CliOption(String opt, String description) {
this.opt = opt;
this.description = description;
}
public String getOpt() {
return opt;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

View File

@@ -140,4 +140,4 @@ public class Codegen extends DefaultGenerator {
}
}
}
}
}

View File

@@ -27,6 +27,7 @@ public interface CodegenConfig {
String getTypeDeclaration(Property p);
String getTypeDeclaration(String name);
void processOpts();
List<CliOption> cliOptions();
String generateExamplePath(String path, Operation operation);
Set<String> reservedWords();

View File

@@ -7,7 +7,7 @@ import java.util.*;
public class CodegenOperation {
public Boolean hasConsumes, hasProduces, hasParams, returnTypeIsPrimitive,
returnSimpleType, subresourceOperation, isMapContainer, isListContainer,
hasMore = Boolean.TRUE;
hasMore = Boolean.TRUE, isMultipart;
public String path, operationId, returnType, httpMethod, returnBaseType,
returnContainer, summary, notes, baseName, defaultResponse;

View File

@@ -77,11 +77,24 @@ public class DefaultCodegen {
protected String templateDir;
protected Map<String, Object> additionalProperties = new HashMap<String, Object>();
protected List<SupportingFile> supportingFiles = new ArrayList<SupportingFile>();
protected List<CliOption> cliOptions = new ArrayList<CliOption>();
public List<CliOption> cliOptions() {
return cliOptions;
}
public void processOpts(){
if(additionalProperties.containsKey("templateDir")) {
this.setTemplateDir((String)additionalProperties.get("templateDir"));
}
if(additionalProperties.containsKey("modelPackage")) {
this.setModelPackage((String)additionalProperties.get("modelPackage"));
}
if(additionalProperties.containsKey("apiPackage")) {
this.setApiPackage((String)additionalProperties.get("apiPackage"));
}
}
// override with any special post-processing
@@ -178,6 +191,14 @@ public class DefaultCodegen {
this.templateDir = templateDir;
}
public void setModelPackage(String modelPackage) {
this.modelPackage = modelPackage;
}
public void setApiPackage(String apiPackage) {
this.apiPackage = apiPackage;
}
public String toApiFilename(String name) {
return toApiName(name);
}
@@ -281,6 +302,9 @@ public class DefaultCodegen {
importMapping.put("LocalDateTime", "org.joda.time.*");
importMapping.put("LocalDate", "org.joda.time.*");
importMapping.put("LocalTime", "org.joda.time.*");
cliOptions.add(new CliOption("modelPackage", "package for generated models"));
cliOptions.add(new CliOption("apiPackage", "package for generated api classes"));
}

View File

@@ -45,19 +45,6 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
"native", "super", "while")
);
additionalProperties.put("invokerPackage", invokerPackage);
additionalProperties.put("groupId", groupId);
additionalProperties.put("artifactId", artifactId);
additionalProperties.put("artifactVersion", artifactVersion);
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("apiInvoker.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiInvoker.java"));
supportingFiles.add(new SupportingFile("JsonUtil.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "JsonUtil.java"));
supportingFiles.add(new SupportingFile("apiException.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiException.java"));
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"String",
@@ -71,8 +58,65 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
);
instantiationTypes.put("array", "ArrayList");
instantiationTypes.put("map", "HashMap");
cliOptions.add(new CliOption("invokerPackage", "root package for generated code"));
cliOptions.add(new CliOption("groupId", "groupId in generated pom.xml"));
cliOptions.add(new CliOption("artifactId", "artifactId in generated pom.xml"));
cliOptions.add(new CliOption("artifactVersion", "artifact version in generated pom.xml"));
cliOptions.add(new CliOption("sourceFolder", "source folder for generated code"));
}
@Override
public void processOpts() {
super.processOpts();
if(additionalProperties.containsKey("invokerPackage")) {
this.setInvokerPackage((String)additionalProperties.get("invokerPackage"));
}
else{
//not set, use default to be passed to template
additionalProperties.put("invokerPackage", invokerPackage);
}
if(additionalProperties.containsKey("groupId")) {
this.setGroupId((String)additionalProperties.get("groupId"));
}
else{
//not set, use to be passed to template
additionalProperties.put("groupId", groupId);
}
if(additionalProperties.containsKey("artifactId")) {
this.setArtifactId((String)additionalProperties.get("artifactId"));
}
else{
//not set, use to be passed to template
additionalProperties.put("artifactId", artifactId);
}
if(additionalProperties.containsKey("artifactVersion")) {
this.setArtifactVersion((String)additionalProperties.get("artifactVersion"));
}
else{
//not set, use to be passed to template
additionalProperties.put("artifactVersion", artifactVersion);
}
if(additionalProperties.containsKey("sourceFolder")) {
this.setSourceFolder((String)additionalProperties.get("sourceFolder"));
}
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("apiInvoker.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiInvoker.java"));
supportingFiles.add(new SupportingFile("JsonUtil.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "JsonUtil.java"));
supportingFiles.add(new SupportingFile("apiException.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiException.java"));
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
@@ -169,5 +213,23 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
return camelize(operationId, true);
}
public void setInvokerPackage(String invokerPackage) {
this.invokerPackage = invokerPackage;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public void setArtifactId(String artifactId) {
this.artifactId = artifactId;
}
public void setArtifactVersion(String artifactVersion) {
this.artifactVersion = artifactVersion;
}
public void setSourceFolder(String sourceFolder) {
this.sourceFolder = sourceFolder;
}
}

View File

@@ -1,6 +1,5 @@
package com.wordnik.swagger.codegen.languages;
import com.wordnik.swagger.util.Json;
import com.wordnik.swagger.codegen.*;
import com.wordnik.swagger.models.properties.*;
@@ -10,7 +9,8 @@ import java.io.File;
public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
protected Set<String> foundationClasses = new HashSet<String>();
protected String sourceFolder = "client";
protected static String PREFIX = "SWG";
protected String classPrefix = "SWG";
protected String projectName = "swaggerClient";
public CodegenType getTag() {
return CodegenType.CLIENT;
@@ -34,12 +34,6 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
templateDir = "objc";
modelPackage = "";
String appName = System.getProperty("appName");
if(appName == null) {
appName = "swaggerClient";
}
additionalProperties.put("projectName", appName);
defaultIncludes = new HashSet<String>(
Arrays.asList(
"bool",
@@ -111,7 +105,31 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
instantiationTypes.put("array", "NSMutableArray");
instantiationTypes.put("map", "NSMutableDictionary");
cliOptions.add(new CliOption("classPrefix", "prefix for generated classes"));
cliOptions.add(new CliOption("sourceFolder", "source folder for generated code"));
cliOptions.add(new CliOption("projectName", "name of the Xcode project in generated Podfile"));
}
@Override
public void processOpts() {
super.processOpts();
if(additionalProperties.containsKey("sourceFolder")) {
this.setSourceFolder((String)additionalProperties.get("sourceFolder"));
}
if(additionalProperties.containsKey("classPrefix")) {
this.setClassPrefix((String)additionalProperties.get("classPrefix"));
}
if(additionalProperties.containsKey("projectName")) {
this.setProjectName((String)additionalProperties.get("projectName"));
}
else{
additionalProperties.put("projectName", projectName);
}
supportingFiles.add(new SupportingFile("SWGObject.h", sourceFolder, "SWGObject.h"));
supportingFiles.add(new SupportingFile("SWGObject.m", sourceFolder, "SWGObject.m"));
supportingFiles.add(new SupportingFile("SWGQueryParamCollection.h", sourceFolder, "SWGQueryParamCollection.h"));
@@ -220,7 +238,7 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
}
// custom classes
else {
return PREFIX + camelize(type);
return classPrefix + camelize(type);
}
}
@@ -266,11 +284,11 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String toApiName(String name) {
return PREFIX + camelize(name) + "Api";
return classPrefix + camelize(name) + "Api";
}
public String toApiFilename(String name) {
return PREFIX + camelize(name) + "Api";
return classPrefix + camelize(name) + "Api";
}
@Override
@@ -313,4 +331,15 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
return camelize(operationId, true);
}
public void setSourceFolder(String sourceFolder) {
this.sourceFolder = sourceFolder;
}
public void setClassPrefix(String classPrefix) {
this.classPrefix = classPrefix;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
}

View File

@@ -0,0 +1,190 @@
package com.wordnik.swagger.codegen.languages;
import com.wordnik.swagger.codegen.*;
import com.wordnik.swagger.models.Operation;
import com.wordnik.swagger.models.properties.*;
import java.util.*;
import java.io.File;
public class RetrofitClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client";
protected String groupId = "io.swagger";
protected String artifactId = "swagger-java-client";
protected String artifactVersion = "1.0.0";
protected String sourceFolder = "src/main/java";
public CodegenType getTag() {
return CodegenType.CLIENT;
}
public String getName() {
return "retrofit";
}
public String getHelp() {
return "Generates a Retrofit client library.";
}
public RetrofitClientCodegen() {
super();
outputFolder = "generated-code/java";
modelTemplateFiles.put("model.mustache", ".java");
apiTemplateFiles.put("api.mustache", ".java");
templateDir = "retrofit";
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);
additionalProperties.put("artifactVersion", artifactVersion);
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("service.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ServiceGenerator.java"));
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"String",
"boolean",
"Boolean",
"Double",
"Integer",
"Long",
"Float",
"Object")
);
instantiationTypes.put("array", "ArrayList");
instantiationTypes.put("map", "HashMap");
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
}
@Override
public String apiFileFolder() {
return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', File.separatorChar);
}
public String modelFileFolder() {
return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar);
}
@Override
public String toVarName(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_");
// if it's all uppper case, do nothing
if (name.matches("^[A-Z_]*$"))
return name;
// camelize (lower first character) the variable name
// pet_id => petId
name = camelize(name, true);
// for reserved word or word starting with number, append _
if(reservedWords.contains(name) || name.matches("^\\d.*"))
name = escapeReservedWord(name);
return name;
}
@Override
public String toParamName(String name) {
// should be the same as variable name
return toVarName(name);
}
@Override
public String toModelName(String name) {
// model name cannot use reserved keyword, e.g. return
if(reservedWords.contains(name))
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
// camelize the model name
// phone_number => PhoneNumber
return camelize(name);
}
@Override
public String toModelFilename(String name) {
// should be the same as the model name
return toModelName(name);
}
@Override
public String getTypeDeclaration(Property p) {
if(p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return getSwaggerType(p) + "<" + getTypeDeclaration(inner) + ">";
}
else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return getSwaggerType(p) + "<String, " + getTypeDeclaration(inner) + ">";
}
return super.getTypeDeclaration(p);
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
String type = null;
if(typeMapping.containsKey(swaggerType)) {
type = typeMapping.get(swaggerType);
if(languageSpecificPrimitives.contains(type))
return toModelName(type);
}
else
type = swaggerType;
return toModelName(type);
}
@Override
public String toOperationId(String operationId) {
// method name cannot use reserved keyword, e.g. return
if(reservedWords.contains(operationId))
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
return camelize(operationId, true);
}
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
Map<String, Object> operations = (Map<String, Object>)objs.get("operations");
if(operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for(CodegenOperation operation : ops) {
if (operation.hasConsumes == Boolean.TRUE) {
Map<String, String> firstType = operation.consumes.get(0);
if (firstType != null) {
if ("multipart/form-data".equals(firstType.get("mediaType"))) {
operation.isMultipart = Boolean.TRUE;
}
}
}
if(operation.returnType == null) {
operation.returnType = "Void";
}
}
}
return objs;
}
}

View File

@@ -0,0 +1,33 @@
package config;
import com.google.common.collect.ImmutableMap;
import java.util.HashMap;
import java.util.Map;
public class Config {
private Map<String, String> options;
public Config() {
this.options = new HashMap<String, String>();
}
public Config(Map<String, String> properties) {
this.options = properties;
}
public Map<String, String> getOptions() {
return ImmutableMap.copyOf(options);
}
public boolean hasOption(String opt){
return options.containsKey(opt);
}
public String getOption(String opt){
return options.get(opt);
}
public void setOption(String opt, String value){
options.put(opt, value);
}
}

View File

@@ -0,0 +1,41 @@
package config;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.util.Iterator;
import java.util.Map;
public class ConfigParser {
public static Config read(String location) {
System.out.println("reading config from " + location);
ObjectMapper mapper = new ObjectMapper();
Config config = new Config();
try {
JsonNode rootNode = mapper.readTree(new File(location));
Iterator<Map.Entry<String, JsonNode>> optionNodes = rootNode.fields();
while (optionNodes.hasNext()) {
Map.Entry<String, JsonNode> optionNode = (Map.Entry<String, JsonNode>) optionNodes.next();
if(optionNode.getValue().isValueNode()){
config.setOption(optionNode.getKey(), optionNode.getValue().asText());
}
else{
System.out.println("omitting non-value node " + optionNode.getKey());
}
}
}
catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
return config;
}
}