Merge remote-tracking branch 'origin' into sync_master_230

This commit is contained in:
wing328
2017-02-10 23:31:36 +08:00
1480 changed files with 60531 additions and 12438 deletions

View File

@@ -56,7 +56,7 @@ public abstract class AbstractGenerator {
if (is == null) {
is = new FileInputStream(new File(name)); // May throw but never return a null value
}
return new InputStreamReader(is);
return new InputStreamReader(is, "UTF-8");
} catch (Exception e) {
LOGGER.error(e.getMessage());
}

View File

@@ -25,9 +25,9 @@ import io.swagger.parser.SwaggerParser;
*/
@Deprecated
public class Codegen extends DefaultGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(Codegen.class);
static Map<String, CodegenConfig> configs = new HashMap<String, CodegenConfig>();
static String configString;
static String debugInfoOptions = "\nThe following additional debug options are available for all codegen targets:" +

View File

@@ -14,7 +14,7 @@ import com.samskivert.mustache.Mustache.Compiler;
public interface CodegenConfig {
CodegenType getTag();
String getName();
String getHelp();
@@ -118,6 +118,8 @@ public interface CodegenConfig {
Map<String, String> modelDocTemplateFiles();
Set<String> languageSpecificPrimitives();
Map<String, String> reservedWordsMappings();
void preprocessSwagger(Swagger swagger);
@@ -197,4 +199,8 @@ public interface CodegenConfig {
String getHttpUserAgent();
String getCommonTemplateDir();
void setIgnoreFilePathOverride(String ignoreFileOverride);
String getIgnoreFilePathOverride();
}

View File

@@ -12,6 +12,8 @@ public class CodegenConstants {
public static final String TEMPLATE_DIR = "templateDir";
public static final String ALLOW_UNICODE_IDENTIFIERS = "allowUnicodeIdentifiers";
public static final String ALLOW_UNICODE_IDENTIFIERS_DESC = "boolean, toggles whether unicode identifiers are allowed in names or not, default is false";
public static final String INVOKER_PACKAGE = "invokerPackage";
public static final String INVOKER_PACKAGE_DESC = "root package for generated code";
@@ -19,6 +21,12 @@ public class CodegenConstants {
public static final String PHP_INVOKER_PACKAGE = "phpInvokerPackage";
public static final String PHP_INVOKER_PACKAGE_DESC = "root package for generated php code";
public static final String PERL_MODULE_NAME = "perlModuleName";
public static final String PERL_MODULE_NAME_DESC = "root module name for generated perl code";
public static final String PYTHON_PACKAGE_NAME = "pythonPackageName";
public static final String PYTHON_PACKAGE_NAME_DESC = "package name for generated python code";
public static final String GROUP_ID = "groupId";
public static final String GROUP_ID_DESC = "groupId in generated pom.xml";
@@ -28,6 +36,33 @@ public class CodegenConstants {
public static final String ARTIFACT_VERSION = "artifactVersion";
public static final String ARTIFACT_VERSION_DESC = "artifact version in generated pom.xml";
public static final String ARTIFACT_URL = "artifactUrl";
public static final String ARTIFACT_URL_DESC = "artifact URL in generated pom.xml";
public static final String ARTIFACT_DESCRIPTION = "artifactDescription";
public static final String ARTIFACT_DESCRIPTION_DESC = "artifact description in generated pom.xml";
public static final String SCM_CONNECTION = "scmConnection";
public static final String SCM_CONNECTION_DESC = "SCM connection in generated pom.xml";
public static final String SCM_DEVELOPER_CONNECTION = "scmDeveloperConnection";
public static final String SCM_DEVELOPER_CONNECTION_DESC = "SCM developer connection in generated pom.xml";
public static final String SCM_URL = "scmUrl";
public static final String SCM_URL_DESC = "SCM URL in generated pom.xml";
public static final String DEVELOPER_NAME = "developerName";
public static final String DEVELOPER_NAME_DESC = "developer name in generated pom.xml";
public static final String DEVELOPER_EMAIL = "developerEmail";
public static final String DEVELOPER_EMAIL_DESC = "developer email in generated pom.xml";
public static final String DEVELOPER_ORGANIZATION = "developerOrganization";
public static final String DEVELOPER_ORGANIZATION_DESC = "developer organization in generated pom.xml";
public static final String DEVELOPER_ORGANIZATION_URL = "developerOrganizationUrl";
public static final String DEVELOPER_ORGANIZATION_URL_DESC = "developer organization URL in generated pom.xml";
public static final String LICENSE_NAME = "licenseName";
public static final String LICENSE_NAME_DESC = "The name of the license";
@@ -86,6 +121,9 @@ public class CodegenConstants {
public static final String USE_COLLECTION = "useCollection";
public static final String USE_COLLECTION_DESC = "Deserialize array types to Collection<T> instead of List<T>.";
public static final String INTERFACE_PREFIX = "interfacePrefix";
public static final String INTERFACE_PREFIX_DESC = "Prefix interfaces with a community standard or widely accepted prefix.";
public static final String RETURN_ICOLLECTION = "returnICollection";
public static final String RETURN_ICOLLECTION_DESC = "Return ICollection<T> instead of the concrete type.";
@@ -137,8 +175,15 @@ public class CodegenConstants {
public static final String GENERATE_MODEL_TESTS_DESC = "Specifies that model tests are to be generated.";
public static final String HIDE_GENERATION_TIMESTAMP = "hideGenerationTimestamp";
public static final String HIDE_GENERATION_TIMESTAMP_DESC = "Hides the generation timestamp.";
public static final String HIDE_GENERATION_TIMESTAMP_DESC = "Hides the generation timestamp when files are generated.";
public static final String GENERATE_PROPERTY_CHANGED = "generatePropertyChanged";
public static final String GENERATE_PROPERTY_CHANGED_DESC = "Specifies that models support raising property changed events.";
public static final String NON_PUBLIC_API = "nonPublicApi";
public static final String NON_PUBLIC_API_DESC = "Generates code with reduced access modifiers; allows embedding elsewhere without exposing non-public API calls to consumers.";
public static final String IGNORE_FILE_OVERRIDE = "ignoreFileOverride";
public static final String IGNORE_FILE_OVERRIDE_DESC = "Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation.";
}

View File

@@ -90,6 +90,7 @@ public class CodegenParameter {
output.collectionFormat = this.collectionFormat;
output.isCollectionFormatMulti = this.isCollectionFormatMulti;
output.description = this.description;
output.unescapedDescription = this.unescapedDescription;
output.baseType = this.baseType;
output.isFormParam = this.isFormParam;
output.isQueryParam = this.isQueryParam;

View File

@@ -7,9 +7,11 @@ import java.util.Map;
import java.util.Objects;
public class CodegenProperty implements Cloneable {
public String baseName, complexType, getter, setter, description, datatype, datatypeWithEnum,
dataFormat, name, min, max, defaultValue, defaultValueWithParam, baseType, containerType;
public String baseName, complexType, getter, setter, description, datatype,
datatypeWithEnum, dataFormat, name, min, max, defaultValue, defaultValueWithParam,
baseType, containerType, title;
/** The 'description' string without escape charcters needed by some programming languages/targets */
public String unescapedDescription;
/**
@@ -49,7 +51,10 @@ public class CodegenProperty implements Cloneable {
public boolean isInherited;
public String nameInCamelCase; // property name in camel case
// enum name based on the property name, usually use as a prefix (e.g. VAR_NAME) for enum name (e.g. VAR_NAME_VALUE1)
public String enumName;
public String enumName;
public Integer maxItems;
public Integer minItems;
@Override
public String toString() {
@@ -74,6 +79,7 @@ public class CodegenProperty implements Cloneable {
result = prime * result + ((defaultValue == null) ? 0 : defaultValue.hashCode());
result = prime * result + ((defaultValueWithParam == null) ? 0 : defaultValueWithParam.hashCode());
result = prime * result + ((description == null) ? 0 : description.hashCode());
result = prime * result + ((title == null) ? 0 : title.hashCode());
result = prime * result + ((example == null) ? 0 : example.hashCode());
result = prime * result + (exclusiveMaximum ? 13:31);
result = prime * result + (exclusiveMinimum ? 13:31);
@@ -117,6 +123,8 @@ public class CodegenProperty implements Cloneable {
result = prime * result + Objects.hashCode(isInherited);
result = prime * result + Objects.hashCode(nameInCamelCase);
result = prime * result + Objects.hashCode(enumName);
result = prime * result + ((maxItems == null) ? 0 : maxItems.hashCode());
result = prime * result + ((minItems == null) ? 0 : minItems.hashCode());
return result;
}
@@ -144,6 +152,9 @@ public class CodegenProperty implements Cloneable {
if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) {
return false;
}
if ((this.title == null) ? (other.title != null) : !this.title.equals(other.title)) {
return false;
}
if ((this.datatype == null) ? (other.datatype != null) : !this.datatype.equals(other.datatype)) {
return false;
}
@@ -283,6 +294,12 @@ public class CodegenProperty implements Cloneable {
if (!Objects.equals(this.enumName, other.enumName)) {
return false;
}
if (this.maxItems != other.maxItems && (this.maxItems == null || !this.maxItems.equals(other.maxItems))) {
return false;
}
if (this.minItems != other.minItems && (this.minItems == null || !this.minItems.equals(other.minItems))) {
return false;
}
return true;
}
@@ -307,6 +324,6 @@ public class CodegenProperty implements Cloneable {
throw new IllegalStateException(e);
}
}
}

View File

@@ -19,6 +19,7 @@ public class CodegenResponse {
public Boolean isFile = Boolean.FALSE;
public Object schema;
public String jsonSchema;
public Map<String, Object> vendorExtensions;
public boolean isWildcard() {
return "0".equals(code) || "default".equals(code);
@@ -68,6 +69,8 @@ public class CodegenResponse {
return false;
if (schema != null ? !schema.equals(that.schema) : that.schema != null)
return false;
if (vendorExtensions != null ? !vendorExtensions.equals(that.vendorExtensions) : that.vendorExtensions != null)
return false;
return jsonSchema != null ? jsonSchema.equals(that.jsonSchema) : that.jsonSchema == null;
}
@@ -91,6 +94,7 @@ public class CodegenResponse {
result = 31 * result + (isFile != null ? isFile.hashCode() : 0);
result = 31 * result + (schema != null ? schema.hashCode() : 0);
result = 31 * result + (jsonSchema != null ? jsonSchema.hashCode() : 0);
result = 31 * result + (vendorExtensions != null ? vendorExtensions.hashCode() : 0);
return result;
}
}

View File

@@ -92,6 +92,7 @@ public class DefaultCodegen {
protected Map<String, String> modelTestTemplateFiles = new HashMap<String, String>();
protected Map<String, String> apiDocTemplateFiles = new HashMap<String, String>();
protected Map<String, String> modelDocTemplateFiles = new HashMap<String, String>();
protected Map<String, String> reservedWordsMappings = new HashMap<String, String>();
protected String templateDir;
protected String embeddedTemplateDir;
protected String commonTemplateDir = "_common";
@@ -106,6 +107,7 @@ public class DefaultCodegen {
protected String library;
protected Boolean sortParamsByRequiredFlag = true;
protected Boolean ensureUniqueParams = true;
protected Boolean allowUnicodeIdentifiers = false;
protected String gitUserId, gitRepoId, releaseNote;
protected String httpUserAgent;
protected Boolean hideGenerationTimestamp = true;
@@ -114,6 +116,8 @@ public class DefaultCodegen {
// Then translated back during JSON encoding and decoding
protected Map<String, String> specialCharReplacements = new HashMap<String, String>();
protected String ignoreFilePathOverride;
public List<CliOption> cliOptions() {
return cliOptions;
}
@@ -141,6 +145,11 @@ public class DefaultCodegen {
.get(CodegenConstants.ENSURE_UNIQUE_PARAMS).toString()));
}
if (additionalProperties.containsKey(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS)) {
this.setAllowUnicodeIdentifiers(Boolean.valueOf(additionalProperties
.get(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS).toString()));
}
if(additionalProperties.containsKey(CodegenConstants.MODEL_NAME_PREFIX)){
this.setModelNamePrefix((String) additionalProperties.get(CodegenConstants.MODEL_NAME_PREFIX));
}
@@ -148,7 +157,6 @@ public class DefaultCodegen {
if(additionalProperties.containsKey(CodegenConstants.MODEL_NAME_SUFFIX)){
this.setModelNameSuffix((String) additionalProperties.get(CodegenConstants.MODEL_NAME_SUFFIX));
}
}
// override with any special post-processing for all models
@@ -185,12 +193,18 @@ public class DefaultCodegen {
for (String name : allModels.keySet()) {
CodegenModel cm = allModels.get(name);
CodegenModel parent = allModels.get(cm.parent);
// if a discriminator exists on the parent, don't add this child to the inheritance heirarchy
// TODO Determine what to do if the parent discriminator name == the grandparent discriminator name
while (parent != null) {
if (parent.children == null) {
parent.children = new ArrayList<CodegenModel>();
parent.children = new ArrayList<CodegenModel>();
}
parent.children.add(cm);
parent = allModels.get(parent.parent);
if (parent.discriminator == null) {
parent = allModels.get(parent.parent);
} else {
parent = null;
}
}
}
}
@@ -303,6 +317,10 @@ public class DefaultCodegen {
* @return the sanitized variable name for enum
*/
public String toEnumVarName(String value, String datatype) {
if (value.length() == 0) {
return "EMPTY";
}
String var = value.replaceAll("\\W+", "_").toUpperCase();
if (var.matches("\\d.*")) {
return "_" + var;
@@ -346,7 +364,7 @@ public class DefaultCodegen {
// override with any special handling of the JMustache compiler
@SuppressWarnings("unused")
public Compiler processCompiler(Compiler compiler) {
return compiler;
return compiler;
}
// override with any special text escaping logic
@@ -464,6 +482,10 @@ public class DefaultCodegen {
public Map<String, String> modelDocTemplateFiles() {
return modelDocTemplateFiles;
}
public Map<String, String> reservedWordsMappings() {
return reservedWordsMappings;
}
public Map<String, String> apiTestTemplateFiles() {
return apiTestTemplateFiles;
@@ -565,6 +587,10 @@ public class DefaultCodegen {
this.ensureUniqueParams = ensureUniqueParams;
}
public void setAllowUnicodeIdentifiers(Boolean allowUnicodeIdentifiers) {
this.allowUnicodeIdentifiers = allowUnicodeIdentifiers;
}
/**
* Return the regular expression/JSON schema pattern (http://json-schema.org/latest/json-schema-validation.html#anchor33)
*
@@ -819,6 +845,10 @@ public class DefaultCodegen {
cliOptions.add(CliOption.newBoolean(CodegenConstants.ENSURE_UNIQUE_PARAMS, CodegenConstants
.ENSURE_UNIQUE_PARAMS_DESC).defaultValue(Boolean.TRUE.toString()));
//name formatting options
cliOptions.add(CliOption.newBoolean(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS, CodegenConstants
.ALLOW_UNICODE_IDENTIFIERS_DESC).defaultValue(Boolean.FALSE.toString()));
// initialize special character mapping
initalizeSpecialCharacterMapping();
}
@@ -1261,6 +1291,18 @@ public class DefaultCodegen {
allProperties = new LinkedHashMap<String, Property>();
allRequired = new ArrayList<String>();
m.allVars = new ArrayList<CodegenProperty>();
int modelImplCnt = 0; // only one inline object allowed in a ComposedModel
for (Model innerModel: ((ComposedModel)model).getAllOf()) {
if (innerModel instanceof ModelImpl) {
if (m.discriminator == null) {
m.discriminator = ((ModelImpl) innerModel).getDiscriminator();
}
if (modelImplCnt++ > 1) {
LOGGER.warn("More than one inline schema specified in allOf:. Only the first one is recognized. All others are ignored.");
break; // only one ModelImpl with discriminator allowed in allOf
}
}
}
} else {
allProperties = null;
allRequired = null;
@@ -1436,6 +1478,7 @@ public class DefaultCodegen {
property.nameInCamelCase = camelize(property.name, false);
property.description = escapeText(p.getDescription());
property.unescapedDescription = p.getDescription();
property.title = p.getTitle();
property.getter = "get" + getterAndSetterCapitalize(name);
property.setter = "set" + getterAndSetterCapitalize(name);
property.example = toExampleValue(p);
@@ -1680,16 +1723,18 @@ public class DefaultCodegen {
property.baseType = getSwaggerType(p);
if (p instanceof ArrayProperty) {
if (p instanceof ArrayProperty) {
property.isContainer = true;
property.isListContainer = true;
property.containerType = "array";
property.baseType = getSwaggerType(p);
// handle inner property
ArrayProperty ap = (ArrayProperty) p;
property.maxItems = ap.getMaxItems();
property.minItems = ap.getMinItems();
CodegenProperty cp = fromProperty(property.name, ap.getItems());
updatePropertyForArray(property, cp);
} else if (p instanceof MapProperty) {
} else if (p instanceof MapProperty) {
property.isContainer = true;
property.isMapContainer = true;
property.containerType = "map";
@@ -1714,6 +1759,7 @@ public class DefaultCodegen {
LOGGER.warn("skipping invalid array property " + Json.pretty(property));
return;
}
property.dataFormat = innerProperty.dataFormat;
if (!languageSpecificPrimitives.contains(innerProperty.baseType)) {
property.complexType = innerProperty.baseType;
} else {
@@ -1750,6 +1796,7 @@ public class DefaultCodegen {
property.isPrimitiveType = true;
}
property.items = innerProperty;
property.dataFormat = innerProperty.dataFormat;
// inner item is Enum
if (isPropertyInnerMostEnum(property)) {
// isEnum is set to true when the type is an enum
@@ -1876,7 +1923,7 @@ public class DefaultCodegen {
* @return Codegen Operation object
*/
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions) {
return fromOperation(path, httpMethod, operation, definitions, null);
return fromOperation(path, httpMethod, operation, definitions, null);
}
/**
@@ -2184,6 +2231,7 @@ public class DefaultCodegen {
r.schema = response.getSchema();
r.examples = toExamples(response.getExamples());
r.jsonSchema = Json.pretty(response);
r.vendorExtensions = response.getVendorExtensions();
addHeaders(response, r.headers);
if (r.schema != null) {
@@ -2354,7 +2402,7 @@ public class DefaultCodegen {
// validation
// handle maximum, minimum properly for int/long by removing the trailing ".0"
if ("integer".equals(type)) {
if ("integer".equals(qp.getType())) {
p.maximum = qp.getMaximum() == null ? null : String.valueOf(qp.getMaximum().longValue());
p.minimum = qp.getMinimum() == null ? null : String.valueOf(qp.getMinimum().longValue());
} else {
@@ -2531,7 +2579,7 @@ public class DefaultCodegen {
@SuppressWarnings("static-method")
public List<CodegenSecurity> fromSecurity(Map<String, SecuritySchemeDefinition> schemes) {
if (schemes == null) {
return Collections.emptyList();
return Collections.emptyList();
}
List<CodegenSecurity> secs = new ArrayList<CodegenSecurity>(schemes.size());
@@ -2555,8 +2603,8 @@ public class DefaultCodegen {
sec.isKeyInHeader = sec.isKeyInQuery = sec.isApiKey = sec.isOAuth = false;
sec.isBasic = true;
} else {
final OAuth2Definition oauth2Definition = (OAuth2Definition) schemeDefinition;
sec.isKeyInHeader = sec.isKeyInQuery = sec.isApiKey = sec.isBasic = false;
final OAuth2Definition oauth2Definition = (OAuth2Definition) schemeDefinition;
sec.isKeyInHeader = sec.isKeyInQuery = sec.isApiKey = sec.isBasic = false;
sec.isOAuth = true;
sec.flow = oauth2Definition.getFlow();
if (sec.flow == null) {
@@ -3191,11 +3239,11 @@ public class DefaultCodegen {
// encountered so far and hopefully make it easier for others to add more special
// cases in the future.
// better error handling when map/array type is invalid
if (name == null) {
LOGGER.error("String to be sanitized is null. Default to ERROR_UNKNOWN");
return "ERROR_UNKNOWN";
}
// better error handling when map/array type is invalid
if (name == null) {
LOGGER.error("String to be sanitized is null. Default to ERROR_UNKNOWN");
return "ERROR_UNKNOWN";
}
// if the name is just '$', map it to 'value' for the time being.
if ("$".equals(name)) {
@@ -3224,7 +3272,14 @@ public class DefaultCodegen {
// remove everything else other than word, number and _
// $php_variable => php_variable
return name.replaceAll("[^a-zA-Z0-9_]", "");
if (allowUnicodeIdentifiers) { //could be converted to a single line with ?: operator
name = Pattern.compile("\\W", Pattern.UNICODE_CHARACTER_CLASS).matcher(name).replaceAll("");
}
else {
name = name.replaceAll("\\W", "");
}
return name;
}
/**
@@ -3416,11 +3471,44 @@ public class DefaultCodegen {
public boolean convertPropertyToBooleanAndWriteBack(String propertyKey) {
boolean booleanValue = false;
if (additionalProperties.containsKey(propertyKey)) {
booleanValue = Boolean.valueOf(additionalProperties.get(propertyKey).toString());
booleanValue = convertPropertyToBoolean(propertyKey);
// write back as boolean
additionalProperties.put(propertyKey, booleanValue);
writePropertyBack(propertyKey, booleanValue);
}
return booleanValue;
}
/**
* Provides an override location, if any is specified, for the .swagger-codegen-ignore.
*
* This is originally intended for the first generation only.
*
* @return a string of the full path to an override ignore file.
*/
public String getIgnoreFilePathOverride() {
return ignoreFilePathOverride;
}
/**
* Sets an override location for the .swagger-codegen.ignore location for the first code generation.
*
* @param ignoreFileOverride The full path to an ignore file
*/
public void setIgnoreFilePathOverride(final String ignoreFileOverride) {
this.ignoreFilePathOverride = ignoreFileOverride;
}
public boolean convertPropertyToBoolean(String propertyKey) {
boolean booleanValue = false;
if (additionalProperties.containsKey(propertyKey)) {
booleanValue = Boolean.valueOf(additionalProperties.get(propertyKey).toString());
}
return booleanValue;
}
public void writePropertyBack(String propertyKey, boolean value) {
additionalProperties.put(propertyKey, value);
}
}

View File

@@ -42,7 +42,21 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
this.swagger = opts.getSwagger();
this.config = opts.getConfig();
this.config.additionalProperties().putAll(opts.getOpts().getProperties());
ignoreProcessor = new CodegenIgnoreProcessor(this.config.getOutputDir());
String ignoreFileLocation = this.config.getIgnoreFilePathOverride();
if(ignoreFileLocation != null) {
final File ignoreFile = new File(ignoreFileLocation);
if(ignoreFile.exists() && ignoreFile.canRead()) {
this.ignoreProcessor = new CodegenIgnoreProcessor(ignoreFile);
} else {
LOGGER.warn("Ignore file specified at {} is not valid. This will fall back to an existing ignore file if present in the output directory.", ignoreFileLocation);
}
}
if(this.ignoreProcessor == null) {
this.ignoreProcessor = new CodegenIgnoreProcessor(this.config.getOutputDir());
}
return this;
}

View File

@@ -54,12 +54,15 @@ public class CodegenConfigurator {
private String artifactId;
private String artifactVersion;
private String library;
private String ignoreFileOverride;
private Map<String, String> systemProperties = new HashMap<String, String>();
private Map<String, String> instantiationTypes = new HashMap<String, String>();
private Map<String, String> typeMappings = new HashMap<String, String>();
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
private Map<String, String> importMappings = new HashMap<String, String>();
private Set<String> languageSpecificPrimitives = new HashSet<String>();
private Map<String, String> reservedWordMappings = new HashMap<String, String>();
private String gitUserId="GIT_USER_ID";
private String gitRepoId="GIT_REPO_ID";
private String releaseNote="Minor update";
@@ -263,7 +266,7 @@ public class CodegenConfigurator {
this.additionalProperties = additionalProperties;
return this;
}
public CodegenConfigurator addAdditionalProperty(String key, Object value) {
this.additionalProperties.put(key, value);
return this;
@@ -341,7 +344,30 @@ public class CodegenConfigurator {
this.httpUserAgent= httpUserAgent;
return this;
}
public Map<String, String> getReservedWordsMappings() {
return reservedWordMappings;
}
public CodegenConfigurator setReservedWordsMappings(Map<String, String> reservedWordsMappings) {
this.reservedWordMappings = reservedWordsMappings;
return this;
}
public CodegenConfigurator addAdditionalReservedWordMapping(String key, String value) {
this.reservedWordMappings.put(key, value);
return this;
}
public String getIgnoreFileOverride() {
return ignoreFileOverride;
}
public CodegenConfigurator setIgnoreFileOverride(final String ignoreFileOverride) {
this.ignoreFileOverride = ignoreFileOverride;
return this;
}
public ClientOptInput toClientOptInput() {
Validate.notEmpty(lang, "language must be specified");
@@ -355,12 +381,14 @@ public class CodegenConfigurator {
config.setInputSpec(inputSpec);
config.setOutputDir(outputDir);
config.setSkipOverwrite(skipOverwrite);
config.setIgnoreFilePathOverride(ignoreFileOverride);
config.instantiationTypes().putAll(instantiationTypes);
config.typeMapping().putAll(typeMappings);
config.importMapping().putAll(importMappings);
config.languageSpecificPrimitives().addAll(languageSpecificPrimitives);
config.reservedWordsMappings().putAll(reservedWordMappings);
checkAndSetAdditionalProperty(apiPackage, CodegenConstants.API_PACKAGE);
checkAndSetAdditionalProperty(modelPackage, CodegenConstants.MODEL_PACKAGE);
checkAndSetAdditionalProperty(invokerPackage, CodegenConstants.INVOKER_PACKAGE);

View File

@@ -58,6 +58,13 @@ public final class CodegenConfiguratorUtils {
}
}
public static void applyReservedWordsMappingsKvp(String reservedWordMappings, CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(reservedWordMappings);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addAdditionalReservedWordMapping(entry.getKey(), entry.getValue());
}
}
private static Set<String> createSetFromCsvList(String csvProperty) {
final List<String> values = OptionUtils.splitCommaSeparatedList(csvProperty);
return new HashSet<String>(values);
@@ -74,4 +81,6 @@ public final class CodegenConfiguratorUtils {
return result;
}
}

View File

@@ -9,13 +9,22 @@ import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.BooleanProperty;
import io.swagger.models.properties.DateProperty;
import io.swagger.models.properties.DateTimeProperty;
import io.swagger.models.properties.IntegerProperty;
import io.swagger.models.properties.LongProperty;
import io.swagger.models.properties.DecimalProperty;
import io.swagger.models.properties.DoubleProperty;
import io.swagger.models.properties.BaseIntegerProperty;
import io.swagger.models.properties.AbstractNumericProperty;
import io.swagger.models.properties.PasswordProperty;
import io.swagger.models.properties.UUIDProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.RefProperty;
import io.swagger.models.properties.StringProperty;
import org.codehaus.plexus.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -25,6 +34,7 @@ import java.util.Map;
import java.util.Set;
public class XmlExampleGenerator {
protected final Logger LOGGER = LoggerFactory.getLogger(XmlExampleGenerator.class);
public static String NEWLINE = "\n";
public static String TAG_START = "<";
public static String CLOSE_TAG = ">";
@@ -163,45 +173,44 @@ public class XmlExampleGenerator {
return sb.toString();
}
/**
* Get the example string value for the given Property.
*
* If an example value was not provided in the specification, a default will be generated.
*
* @param property Property to get example string for
*
* @return Example String
*/
protected String getExample(Property property) {
if (property instanceof DateTimeProperty) {
if (property.getExample() != null) {
return property.getExample().toString();
} else {
return "2000-01-23T04:56:07.000Z";
}
} else if (property instanceof StringProperty) {
if (property.getExample() != null) {
return property.getExample().toString();
} else {
return "string";
}
if (property.getExample() != null) {
return property.getExample().toString();
} else if (property instanceof DateTimeProperty) {
return "2000-01-23T04:56:07.000Z";
} else if (property instanceof DateProperty) {
if (property.getExample() != null) {
return property.getExample().toString();
} else {
return "2000-01-23";
}
} else if (property instanceof IntegerProperty) {
if (property.getExample() != null) {
return property.getExample().toString();
} else {
return "0";
}
return "2000-01-23";
} else if (property instanceof BooleanProperty) {
if (property.getExample() != null) {
return property.getExample().toString();
} else {
return "true";
}
return "true";
} else if (property instanceof LongProperty) {
if (property.getExample() != null) {
return property.getExample().toString();
} else {
return "123456";
}
return "123456789";
} else if (property instanceof DoubleProperty) { // derived from DecimalProperty so make sure this is first
return "3.149";
} else if (property instanceof DecimalProperty) {
return "1.3579";
} else if (property instanceof PasswordProperty) {
return "********";
} else if (property instanceof UUIDProperty) {
return "046b6c7f-0b8a-43b9-b35d-6489e6daee91";
// do these last in case the specific types above are derived from these classes
} else if (property instanceof StringProperty) {
return "aeiou";
} else if (property instanceof BaseIntegerProperty) {
return "123";
} else if (property instanceof AbstractNumericProperty) {
return "1.23";
}
return "not implemented " + property;
LOGGER.warn("default example value not implemented for " + property);
return "";
}
@SuppressWarnings("static-method")

View File

@@ -8,34 +8,71 @@ import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Presents a processing utility for parsing and evaluating files containing common ignore patterns. (.swagger-codegen-ignore)
*/
public class CodegenIgnoreProcessor {
private static final Logger LOGGER = LoggerFactory.getLogger(CodegenIgnoreProcessor.class);
private final String outputPath;
private File ignoreFile = null;
private List<Rule> exclusionRules = new ArrayList<>();
private List<Rule> inclusionRules = new ArrayList<>();
public CodegenIgnoreProcessor(String outputPath) {
this.outputPath = outputPath;
final File directory = new File(outputPath);
if(directory.exists() && directory.isDirectory()){
final File codegenIgnore = new File(directory, ".swagger-codegen-ignore");
if(codegenIgnore.exists() && codegenIgnore.isFile()){
try {
loadCodegenRules(codegenIgnore);
} catch (IOException e) {
LOGGER.error("Could not process .swagger-codegen-ignore.", e.getMessage());
}
} else {
// log info message
LOGGER.info("No .swagger-codegen-ignore file found.");
}
/**
* Loads the default ignore file (.swagger-codegen-ignore) from the specified path.
*
* @param baseDirectory The base directory of the files to be processed. This contains the ignore file.
*/
public CodegenIgnoreProcessor(final String baseDirectory) {
this(baseDirectory, ".swagger-codegen-ignore");
}
/**
* Loads the specified ignore file by name ([ignoreFile]) from the specified path.
*
* @param baseDirectory The base directory of the files to be processed. This contains the ignore file.
* @param ignoreFile The file containing ignore patterns.
*/
@SuppressWarnings("WeakerAccess")
public CodegenIgnoreProcessor(final String baseDirectory, final String ignoreFile) {
final File directory = new File(baseDirectory);
final File targetIgnoreFile = new File(directory, ignoreFile);
if (directory.exists() && directory.isDirectory()) {
loadFromFile(targetIgnoreFile);
} else {
LOGGER.warn("Directory does not exist, or is inaccessible. No file will be evaluated.");
}
}
void loadCodegenRules(File codegenIgnore) throws IOException {
/**
* Constructs an instance of {@link CodegenIgnoreProcessor} from an ignore file defined by {@code targetIgnoreFile}.
*
* @param targetIgnoreFile The ignore file location.
*/
public CodegenIgnoreProcessor(final File targetIgnoreFile) {
loadFromFile(targetIgnoreFile);
}
private void loadFromFile(File targetIgnoreFile) {
if (targetIgnoreFile.exists() && targetIgnoreFile.isFile()) {
try {
loadCodegenRules(targetIgnoreFile);
this.ignoreFile = targetIgnoreFile;
} catch (IOException e) {
LOGGER.error(String.format("Could not process %s.", targetIgnoreFile.getName()), e.getMessage());
}
} else {
// log info message
LOGGER.info(String.format("No %s file found.", targetIgnoreFile.getName()));
}
}
void loadCodegenRules(final File codegenIgnore) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(codegenIgnore))) {
String line;
@@ -61,8 +98,17 @@ public class CodegenIgnoreProcessor {
}
}
public boolean allowsFile(File targetFile) {
File file = new File(new File(this.outputPath).toURI().relativize(targetFile.toURI()).getPath());
/**
* Determines whether or not a file defined by {@code toEvaluate} is allowed,
* under the exclusion rules from the ignore file being processed.
*
* @param targetFile The file to check against exclusion rules from the ignore file.
* @return {@code false} if file matches any pattern in the ignore file (disallowed), otherwise {@code true} (allowed).
*/
public boolean allowsFile(final File targetFile) {
if(this.ignoreFile == null) return true;
File file = new File(this.ignoreFile.getParentFile().toURI().relativize(targetFile.toURI()).getPath());
Boolean directoryExcluded = false;
Boolean exclude = false;
if(exclusionRules.size() == 0 && inclusionRules.size() == 0) {
@@ -124,10 +170,23 @@ public class CodegenIgnoreProcessor {
return Boolean.FALSE.equals(exclude);
}
/**
* Allows a consumer to manually inspect explicit "inclusion rules". That is, patterns in the ignore file which have been negated.
*
* @return A {@link ImmutableList#copyOf(Collection)} of rules which possibly negate exclusion rules in the ignore file.
*/
public List<Rule> getInclusionRules() {
return ImmutableList.copyOf(inclusionRules);
}
/**
* Allows a consumer to manually inspect all "exclusion rules". That is, patterns in the ignore file which represent
* files and directories to be excluded, unless explicitly overridden by {@link CodegenIgnoreProcessor#getInclusionRules()} rules.
*
* NOTE: Existence in this list doesn't mean a file is excluded. The rule can be overridden by {@link CodegenIgnoreProcessor#getInclusionRules()} rules.
*
* @return A {@link ImmutableList#copyOf(Collection)} of rules which define exclusions by patterns in the ignore file.
*/
public List<Rule> getExclusionRules() {
return ImmutableList.copyOf(exclusionRules);
}

View File

@@ -51,6 +51,8 @@ public abstract class Rule {
* Example: **\/*.bak excludes all backup. Adding !/test.bak will include test.bak in the project root.
* <p>
* NOTE: It is not possible to re-include a file if a parent directory of that file is excluded.
*
* @return {@code true} if the rule is negated (inverse), otherwise {@code false} (normal).
*/
public Boolean getNegated() {
return this.syntax != null && this.syntax.size() > 0 && this.syntax.get(0).getToken() == IgnoreLineParser.Token.NEGATE;

View File

@@ -27,6 +27,8 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
protected String packageCompany = "Swagger";
protected String packageCopyright = "No Copyright";
protected String interfacePrefix = "I";
protected String sourceFolder = "src";
// TODO: Add option for test folder output location. Nice to allow e.g. ./test instead of ./src.
@@ -254,6 +256,19 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES)) {
setOptionalEmitDefaultValue(Boolean.valueOf(additionalProperties.get(CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES).toString()));
}
if (additionalProperties.containsKey(CodegenConstants.INTERFACE_PREFIX)) {
String useInterfacePrefix = additionalProperties.get(CodegenConstants.INTERFACE_PREFIX).toString();
if("false".equals(useInterfacePrefix.toLowerCase())) {
setInterfacePrefix("");
} else if(!"true".equals(useInterfacePrefix.toLowerCase())) {
// NOTE: if user passes "true" explicitly, we use the default I- prefix. The other supported case here is a custom prefix.
setInterfacePrefix(sanitizeName(useInterfacePrefix));
}
}
// This either updates additionalProperties with the above fixes, or sets the default if the option was not specified.
additionalProperties.put(CodegenConstants.INTERFACE_PREFIX, interfacePrefix);
}
@Override
@@ -401,10 +416,13 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
}
return name;
}
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@@ -466,7 +484,13 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
if (p instanceof StringProperty) {
StringProperty dp = (StringProperty) p;
if (dp.getDefault() != null) {
return "\"" + dp.getDefault() + "\"";
String _default = dp.getDefault();
if (dp.getEnum() == null) {
return "\"" + _default + "\"";
} else {
// convert to enum var name later in postProcessModels
return _default;
}
}
} else if (p instanceof BooleanProperty) {
BooleanProperty dp = (BooleanProperty) p;
@@ -613,8 +637,20 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
this.sourceFolder = sourceFolder;
}
public String getInterfacePrefix() {
return interfacePrefix;
}
public void setInterfacePrefix(final String interfacePrefix) {
this.interfacePrefix = interfacePrefix;
}
@Override
public String toEnumVarName(String name, String datatype) {
if (name.length() == 0) {
return "Empty";
}
// for symbol, e.g. $, #
if (getSymbolName(name) != null) {
return camelize(getSymbolName(name));

View File

@@ -52,6 +52,15 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
protected String groupId = "io.swagger";
protected String artifactId = "swagger-java";
protected String artifactVersion = "1.0.0";
protected String artifactUrl = "https://github.com/swagger-api/swagger-codegen";
protected String artifactDescription = "Swagger Java";
protected String developerName = "Swagger";
protected String developerEmail = "apiteam@swagger.io";
protected String developerOrganization = "Swagger";
protected String developerOrganizationUrl = "http://swagger.io";
protected String scmConnection = "scm:git:git@github.com:swagger-api/swagger-codegen.git";
protected String scmDeveloperConnection = "scm:git:git@github.com:swagger-api/swagger-codegen.git";
protected String scmUrl = "https://github.com/swagger-api/swagger-codegen";
protected String licenseName = "Unlicense";
protected String licenseUrl = "http://unlicense.org";
protected String projectFolder = "src" + File.separator + "main";
@@ -118,6 +127,15 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
cliOptions.add(new CliOption(CodegenConstants.GROUP_ID, CodegenConstants.GROUP_ID_DESC));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_ID, CodegenConstants.ARTIFACT_ID_DESC));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_VERSION, CodegenConstants.ARTIFACT_VERSION_DESC));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_URL, CodegenConstants.ARTIFACT_URL_DESC));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_DESCRIPTION, CodegenConstants.ARTIFACT_DESCRIPTION_DESC));
cliOptions.add(new CliOption(CodegenConstants.SCM_CONNECTION, CodegenConstants.SCM_CONNECTION_DESC));
cliOptions.add(new CliOption(CodegenConstants.SCM_DEVELOPER_CONNECTION, CodegenConstants.SCM_DEVELOPER_CONNECTION_DESC));
cliOptions.add(new CliOption(CodegenConstants.SCM_URL, CodegenConstants.SCM_URL_DESC));
cliOptions.add(new CliOption(CodegenConstants.DEVELOPER_NAME, CodegenConstants.DEVELOPER_NAME_DESC));
cliOptions.add(new CliOption(CodegenConstants.DEVELOPER_EMAIL, CodegenConstants.DEVELOPER_EMAIL_DESC));
cliOptions.add(new CliOption(CodegenConstants.DEVELOPER_ORGANIZATION, CodegenConstants.DEVELOPER_ORGANIZATION_DESC));
cliOptions.add(new CliOption(CodegenConstants.DEVELOPER_ORGANIZATION_URL, CodegenConstants.DEVELOPER_ORGANIZATION_URL_DESC));
cliOptions.add(new CliOption(CodegenConstants.LICENSE_NAME, CodegenConstants.LICENSE_NAME_DESC));
cliOptions.add(new CliOption(CodegenConstants.LICENSE_URL, CodegenConstants.LICENSE_URL_DESC));
cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, CodegenConstants.SOURCE_FOLDER_DESC));
@@ -191,6 +209,60 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
}
if (additionalProperties.containsKey(CodegenConstants.ARTIFACT_URL)) {
this.setArtifactUrl((String) additionalProperties.get(CodegenConstants.ARTIFACT_URL));
} else {
additionalProperties.put(CodegenConstants.ARTIFACT_URL, artifactUrl);
}
if (additionalProperties.containsKey(CodegenConstants.ARTIFACT_DESCRIPTION)) {
this.setArtifactDescription((String) additionalProperties.get(CodegenConstants.ARTIFACT_DESCRIPTION));
} else {
additionalProperties.put(CodegenConstants.ARTIFACT_DESCRIPTION, artifactDescription);
}
if (additionalProperties.containsKey(CodegenConstants.SCM_CONNECTION)) {
this.setScmConnection((String) additionalProperties.get(CodegenConstants.SCM_CONNECTION));
} else {
additionalProperties.put(CodegenConstants.SCM_CONNECTION, scmConnection);
}
if (additionalProperties.containsKey(CodegenConstants.SCM_DEVELOPER_CONNECTION)) {
this.setScmDeveloperConnection((String) additionalProperties.get(CodegenConstants.SCM_DEVELOPER_CONNECTION));
} else {
additionalProperties.put(CodegenConstants.SCM_DEVELOPER_CONNECTION, scmDeveloperConnection);
}
if (additionalProperties.containsKey(CodegenConstants.SCM_URL)) {
this.setScmUrl((String) additionalProperties.get(CodegenConstants.SCM_URL));
} else {
additionalProperties.put(CodegenConstants.SCM_URL, scmUrl);
}
if (additionalProperties.containsKey(CodegenConstants.DEVELOPER_NAME)) {
this.setDeveloperName((String) additionalProperties.get(CodegenConstants.DEVELOPER_NAME));
} else {
additionalProperties.put(CodegenConstants.DEVELOPER_NAME, developerName);
}
if (additionalProperties.containsKey(CodegenConstants.DEVELOPER_EMAIL)) {
this.setDeveloperEmail((String) additionalProperties.get(CodegenConstants.DEVELOPER_EMAIL));
} else {
additionalProperties.put(CodegenConstants.DEVELOPER_EMAIL, developerEmail);
}
if (additionalProperties.containsKey(CodegenConstants.DEVELOPER_ORGANIZATION)) {
this.setDeveloperOrganization((String) additionalProperties.get(CodegenConstants.DEVELOPER_ORGANIZATION));
} else {
additionalProperties.put(CodegenConstants.DEVELOPER_ORGANIZATION, developerOrganization);
}
if (additionalProperties.containsKey(CodegenConstants.DEVELOPER_ORGANIZATION_URL)) {
this.setDeveloperOrganizationUrl((String) additionalProperties.get(CodegenConstants.DEVELOPER_ORGANIZATION_URL));
} else {
additionalProperties.put(CodegenConstants.DEVELOPER_ORGANIZATION_URL, developerOrganizationUrl);
}
if (additionalProperties.containsKey(CodegenConstants.LICENSE_NAME)) {
this.setLicenseName((String) additionalProperties.get(CodegenConstants.LICENSE_NAME));
} else {
@@ -336,6 +408,9 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
@Override
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@@ -434,11 +509,22 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
@Override
public String toModelName(final String name) {
final String sanitizedName = sanitizeName(modelNamePrefix + name + modelNameSuffix);
final String sanitizedName = sanitizeName(name);
String nameWithPrefixSuffix = sanitizedName;
if (!StringUtils.isEmpty(modelNamePrefix)) {
// add '_' so that model name can be camelized correctly
nameWithPrefixSuffix = modelNamePrefix + "_" + nameWithPrefixSuffix;
}
if (!StringUtils.isEmpty(modelNameSuffix)) {
// add '_' so that model name can be camelized correctly
nameWithPrefixSuffix = nameWithPrefixSuffix + "_" + modelNameSuffix;
}
// camelize the model name
// phone_number => PhoneNumber
final String camelizedName = camelize(sanitizedName);
final String camelizedName = camelize(nameWithPrefixSuffix);
// model name cannot use reserved keyword, e.g. return
if (isReservedWord(camelizedName)) {
@@ -448,7 +534,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
}
// model name starts with number
if (name.matches("^\\d.*")) {
if (camelizedName.matches("^\\d.*")) {
final String modelName = "Model" + camelizedName; // e.g. 200Response => Model200Response (after camelize)
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + modelName);
return modelName;
@@ -815,6 +901,10 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
@Override
public String toEnumVarName(String value, String datatype) {
if (value.length() == 0) {
return "EMPTY";
}
// for symbol, e.g. $, #
if (getSymbolName(value) != null) {
return getSymbolName(value).toUpperCase();
@@ -929,6 +1019,42 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
this.artifactVersion = artifactVersion;
}
public void setArtifactUrl(String artifactUrl) {
this.artifactUrl = artifactUrl;
}
public void setArtifactDescription(String artifactDescription) {
this.artifactDescription = artifactDescription;
}
public void setScmConnection(String scmConnection) {
this.scmConnection = scmConnection;
}
public void setScmDeveloperConnection(String scmDeveloperConnection) {
this.scmDeveloperConnection = scmDeveloperConnection;
}
public void setScmUrl(String scmUrl) {
this.scmUrl = scmUrl;
}
public void setDeveloperName(String developerName) {
this.developerName = developerName;
}
public void setDeveloperEmail(String developerEmail) {
this.developerEmail = developerEmail;
}
public void setDeveloperOrganization(String developerOrganization) {
this.developerOrganization = developerOrganization;
}
public void setDeveloperOrganizationUrl(String developerOrganizationUrl) {
this.developerOrganizationUrl = developerOrganizationUrl;
}
public void setLicenseName(String licenseName) {
this.licenseName = licenseName;
}
@@ -1008,4 +1134,22 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
return escapeText(pattern);
}
public boolean convertPropertyToBoolean(String propertyKey) {
boolean booleanValue = false;
if (additionalProperties.containsKey(propertyKey)) {
booleanValue = Boolean.valueOf(additionalProperties.get(propertyKey).toString());
}
return booleanValue;
}
public void writePropertyBack(String propertyKey, boolean value) {
additionalProperties.put(propertyKey, value);
}
@Override
public String sanitizeTag(String tag) {
return camelize(sanitizeName(tag));
}
}

View File

@@ -1,6 +1,7 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.codegen.languages.features.BeanValidationFeatures;
import io.swagger.models.Operation;
import io.swagger.models.Path;
import io.swagger.models.Swagger;
@@ -10,7 +11,7 @@ import org.slf4j.LoggerFactory;
import java.util.*;
public abstract class AbstractJavaJAXRSServerCodegen extends AbstractJavaCodegen {
public abstract class AbstractJavaJAXRSServerCodegen extends AbstractJavaCodegen implements BeanValidationFeatures {
/**
* Name of the sub-directory in "src/main/resource" where to find the
* Mustache template for the JAX-RS Codegen.
@@ -19,6 +20,9 @@ public abstract class AbstractJavaJAXRSServerCodegen extends AbstractJavaCodegen
protected String implFolder = "src/main/java";
protected String testResourcesFolder = "src/test/resources";
protected String title = "Swagger Server";
protected boolean useBeanValidation = true;
static Logger LOGGER = LoggerFactory.getLogger(AbstractJavaJAXRSServerCodegen.class);
public AbstractJavaJAXRSServerCodegen()
@@ -40,6 +44,8 @@ public abstract class AbstractJavaJAXRSServerCodegen extends AbstractJavaCodegen
cliOptions.add(new CliOption(CodegenConstants.IMPL_FOLDER, CodegenConstants.IMPL_FOLDER_DESC));
cliOptions.add(new CliOption("title", "a title describing the application"));
cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations"));
}
@@ -60,6 +66,15 @@ public abstract class AbstractJavaJAXRSServerCodegen extends AbstractJavaCodegen
if (additionalProperties.containsKey(CodegenConstants.IMPL_FOLDER)) {
implFolder = (String) additionalProperties.get(CodegenConstants.IMPL_FOLDER);
}
if (additionalProperties.containsKey(USE_BEANVALIDATION)) {
this.setUseBeanValidation(convertPropertyToBoolean(USE_BEANVALIDATION));
}
if (useBeanValidation) {
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);
}
}
@Override
@@ -204,4 +219,9 @@ public abstract class AbstractJavaJAXRSServerCodegen extends AbstractJavaCodegen
private String implFileFolder(String output) {
return outputFolder + "/" + output + "/" + apiPackage().replace('.', '/');
}
public void setUseBeanValidation(boolean useBeanValidation) {
this.useBeanValidation = useBeanValidation;
}
}

View File

@@ -251,8 +251,11 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
.replaceAll(regLastPathSeparator+ "$", "");
}
@Override
public String escapeReservedWord(String name) {
@Override
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@@ -589,6 +592,10 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
@Override
public String toEnumVarName(String name, String datatype) {
if (name.length() == 0) {
return "EMPTY";
}
// for symbol, e.g. $, #
if (getSymbolName(name) != null) {
return (getSymbolName(name)).toUpperCase();

View File

@@ -67,7 +67,10 @@ public abstract class AbstractScalaCodegen extends DefaultCodegen {
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@@ -112,7 +112,6 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
}
}
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
@@ -120,6 +119,9 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
@Override
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@@ -155,8 +157,8 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
@Override
public String toVarName(String name) {
// should be the same as variable name
return getNameUsingModelPropertyNaming(name);
// should be the same as variable name
return getNameUsingModelPropertyNaming(name);
}
@Override
@@ -291,6 +293,10 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
@Override
public String toEnumVarName(String name, String datatype) {
if (name.length() == 0) {
return "Empty";
}
// for symbol, e.g. $, #
if (getSymbolName(name) != null) {
return camelize(getSymbolName(name));

View File

@@ -154,6 +154,9 @@ public class AkkaScalaClientCodegen extends AbstractScalaCodegen implements Code
@Override
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "`" + name + "`";
}

View File

@@ -119,7 +119,10 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@@ -14,8 +14,6 @@ import static java.util.UUID.randomUUID;
public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
protected String sourceFolder = "src" + File.separator + packageName;
private final String packageGuid = "{" + randomUUID().toString().toUpperCase() + "}";
@SuppressWarnings("hiding")
@@ -24,6 +22,7 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
public AspNetCoreServerCodegen() {
super();
setSourceFolder("src");
outputFolder = "generated-code" + File.separator + this.getName();
modelTemplateFiles.put("model.mustache", ".cs");
@@ -91,38 +90,53 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
apiPackage = packageName + ".Controllers";
modelPackage = packageName + ".Models";
String packageFolder = sourceFolder + File.separator + packageName;
supportingFiles.add(new SupportingFile("NuGet.Config", "", "NuGet.Config"));
supportingFiles.add(new SupportingFile("global.json", "", "global.json"));
supportingFiles.add(new SupportingFile("build.sh.mustache", "", "build.sh"));
supportingFiles.add(new SupportingFile("build.bat.mustache", "", "build.bat"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("Solution.mustache", "", this.packageName + ".sln"));
supportingFiles.add(new SupportingFile("Dockerfile.mustache", this.sourceFolder, "Dockerfile"));
supportingFiles.add(new SupportingFile("gitignore", this.sourceFolder, ".gitignore"));
supportingFiles.add(new SupportingFile("appsettings.json", this.sourceFolder, "appsettings.json"));
supportingFiles.add(new SupportingFile("Dockerfile.mustache", packageFolder, "Dockerfile"));
supportingFiles.add(new SupportingFile("gitignore", packageFolder, ".gitignore"));
supportingFiles.add(new SupportingFile("appsettings.json", packageFolder, "appsettings.json"));
supportingFiles.add(new SupportingFile("project.json.mustache", this.sourceFolder, "project.json"));
supportingFiles.add(new SupportingFile("Startup.mustache", this.sourceFolder, "Startup.cs"));
supportingFiles.add(new SupportingFile("Program.mustache", this.sourceFolder, "Program.cs"));
supportingFiles.add(new SupportingFile("web.config", this.sourceFolder, "web.config"));
supportingFiles.add(new SupportingFile("project.json.mustache", packageFolder, "project.json"));
supportingFiles.add(new SupportingFile("Startup.mustache", packageFolder, "Startup.cs"));
supportingFiles.add(new SupportingFile("Program.mustache", packageFolder, "Program.cs"));
supportingFiles.add(new SupportingFile("web.config", packageFolder, "web.config"));
supportingFiles.add(new SupportingFile("Project.xproj.mustache", this.sourceFolder, this.packageName + ".xproj"));
supportingFiles.add(new SupportingFile("Project.xproj.mustache", packageFolder, this.packageName + ".xproj"));
supportingFiles.add(new SupportingFile("Properties" + File.separator + "launchSettings.json", this.sourceFolder + File.separator + "Properties", "launchSettings.json"));
supportingFiles.add(new SupportingFile("Properties" + File.separator + "launchSettings.json", packageFolder + File.separator + "Properties", "launchSettings.json"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "README.md", this.sourceFolder + File.separator + "wwwroot", "README.md"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "index.html", this.sourceFolder + File.separator + "wwwroot", "index.html"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "web.config", this.sourceFolder + File.separator + "wwwroot", "web.config"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "README.md", packageFolder + File.separator + "wwwroot", "README.md"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "index.html", packageFolder + File.separator + "wwwroot", "index.html"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "web.config", packageFolder + File.separator + "wwwroot", "web.config"));
}
@Override
public void setSourceFolder(final String sourceFolder) {
if(sourceFolder == null) {
LOGGER.warn("No sourceFolder specified, using default");
this.sourceFolder = "src" + File.separator + this.packageName;
} else if(!sourceFolder.equals("src") && !sourceFolder.startsWith("src")) {
LOGGER.warn("ASP.NET Core requires source code exists under src. Adjusting.");
this.sourceFolder = "src" + File.separator + sourceFolder;
} else {
this.sourceFolder = sourceFolder;
}
}
@Override
public String apiFileFolder() {
return outputFolder + File.separator + sourceFolder + File.separator + "Controllers";
return outputFolder + File.separator + sourceFolder + File.separator + packageName + File.separator + "Controllers";
}
@Override
public String modelFileFolder() {
return outputFolder + File.separator + sourceFolder + File.separator + "Models";
return outputFolder + File.separator + sourceFolder + File.separator + packageName + File.separator + "Models";
}
@Override

View File

@@ -0,0 +1,662 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.models.properties.*;
import io.swagger.models.parameters.*;
import io.swagger.models.Model;
import io.swagger.models.Operation;
import io.swagger.models.Swagger;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.io.File;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class BashClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String apiVersion = "1.0.0";
protected String curlOptions;
protected boolean processMarkdown = false;
protected String scriptName = "client.sh";
protected boolean generateBashCompletion = false;
protected boolean generateZshCompletion = false;
protected String hostEnvironmentVariable;
protected String basicAuthEnvironmentVariable;
protected String apiKeyAuthEnvironmentVariable;
public static final String CURL_OPTIONS = "curlOptions";
public static final String PROCESS_MARKDOWN = "processMarkdown";
public static final String SCRIPT_NAME = "scriptName";
public static final String
GENERATE_BASH_COMPLETION = "generateBashCompletion";
public static final String
GENERATE_ZSH_COMPLETION = "generateZshCompletion";
public static final String
HOST_ENVIRONMENT_VARIABLE_NAME = "hostEnvironmentVariable";
public static final String
BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME = "basicAuthEnvironmentVariable";
public static final String
APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME = "apiKeyAuthEnvironmentVariable";
/**
* Configures the type of generator.
*
* @return the CodegenType for this generator
* @see io.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 "bash";
}
/**
* 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 Bash client script based on cURL.";
}
public BashClientCodegen() {
super();
/**
* Set the output folder here
*/
outputFolder = "generated-code/bash";
/**
* No model files.
*/
modelTemplateFiles.clear();
/**
* No API files.
*/
apiTemplateFiles.clear();
/**
* Templates location for client script and bash completion template.
*/
embeddedTemplateDir = templateDir = "bash";
/**
* Allow the user to force the script to always include certain cURL
* comamnds
*/
cliOptions.add(CliOption.newString(CURL_OPTIONS, "Default cURL options"));
cliOptions.add(CliOption.newBoolean(PROCESS_MARKDOWN,
"Convert all Markdown Markup into terminal formatting"));
cliOptions.add(CliOption.newString(SCRIPT_NAME,
"The name of the script that will be generated "+
"(e.g. petstore-cli)"));
cliOptions.add(CliOption.newBoolean(GENERATE_BASH_COMPLETION,
"Whether to generate the Bash completion script"));
cliOptions.add(CliOption.newBoolean(GENERATE_ZSH_COMPLETION,
"Whether to generate the Zsh completion script"));
cliOptions.add(CliOption.newString(HOST_ENVIRONMENT_VARIABLE_NAME,
"Name of environment variable where host can be defined "+
"(e.g. PETSTORE_HOST='http://petstore.swagger.io:8080')"));
cliOptions.add(CliOption.newString(BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME,
"Name of environment variable where username and password "
+
"can be defined (e.g. PETSTORE_CREDS='username:password')"));
cliOptions.add(CliOption.newBoolean(APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME,
"Name of environment variable where API key "
+
"can be defined (e.g. PETSTORE_APIKEY='kjhasdGASDa5asdASD')"));
/**
* Bash reserved words.
*/
reservedWords = new HashSet<String> (
Arrays.asList(
"case",
"do",
"done",
"elif",
"else",
"esac",
"fi",
"for",
"function",
"if",
"in",
"select",
"then",
"time",
"until",
"while")
);
typeMapping.clear();
typeMapping.put("array", "array");
typeMapping.put("map", "map");
typeMapping.put("List", "array");
typeMapping.put("boolean", "boolean");
typeMapping.put("string", "string");
typeMapping.put("int", "integer");
typeMapping.put("float", "float");
typeMapping.put("number", "integer");
typeMapping.put("DateTime", "string");
typeMapping.put("long", "integer");
typeMapping.put("short", "integer");
typeMapping.put("char", "string");
typeMapping.put("double", "float");
typeMapping.put("object", "map");
typeMapping.put("integer", "integer");
typeMapping.put("ByteArray", "string");
typeMapping.put("binary", "binary");
/**
* Additional Properties. These values can be passed to the templates and
* are available in models, apis, and supporting files.
*/
additionalProperties.put("apiVersion", apiVersion);
/**
* Language Specific Primitives. These types will not trigger imports by
* the client generator
*/
languageSpecificPrimitives = new HashSet<String>();
}
@Override
public void processOpts() {
super.processOpts();
String curlopts = "";
if (additionalProperties.containsKey(CURL_OPTIONS)) {
setCurlOptions(additionalProperties.get(CURL_OPTIONS).toString());
additionalProperties.put("x-codegen-curl-options", curlopts);
}
if (additionalProperties.containsKey(PROCESS_MARKDOWN)) {
setProcessMarkdown(
Boolean.parseBoolean(
additionalProperties.get(PROCESS_MARKDOWN).toString()));
}
if (additionalProperties.containsKey(GENERATE_BASH_COMPLETION)) {
setGenerateBashCompletion(
Boolean.parseBoolean(
additionalProperties.get(GENERATE_BASH_COMPLETION).toString()));
}
if (additionalProperties.containsKey(GENERATE_ZSH_COMPLETION)) {
setGenerateZshCompletion(
Boolean.parseBoolean(
additionalProperties.get(GENERATE_ZSH_COMPLETION).toString()));
}
if (additionalProperties.containsKey(SCRIPT_NAME)) {
setScriptName(additionalProperties.get(SCRIPT_NAME).toString());
}
additionalProperties.put("x-codegen-script-name", scriptName);
if (additionalProperties.containsKey(HOST_ENVIRONMENT_VARIABLE_NAME)) {
setHostEnvironmentVariable(
additionalProperties.get(HOST_ENVIRONMENT_VARIABLE_NAME).toString());
additionalProperties.put("x-codegen-host-env", hostEnvironmentVariable);
}
if (additionalProperties.containsKey(BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME)) {
setBasicAuthEnvironmentVariable(
additionalProperties.get(BASIC_AUTH_ENVIRONMENT_VARIABLE_NAME).toString());
additionalProperties.put("x-codegen-basicauth-env", basicAuthEnvironmentVariable);
}
if (additionalProperties.containsKey(APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME)) {
setApiKeyAuthEnvironmentVariable(
additionalProperties.get(APIKEY_AUTH_ENVIRONMENT_VARIABLE_NAME).toString());
additionalProperties.put("x-codegen-apikey-env", apiKeyAuthEnvironmentVariable);
}
supportingFiles.add(new SupportingFile(
"client.mustache", "", scriptName));
supportingFiles.add(new SupportingFile(
"bash-completion.mustache", "", scriptName+".bash-completion"));
supportingFiles.add(new SupportingFile(
"zsh-completion.mustache", "", "_"+scriptName));
supportingFiles.add(new SupportingFile(
"README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile(
"Dockerfile.mustache", "", "Dockerfile"));
}
public void setCurlOptions(String curlOptions) {
this.curlOptions = curlOptions;
}
public void setProcessMarkdown(boolean processMarkdown) {
this.processMarkdown = processMarkdown;
}
public void setScriptName(String scriptName) {
this.scriptName = scriptName;
}
public void setGenerateBashCompletion(boolean generateBashCompletion) {
this.generateBashCompletion = generateBashCompletion;
}
public void setGenerateZshCompletion(boolean generateZshCompletion) {
this.generateZshCompletion = generateZshCompletion;
}
public void setHostEnvironmentVariable(String hostEnvironmentVariable) {
this.hostEnvironmentVariable = hostEnvironmentVariable;
}
public void setBasicAuthEnvironmentVariable(String
basicAuthEnvironmentVariable) {
this.basicAuthEnvironmentVariable = basicAuthEnvironmentVariable;
}
public void setApiKeyAuthEnvironmentVariable(String
apiKeyAuthEnvironmentVariable) {
this.apiKeyAuthEnvironmentVariable = apiKeyAuthEnvironmentVariable;
}
/**
* 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;
}
/**
* Location to write api files. You can use the apiPackage() as defined when
* the class is instantiated.
*/
@Override
public String apiFileFolder() {
return outputFolder;
}
/**
* 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 io.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 type;
}
else
type = swaggerType;
return toModelName(type);
}
/**
* Convert Swagger Parameter object to Codegen Parameter object
*
* @param param Swagger parameter object
* @param imports set of imports for library/package/module
* @return Codegen Parameter object
*/
@Override
public CodegenParameter fromParameter(Parameter param, Set<String> imports) {
CodegenParameter p = super.fromParameter(param, imports);
if(param instanceof BodyParameter) {
Model model = ((BodyParameter)param).getSchema();
}
else if(param instanceof SerializableParameter) {
/**
* Currently it's not possible to specify in the codegen other collection
* formats than 'multi'
*/
SerializableParameter sparam = (SerializableParameter)param;
if( sparam.getCollectionFormat() != null
&& !sparam.getCollectionFormat().isEmpty()) {
String collectionFormat = sparam.getCollectionFormat();
if(sparam.isExclusiveMaximum()!=null && sparam.isExclusiveMaximum()) {
p.vendorExtensions.put("x-codegen-collection-max-items",
sparam.getMaxItems());
}
if(sparam.isExclusiveMinimum()!=null && sparam.isExclusiveMinimum()) {
p.vendorExtensions.put("x-codegen-collection-min-items",
sparam.getMinItems());
}
if( (collectionFormat.equals("multi"))
&& (param.getIn().equals("query")) ) {
/**
* 'multi' is only supported for query parameters
*/
p.vendorExtensions.put("x-codegen-collection-multi", true);
}
else if(collectionFormat.equals("csv")) {
p.vendorExtensions.put("x-codegen-collection-csv", true);
}
else if(collectionFormat.equals("ssv")) {
p.vendorExtensions.put("x-codegen-collection-ssv", true);
}
else if(collectionFormat.equals("tsv")) {
p.vendorExtensions.put("x-codegen-collection-tsv", true);
}
else if(collectionFormat.equals("pipes")) {
p.vendorExtensions.put("x-codegen-collection-pipes", true);
}
else {
/** Unsupported collection format */
}
}
}
return p;
}
/**
* Override with any special text escaping logic
*/
@SuppressWarnings("static-method")
public String escapeText(String input) {
if (input == null) {
return input;
}
/**
* Trim the input text always.
*/
String result = input.trim();
/**
* remove standalone '\'
*
* replace " with \"
* outter unescape to retain the original multi-byte characters
*/
result = escapeUnsafeCharacters(
StringEscapeUtils.unescapeJava(
StringEscapeUtils.escapeJava(result).replace("\\/", "/"))
.replace("\\", "\\\\")
.replace("\"", "\\\""));
if(this.processMarkdown) {
/**
* Convert markdown strong **Bold text** and __Bold text__
* to bash bold control sequences (tput bold)
*/
result = result.replaceAll("(?m)(^|\\s)\\*{2}([\\w\\d ]+)\\*{2}($|\\s)",
"\\$\\(tput bold\\) $2 \\$\\(tput sgr0\\)");
result = result.replaceAll("(?m)(^|\\s)_{2}([\\w\\d ]+)_{2}($|\\s)",
"\\$\\(tput bold\\) $2 \\$\\(tput sgr0\\)");
/**
* Convert markdown *Italics text* and _Italics text_ to bash dim
* control sequences (tput dim)
*/
result = result.replaceAll("(?m)(^|\\s)\\*{1}([\\w\\d ]+)\\*{1}($|\\s)",
"\\$\\(tput dim\\) $2 \\$\\(tput sgr0\\)");
result = result.replaceAll("(?m)(^|\\s)_{1}([\\w\\d ]+)_{1}($|\\s)",
"\\$\\(tput dim\\) $2 \\$\\(tput sgr0\\)");
/**
* Convert all markdown section 1 level headers with bold
*/
result = result.replaceAll("(?m)^\\#\\s+(.+)$",
"\n\\$\\(tput bold\\)\\$\\(tput setaf 7\\)"
+"$1\\$\\(tput sgr0\\)");
/**
* Convert all markdown section 2 level headers with bold
*/
result = result.replaceAll("(?m)^\\#\\#\\s+(.+)$",
"\n\\$\\(tput bold\\)\\$\\(tput setaf 7\\)"
+"$1\\$\\(tput sgr0\\)");
/**
* Convert all markdown section 3 level headers with bold
*/
result = result.replaceAll("(?m)^\\#\\#\\#\\s+(.+)$",
"\n\\$\\(tput bold\\)\\$\\(tput setaf 7\\)"
+"$1\\$\\(tput sgr0\\)");
/**
* Convert all markdown code blocks into --- delimited sections
*/
result = result.replaceAll("(?m)\\s*```.*$",
"\n---");
result = result.replaceAll("(?m)\\s*\\'\\'\\'.*$",
"\n---");
/**
* Remove any trailing new line at the end of the string
*/
result = result.replaceAll("\\s+$", "");
}
return result;
}
@Override
public String escapeQuotationMark(String input) {
return input;
}
/**
* Override with any special text escaping logic to handle unsafe
* characters so as to avoid code injection.
*
* @param input String to be cleaned up
* @return string with unsafe characters removed or escaped
*/
public String escapeUnsafeCharacters(String input) {
/**
* Replace backticks with normal single quotes.
*/
String result = input.replaceAll("`", "'");
return result;
}
@Override
public CodegenOperation fromOperation(String path, String httpMethod,
Operation operation,
Map<String, Model> definitions,
Swagger swagger) {
CodegenOperation op = super.fromOperation(path, httpMethod, operation,
definitions, swagger);
/**
* Check if the operation has a Bash codegen specific description
* for help
*/
if(op.vendorExtensions.containsKey("x-bash-codegen-description")) {
String bash_description
= (String)op.vendorExtensions.get("x-bash-codegen-description");
op.vendorExtensions.put("x-bash-codegen-description",
escapeText(bash_description));
}
/**
* Check if operation has an 'x-code-samples' vendor extension with
* Shell example
*/
if(op.vendorExtensions.containsKey("x-code-samples")) {
List codesamples = (List)op.vendorExtensions.get("x-code-samples");
for (Object codesample : codesamples) {
ObjectNode codesample_object = (ObjectNode)codesample;
if((codesample_object.get("lang").asText()).equals("Shell")) {
op.vendorExtensions.put("x-bash-codegen-sample",
escapeUnsafeCharacters(
codesample_object.get("source").asText()));
}
}
}
for (CodegenParameter p : op.bodyParams) {
if(p.dataType != null && definitions.get(p.dataType) != null) {
/**
* If the operation produces Json and has nonempty example
* try to reformat it.
*/
if(operation.getConsumes() != null
&& operation.getConsumes().contains("application/json")
&& definitions.get(p.dataType).getExample() != null) {
ObjectMapper mapper = new ObjectMapper();
try {
p.vendorExtensions.put(
"x-codegen-body-example",
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(
definitions.get(p.dataType).getExample()));
}
catch(JsonProcessingException e) {
e.printStackTrace();
}
}
else {
/**
* Otherwise present whatever is provided as example
*/
p.vendorExtensions.put(
"x-codegen-body-example",
definitions.get(p.dataType).getExample());
}
}
}
return op;
}
/**
* Preprocess original properties from the Swagger definition where necessary.
*
* @param swagger [description]
*/
@Override
public void preprocessSwagger(Swagger swagger) {
super.preprocessSwagger(swagger);
if ("/".equals(swagger.getBasePath())) {
swagger.setBasePath("");
}
if(swagger.getInfo() != null
&& swagger.getInfo().getVendorExtensions()!=null) {
String bash_codegen_app_description
= (String)swagger.getInfo().getVendorExtensions()
.get("x-bash-codegen-description");
if(bash_codegen_app_description != null) {
bash_codegen_app_description
= escapeText(bash_codegen_app_description);
additionalProperties.put("x-bash-codegen-app-description",
bash_codegen_app_description);
}
}
}
}

View File

@@ -1,6 +1,9 @@
package io.swagger.codegen.languages;
import com.google.common.collect.ImmutableMap;
import com.sun.org.apache.bcel.internal.classfile.Code;
import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.CodegenModel;
@@ -45,6 +48,9 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
protected Map<Character, String> regexModifiers;
protected final Map<String, String> frameworks;
// By default, generated code is considered public
protected boolean nonPublicApi = Boolean.FALSE;
public CSharpClientCodegen() {
super();
modelTemplateFiles.put("model.mustache", ".cs");
@@ -72,6 +78,10 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
CodegenConstants.OPTIONAL_PROJECT_GUID_DESC,
null);
addOption(CodegenConstants.INTERFACE_PREFIX,
CodegenConstants.INTERFACE_PREFIX_DESC,
interfacePrefix);
CliOption framework = new CliOption(
CodegenConstants.DOTNET_FRAMEWORK,
CodegenConstants.DOTNET_FRAMEWORK_DESC
@@ -126,6 +136,18 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
CodegenConstants.PACKAGE_DESCRIPTION_DESC,
this.generatePropertyChanged);
// NOTE: This will reduce visibility of all public members in templates. Users can use InternalsVisibleTo
// https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute(v=vs.110).aspx
// to expose to shared code if the generated code is not embedded into another project. Otherwise, users of codegen
// should rely on default public visibility.
addSwitch(CodegenConstants.NON_PUBLIC_API,
CodegenConstants.NON_PUBLIC_API_DESC,
this.nonPublicApi);
addSwitch(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS,
CodegenConstants.ALLOW_UNICODE_IDENTIFIERS_DESC,
this.allowUnicodeIdentifiers);
regexModifiers = new HashMap<Character, String>();
regexModifiers.put('i', "IgnoreCase");
regexModifiers.put('m', "Multiline");
@@ -228,6 +250,10 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
.get(CodegenConstants.OPTIONAL_ASSEMBLY_INFO).toString()));
}
if (additionalProperties.containsKey(CodegenConstants.NON_PUBLIC_API)) {
setNonPublicApi(Boolean.valueOf(additionalProperties.get(CodegenConstants.NON_PUBLIC_API).toString()));
}
final String testPackageName = testPackageName();
String packageFolder = sourceFolder + File.separator + packageName;
String clientPackageDir = packageFolder + File.separator + clientPackage;
@@ -293,6 +319,7 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
if (optionalProjectFileFlag) {
supportingFiles.add(new SupportingFile("Solution.mustache", "", packageName + ".sln"));
supportingFiles.add(new SupportingFile("Project.mustache", packageFolder, packageName + ".csproj"));
supportingFiles.add(new SupportingFile("nuspec.mustache", packageFolder, packageName + ".nuspec"));
if(Boolean.FALSE.equals(excludeTests)) {
// NOTE: This exists here rather than previous excludeTests block because the test project is considered an optional project file.
@@ -494,6 +521,10 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
@Override
public String toEnumVarName(String value, String datatype) {
if (value.length() == 0) {
return "Empty";
}
// for symbol, e.g. $, #
if (getSymbolName(value) != null) {
return camelize(getSymbolName(value));
@@ -547,6 +578,14 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
this.generatePropertyChanged = generatePropertyChanged;
}
public boolean isNonPublicApi() {
return nonPublicApi;
}
public void setNonPublicApi(final boolean nonPublicApi) {
this.nonPublicApi = nonPublicApi;
}
@Override
public String toModelDocFilename(String name) {
return toModelFilename(name);

View File

@@ -62,7 +62,7 @@ public class CppRestClientCodegen extends DefaultCodegen implements CodegenConfi
apiTemplateFiles.put("api-header.mustache", ".h");
apiTemplateFiles.put("api-source.mustache", ".cpp");
templateDir = "cpprest";
embeddedTemplateDir = templateDir = "cpprest";
cliOptions.clear();

View File

@@ -10,6 +10,8 @@ import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import io.swagger.codegen.CliOption;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
@@ -170,7 +172,10 @@ public class CsharpDotNet2ClientCodegen extends DefaultCodegen implements Codege
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@@ -230,11 +235,26 @@ public class CsharpDotNet2ClientCodegen extends DefaultCodegen implements Codege
@Override
public String toModelName(String name) {
if (!StringUtils.isEmpty(modelNamePrefix)) {
name = modelNamePrefix + "_" + name;
}
if (!StringUtils.isEmpty(modelNameSuffix)) {
name = name + "_" + modelNameSuffix;
}
name = sanitizeName(name);
// model name cannot use reserved keyword, e.g. return
if (isReservedWord(name)) {
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + camelize("model_" + name));
name = "model_" + name; // e.g. return => ModelReturn (after camelize)
}
// model name starts with number
if (name.matches("^\\d.*")) {
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + camelize("model_" + name));
name = "model_" + name; // e.g. 200Response => Model200Response (after camelize)
}
// camelize the model name
@@ -281,12 +301,18 @@ public class CsharpDotNet2ClientCodegen extends DefaultCodegen implements Codege
@Override
public String toOperationId(String operationId) {
// method name cannot use reserved keyword, e.g. return
if (isReservedWord(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
// throw exception if method name is empty (should not occur as an auto-generated method name will be used)
if (StringUtils.isEmpty(operationId)) {
throw new RuntimeException("Empty method name (operationId) not allowed");
}
return camelize(operationId);
// method name cannot use reserved keyword, e.g. return
if (isReservedWord(operationId)) {
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + camelize(sanitizeName("call_" + operationId)));
operationId = "call_" + operationId;
}
return camelize(sanitizeName(operationId));
}
@Override

View File

@@ -174,7 +174,10 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@@ -0,0 +1,388 @@
package io.swagger.codegen.languages;
import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Template;
import io.swagger.codegen.*;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import java.io.IOException;
import java.io.Writer;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ElixirClientCodegen extends DefaultCodegen implements CodegenConfig {
// source folder where to write the files
protected String sourceFolder = "lib";
protected String apiVersion = "1.0.0";
String supportedElixirVersion = "1.4";
List<String> extraApplications = Arrays.asList(":logger");
List<String> deps = Arrays.asList(
"{:tesla, \"~> 0.5.0\"}",
"{:poison, \">= 1.0.0\"}"
);
public ElixirClientCodegen() {
super();
// set the output folder here
outputFolder = "generated-code/elixir";
/**
* 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
".ex"); // 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
".ex"); // 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 = "elixir";
/**
* 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("README.md.mustache", // the input template or file
"", // the destination folder, relative `outputFolder`
"README.md") // the output file
);
supportingFiles.add(new SupportingFile("config.exs.mustache",
"config",
"config.exs")
);
supportingFiles.add(new SupportingFile("mix.exs.mustache",
"",
"mix.exs")
);
supportingFiles.add(new SupportingFile("test_helper.exs.mustache",
"test",
"test_helper.exs")
);
/**
* 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")
);
}
/**
* Configures the type of generator.
*
* @return the CodegenType for this generator
* @see io.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 "elixir";
}
/**
* 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 an elixir client library (alpha).";
}
@Override
public void processOpts() {
super.processOpts();
additionalProperties.put("supportedElixirVersion", supportedElixirVersion);
additionalProperties.put("extraApplications", join(",", extraApplications));
additionalProperties.put("deps", deps);
additionalProperties.put("underscored", new Mustache.Lambda() {
@Override
public void execute(Template.Fragment fragment, Writer writer) throws IOException {
writer.write(underscored(fragment.execute()));
}
});
additionalProperties.put("modulized", new Mustache.Lambda() {
@Override
public void execute(Template.Fragment fragment, Writer writer) throws IOException {
writer.write(modulized(fragment.execute()));
}
});
}
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
Map<String, Object> operations = (Map<String, Object>) super.postProcessOperations(objs).get("operations");
List<CodegenOperation> os = (List<CodegenOperation>) operations.get("operation");
List<ExtendedCodegenOperation> newOs = new ArrayList<ExtendedCodegenOperation>();
Pattern pattern = Pattern.compile("(.*)\\{([^\\}]+)\\}(.*)");
for (CodegenOperation o : os) {
ArrayList<String> pathTemplateNames = new ArrayList<String>();
Matcher matcher = pattern.matcher(o.path);
StringBuffer buffer = new StringBuffer();
while (matcher.find()) {
String pathTemplateName = matcher.group(2);
matcher.appendReplacement(buffer, "$1" + "#{" + underscore(pathTemplateName) + "}" + "$3");
pathTemplateNames.add(pathTemplateName);
}
ExtendedCodegenOperation eco = new ExtendedCodegenOperation(o);
if (buffer.toString().isEmpty()) {
eco.setReplacedPathName(o.path);
} else {
eco.setReplacedPathName(buffer.toString());
}
eco.setPathTemplateNames(pathTemplateNames);
newOs.add(eco);
}
operations.put("operation", newOs);
return objs;
}
// We should use String.join if we can use Java8
String join(CharSequence charSequence, Iterable<String> iterable) {
StringBuilder buf = new StringBuilder();
for (String str : iterable) {
if (0 < buf.length()) {
buf.append((charSequence));
}
buf.append(str);
}
return buf.toString();
}
String underscored(String words) {
ArrayList<String> underscoredWords = new ArrayList<String>();
for (String word : words.split(" ")) {
underscoredWords.add(underscore(word));
}
return join("_", underscoredWords);
}
String modulized(String words) {
ArrayList<String> modulizedWords = new ArrayList<String>();
for (String word : words.split(" ")) {
modulizedWords.add(camelize(word));
}
return join("", modulizedWords);
}
/**
* 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 + "/" + underscored((String) additionalProperties.get("appName")) + "/" + "model";
}
/**
* Location to write api files. You can use the apiPackage() as defined when the class is
* instantiated
*/
@Override
public String apiFileFolder() {
return outputFolder + "/" + sourceFolder + "/" + underscored((String) additionalProperties.get("appName")) + "/" + "api";
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "Default";
}
return initialCaps(name);
}
@Override
public String toApiFilename(String name) {
return snakeCase(name);
}
@Override
public String toModelFilename(String name) {
return snakeCase(name);
}
/**
* 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 io.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);
}
class ExtendedCodegenOperation extends CodegenOperation {
private List<String> pathTemplateNames = new ArrayList<String>();
private String replacedPathName;
public ExtendedCodegenOperation(CodegenOperation o) {
super();
// Copy all fields of CodegenOperation
this.responseHeaders.addAll(o.responseHeaders);
this.hasAuthMethods = o.hasAuthMethods;
this.hasConsumes = o.hasConsumes;
this.hasProduces = o.hasProduces;
this.hasParams = o.hasParams;
this.hasOptionalParams = o.hasOptionalParams;
this.returnTypeIsPrimitive = o.returnTypeIsPrimitive;
this.returnSimpleType = o.returnSimpleType;
this.subresourceOperation = o.subresourceOperation;
this.isMapContainer = o.isMapContainer;
this.isListContainer = o.isListContainer;
this.isMultipart = o.isMultipart;
this.hasMore = o.hasMore;
this.isResponseBinary = o.isResponseBinary;
this.hasReference = o.hasReference;
this.isRestfulIndex = o.isRestfulIndex;
this.isRestfulShow = o.isRestfulShow;
this.isRestfulCreate = o.isRestfulCreate;
this.isRestfulUpdate = o.isRestfulUpdate;
this.isRestfulDestroy = o.isRestfulDestroy;
this.isRestful = o.isRestful;
this.path = o.path;
this.operationId = o.operationId;
this.returnType = o.returnType;
this.httpMethod = o.httpMethod;
this.returnBaseType = o.returnBaseType;
this.returnContainer = o.returnContainer;
this.summary = o.summary;
this.unescapedNotes = o.unescapedNotes;
this.notes = o.notes;
this.baseName = o.baseName;
this.defaultResponse = o.defaultResponse;
this.discriminator = o.discriminator;
this.consumes = o.consumes;
this.produces = o.produces;
this.bodyParam = o.bodyParam;
this.allParams = o.allParams;
this.bodyParams = o.bodyParams;
this.pathParams = o.pathParams;
this.queryParams = o.queryParams;
this.headerParams = o.headerParams;
this.formParams = o.formParams;
this.authMethods = o.authMethods;
this.tags = o.tags;
this.responses = o.responses;
this.imports = o.imports;
this.examples = o.examples;
this.externalDocs = o.externalDocs;
this.vendorExtensions = o.vendorExtensions;
this.nickname = o.nickname;
this.operationIdLowerCase = o.operationIdLowerCase;
}
public List<String> getPathTemplateNames() {
return pathTemplateNames;
}
public void setPathTemplateNames(List<String> pathTemplateNames) {
this.pathTemplateNames = pathTemplateNames;
}
public String getReplacedPathName() {
return replacedPathName;
}
public void setReplacedPathName(String replacedPathName) {
this.replacedPathName = replacedPathName;
}
}
@Override
public String escapeQuotationMark(String input) {
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
// no need to escape as Elixir does not support multi-line comments
return input;
}
}

View File

@@ -182,8 +182,11 @@ public class ErlangServerCodegen extends DefaultCodegen implements CodegenConfig
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return name + "_"; // add an underscore to the name
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
/**

View File

@@ -0,0 +1,320 @@
package io.swagger.codegen.languages;
import com.google.common.base.Strings;
import io.swagger.codegen.*;
import io.swagger.models.Model;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
public class FinchServerCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.petstore.client";
protected String groupId = "io.swagger";
protected String artifactId = "finch-server";
protected String artifactVersion = "1.0.0";
protected String sourceFolder = "src/main/scala";
protected String packageName = "io.swagger.petstore";
public FinchServerCodegen() {
super();
outputFolder = "generated-code/finch";
modelTemplateFiles.put("model.mustache", ".scala");
apiTemplateFiles.put("api.mustache", ".scala");
embeddedTemplateDir = templateDir = "finch";
apiPackage = packageName + ".apis";
modelPackage = packageName + ".models";
setReservedWordsLowerCase(
Arrays.asList(
// Scala
"abstract", "case", "catch", "class", "def",
"do", "else", "extends", "false", "final",
"finally", "for", "forSome", "if", "implicit",
"import", "lazy", "match", "new", "null",
"object", "override", "package", "private", "protected",
"return", "sealed", "super", "this", "throw",
"trait", "try", "true", "type", "val",
"var", "while", "with", "yield",
// Scala-interop languages keywords
"abstract", "continue", "switch", "assert",
"default", "synchronized", "goto",
"break", "double", "implements", "byte",
"public", "throws", "enum", "instanceof", "transient",
"int", "short", "char", "interface", "static",
"void", "finally", "long", "strictfp", "volatile", "const", "float",
"native")
);
defaultIncludes = new HashSet<String>(
Arrays.asList("double",
"Int",
"Long",
"Float",
"Double",
"char",
"float",
"String",
"boolean",
"Boolean",
"Double",
"Integer",
"Long",
"Float",
"List",
"Set",
"Map")
);
typeMapping = new HashMap<String, String>();
typeMapping.put("string", "String");
typeMapping.put("boolean", "Boolean");
typeMapping.put("integer", "Int");
typeMapping.put("float", "Float");
typeMapping.put("long", "Long");
typeMapping.put("double", "Double");
typeMapping.put("number", "BigDecimal");
typeMapping.put("date-time", "LocalDateTime");
typeMapping.put("date", "LocalDateTime");
typeMapping.put("file", "File");
typeMapping.put("array", "Seq");
typeMapping.put("list", "List");
typeMapping.put("map", "Map");
typeMapping.put("object", "Object");
typeMapping.put("binary", "Array[Byte]");
typeMapping.put("Date", "LocalDateTime");
typeMapping.put("DateTime", "LocalDateTime");
additionalProperties.put("modelPackage", modelPackage());
additionalProperties.put("apiPackage", apiPackage());
additionalProperties.put("appName", "Swagger Sample");
additionalProperties.put("appDescription", "A sample swagger server");
additionalProperties.put("infoUrl", "http://swagger.io");
additionalProperties.put("infoEmail", "apiteam@swagger.io");
additionalProperties.put("licenseInfo", "Apache 2.0");
additionalProperties.put("licenseUrl", "http://apache.org/licenses/LICENSE-2.0.html");
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
} else {
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
}
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("build.sbt", "", "build.sbt"));
supportingFiles.add(new SupportingFile("Server.mustache", sourceFolder, "Server.scala"));
supportingFiles.add(new SupportingFile("DataAccessor.mustache", sourceFolder, "DataAccessor.scala"));
supportingFiles.add(new SupportingFile("project/build.properties", "project", "build.properties"));
supportingFiles.add(new SupportingFile("project/plugins.sbt", "project", "plugins.sbt"));
supportingFiles.add(new SupportingFile("sbt", "", "sbt"));
supportingFiles.add(new SupportingFile("endpoint.mustache", sourceFolder, "endpoint.scala"));
supportingFiles.add(new SupportingFile("errors.mustache", sourceFolder, "errors.scala"));
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"String",
"Boolean",
"Double",
"Int",
"Integer",
"Long",
"Float",
"Any",
"AnyVal",
"AnyRef",
"Object")
);
instantiationTypes.put("array", "ArrayList");
instantiationTypes.put("map", "HashMap");
importMapping = new HashMap<String, String>();
importMapping.put("BigDecimal", "java.math.BigDecimal");
importMapping.put("UUID", "java.util.UUID");
importMapping.put("File", "java.io.File");
importMapping.put("Date", "java.util.Date");
importMapping.put("Timestamp", "java.sql.Timestamp");
importMapping.put("Map", "scala.collection.immutable.Map");
importMapping.put("HashMap", "scala.collection.immutable.HashMap");
importMapping.put("Seq", "scala.collection.immutable.Seq");
importMapping.put("ArrayBuffer", "scala.collection.mutable.ArrayBuffer");
importMapping.put("DateTime", "java.time.LocalDateTime");
importMapping.put("LocalDateTime", "java.time.LocalDateTime");
importMapping.put("LocalDate", "java.time.LocalDate");
importMapping.put("LocalTime", "java.time.LocalTime");
cliOptions.clear();
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "Finch package name (e.g. io.swagger.petstore).")
.defaultValue(this.packageName));
cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
}
@Override
public CodegenType getTag() {
return CodegenType.SERVER;
}
@Override
public String getName() {
return "finch";
}
@Override
public String getHelp() {
return "Generates a Scala server application with Finch.";
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
}
@Override
public String apiFileFolder() {
return outputFolder + File.separator + sourceFolder + File.separator + apiPackage().replace('.', File.separatorChar);
}
@Override
public String modelFileFolder() {
return outputFolder + File.separator + sourceFolder + File.separator + modelPackage().replace('.', File.separatorChar);
}
/**
* Convert Swagger Model object to Codegen Model object
*
* @param name the name of the model
* @param model Swagger Model object
* @param allDefinitions a map of all Swagger models from the spec
* @return Codegen Model object
*/
@Override
public CodegenModel fromModel(String name, Model model, Map<String, Model> allDefinitions) {
CodegenModel codegenModel = super.fromModel(name, model, allDefinitions);
return codegenModel;
}
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation op : operationList) {
op.httpMethod = op.httpMethod.toLowerCase();
String path = new String(op.path);
// remove first /
if (path.startsWith("/")) {
path = path.substring(1);
}
// remove last /
if (path.endsWith("/")) {
path = path.substring(0, path.length()-1);
}
String[] items = path.split("/", -1);
String scalaPath = "";
int pathParamIndex = 0;
for (int i = 0; i < items.length; ++i) {
if (items[i].matches("^\\{(.*)\\}$")) { // wrap in {}
// find the datatype of the parameter
final CodegenParameter cp = op.pathParams.get(pathParamIndex);
// TODO: Handle non-primitives…
scalaPath = scalaPath + cp.dataType.toLowerCase();
pathParamIndex++;
} else {
scalaPath = scalaPath + "\"" + items[i] + "\"";
}
if (i != items.length -1) {
scalaPath = scalaPath + " :: ";
}
}
for (CodegenParameter p : op.allParams) {
// TODO: This hacky, should be converted to mappings if possible to keep it clean.
// This could also be done using template imports
if(Boolean.TRUE.equals(p.isPrimitiveType)) {
p.vendorExtensions.put("x-codegen-normalized-path-type", p.dataType.toLowerCase());
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType);
} else if(Boolean.TRUE.equals(p.isBodyParam)) {
p.vendorExtensions.put("x-codegen-normalized-path-type", "jsonBody["+ p.dataType + "]");
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType);
} else if(Boolean.TRUE.equals(p.isContainer) || Boolean.TRUE.equals(p.isListContainer)) {
p.vendorExtensions.put("x-codegen-normalized-path-type", "params(\""+ p.paramName + "\")");
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType.replaceAll("^[^\\[]+", "Seq"));
} else if(Boolean.TRUE.equals(p.isFile)) {
p.vendorExtensions.put("x-codegen-normalized-path-type", "fileUpload(\""+ p.paramName + "\")");
p.vendorExtensions.put("x-codegen-normalized-input-type", "FileUpload");
} else {
p.vendorExtensions.put("x-codegen-normalized-path-type", p.dataType);
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType);
}
}
op.vendorExtensions.put("x-codegen-path", scalaPath);
}
return objs;
}
@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 escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
}

View File

@@ -177,8 +177,11 @@ public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig
}
@Override
public String escapeReservedWord(String name) {
return name + "_";
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@Override

View File

@@ -236,10 +236,13 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
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

View File

@@ -43,7 +43,7 @@ public class GoClientCodegen extends DefaultCodegen implements CodegenConfig {
modelDocTemplateFiles.put("model_doc.mustache", ".md");
apiDocTemplateFiles.put("api_doc.mustache", ".md");
templateDir = "go";
embeddedTemplateDir = templateDir = "go";
setReservedWordsLowerCase(
Arrays.asList(
@@ -180,9 +180,10 @@ public class GoClientCodegen extends DefaultCodegen implements CodegenConfig {
// - XName
// - X_Name
// ... or maybe a suffix?
// - Name_ ... think this will work.
// FIXME: This should also really be a customizable option
// - Name_ ... think this will work.
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return camelize(name) + '_';
}

View File

@@ -204,6 +204,9 @@ public class GoServerCodegen extends DefaultCodegen implements CodegenConfig {
*/
@Override
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; // add an underscore to the name
}

View File

@@ -154,8 +154,11 @@ public class HaskellServantCodegen extends DefaultCodegen implements CodegenConf
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return name + "_";
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
public String firstLetterToUpper(String word) {

View File

@@ -68,7 +68,7 @@ public class JMeterCodegen extends DefaultCodegen implements CodegenConfig {
* 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 = "JMeter";
embeddedTemplateDir = templateDir = "JMeter";
/*
* Api Package. Optional, if needed, this can be used in templates
@@ -119,10 +119,13 @@ public class JMeterCodegen extends DefaultCodegen implements CodegenConfig {
*
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name
}
@Override
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
/**
* Location to write model files. You can use the modelPackage() as defined when the class is

View File

@@ -27,8 +27,6 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
protected boolean addConsumesProducesJson = true;
protected boolean useJaxbAnnotations = true;
protected boolean useBeanValidation = false;
protected boolean generateSpringApplication = false;
@@ -41,7 +39,7 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
protected boolean useWadlFeature = false;
protected boolean useMultipartFeature = false;
protected boolean useBeanValidationFeature = false;
protected boolean generateSpringBootApplication= false;
@@ -56,6 +54,10 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
protected boolean useLoggingFeatureForTests = false;
protected boolean useAnnotatedBasePath = false;
protected boolean generateNonSpringApplication = false;
public JavaCXFServerCodegen()
{
super();
@@ -84,7 +86,6 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
cliOptions.add(CliOption.newBoolean(USE_JAXB_ANNOTATIONS, "Use JAXB annotations for XML"));
cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations"));
cliOptions.add(CliOption.newBoolean(GENERATE_SPRING_APPLICATION, "Generate Spring application"));
cliOptions.add(CliOption.newBoolean(USE_SPRING_ANNOTATION_CONFIG, "Use Spring Annotation Config"));
@@ -108,6 +109,9 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
cliOptions
.add(CliOption.newBoolean(ADD_CONSUMES_PRODUCES_JSON, "Add @Consumes/@Produces Json to API interface"));
cliOptions.add(CliOption.newBoolean(USE_ANNOTATED_BASE_PATH, "Use @Path annotations for basePath"));
cliOptions.add(CliOption.newBoolean(GENERATE_NON_SPRING_APPLICATION, "Generate non-Spring application"));
}
@@ -121,11 +125,6 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
this.setUseJaxbAnnotations(useJaxbAnnotationsProp);
}
if (additionalProperties.containsKey(USE_BEANVALIDATION)) {
boolean useBeanValidationProp = convertPropertyToBooleanAndWriteBack(USE_BEANVALIDATION);
this.setUseBeanValidation(useBeanValidationProp);
}
if (additionalProperties.containsKey(ADD_CONSUMES_PRODUCES_JSON)) {
this.setAddConsumesProducesJson(convertPropertyToBooleanAndWriteBack(ADD_CONSUMES_PRODUCES_JSON));
}
@@ -159,6 +158,16 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
this.setGenerateJbossDeploymentDescriptor(generateJbossDeploymentDescriptorProp);
}
if (additionalProperties.containsKey(USE_ANNOTATED_BASE_PATH)) {
boolean useAnnotatedBasePathProp = convertPropertyToBooleanAndWriteBack(USE_ANNOTATED_BASE_PATH);
this.setUseAnnotatedBasePath(useAnnotatedBasePathProp);
}
if (additionalProperties.containsKey(GENERATE_NON_SPRING_APPLICATION)) {
boolean generateNonSpringApplication = convertPropertyToBooleanAndWriteBack(GENERATE_NON_SPRING_APPLICATION);
this.setGenerateNonSpringApplication(generateNonSpringApplication);
}
supportingFiles.clear(); // Don't need extra files provided by AbstractJAX-RS & Java Codegen
writeOptional(outputFolder, new SupportingFile("server/pom.mustache", "", "pom.xml"));
@@ -191,10 +200,12 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
(testResourcesFolder + '/'), "application.properties"));
}
}
if (this.generateNonSpringApplication) {
writeOptional(outputFolder, new SupportingFile("server/nonspring-web.mustache",
("src/main/webapp/WEB-INF"), "web.xml"));
}
}
@Override
@@ -224,10 +235,6 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
return "Generates a Java JAXRS Server application based on Apache CXF framework.";
}
public void setUseBeanValidation(boolean useBeanValidation) {
this.useBeanValidation = useBeanValidation;
}
public void setGenerateSpringApplication(boolean generateSpringApplication) {
this.generateSpringApplication = generateSpringApplication;
}
@@ -293,4 +300,12 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
this.addConsumesProducesJson = addConsumesProducesJson;
}
public void setUseAnnotatedBasePath(boolean useAnnotatedBasePath) {
this.useAnnotatedBasePath = useAnnotatedBasePath;
}
public void setGenerateNonSpringApplication(boolean generateNonSpringApplication) {
this.generateNonSpringApplication = generateNonSpringApplication;
}
}

View File

@@ -1,8 +1,10 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenModel;
import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.SupportingFile;
import io.swagger.codegen.languages.features.BeanValidationFeatures;
import java.io.File;
@@ -13,7 +15,10 @@ import java.io.File;
* in /src/gen/java and a sample ServiceImpl in /src/main/java. The API uses CDI
* to get an instance of ServiceImpl that implements the Service interface.
*/
public class JavaJAXRSCXFCDIServerCodegen extends JavaJAXRSSpecServerCodegen {
public class JavaJAXRSCXFCDIServerCodegen extends JavaJAXRSSpecServerCodegen implements BeanValidationFeatures {
protected boolean useBeanValidation = true;
/**
* Default constructor
*/
@@ -32,6 +37,8 @@ public class JavaJAXRSCXFCDIServerCodegen extends JavaJAXRSSpecServerCodegen {
// Updated template directory
embeddedTemplateDir = templateDir = JAXRS_TEMPLATE_DIRECTORY_NAME
+ File.separator + "cxf-cdi";
cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations"));
}
@Override
@@ -43,6 +50,14 @@ public class JavaJAXRSCXFCDIServerCodegen extends JavaJAXRSSpecServerCodegen {
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(USE_BEANVALIDATION)) {
this.setUseBeanValidation(convertPropertyToBoolean(USE_BEANVALIDATION));
}
if (useBeanValidation) {
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);
}
supportingFiles.clear(); // Don't need extra files provided by AbstractJAX-RS & Java Codegen
// writeOptional means these files are only written if they don't already exist
@@ -73,4 +88,7 @@ public class JavaJAXRSCXFCDIServerCodegen extends JavaJAXRSSpecServerCodegen {
+ "Apache CXF runtime and a Java EE runtime with CDI enabled.";
}
public void setUseBeanValidation(boolean useBeanValidation) {
this.useBeanValidation = useBeanValidation;
}
}

View File

@@ -2,27 +2,30 @@ package io.swagger.codegen.languages;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenModel;
import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.SupportingFile;
import io.swagger.codegen.languages.features.BeanValidationFeatures;
import io.swagger.models.Operation;
import io.swagger.models.Swagger;
import io.swagger.models.properties.Property;
import io.swagger.util.Json;
import org.apache.commons.io.FileUtils;
public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen
{
public JavaJAXRSSpecServerCodegen()
{
public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen
{
public JavaJAXRSSpecServerCodegen()
{
super();
invokerPackage = "io.swagger.api";
artifactId = "swagger-jaxrs-server";
@@ -67,26 +70,27 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen
library.setEnum(supportedLibraries);
cliOptions.add(library);
}
@Override
public void processOpts()
{
super.processOpts();
supportingFiles.clear(); // Don't need extra files provided by AbstractJAX-RS & Java Codegen
}
@Override
public void processOpts()
{
super.processOpts();
supportingFiles.clear(); // Don't need extra files provided by AbstractJAX-RS & Java Codegen
writeOptional(outputFolder, new SupportingFile("pom.mustache", "", "pom.xml"));
writeOptional(outputFolder, new SupportingFile("RestApplication.mustache",
(sourceFolder + '/' + invokerPackage).replace(".", "/"), "RestApplication.java"));
}
}
@Override
public String getName()
{
return "jaxrs-spec";
}
@Override
public String getName()
{
return "jaxrs-spec";
}
@Override
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
@@ -127,16 +131,16 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen
model.imports.remove("JsonProperty");
}
@Override
@Override
public void preprocessSwagger(Swagger swagger) {
//copy input swagger to output folder
try {
String swaggerJson = Json.pretty(swagger);
//copy input swagger to output folder
try {
String swaggerJson = Json.pretty(swagger);
FileUtils.writeStringToFile(new File(outputFolder + File.separator + "swagger.json"), swaggerJson);
} catch (IOException e) {
} catch (IOException e) {
throw new RuntimeException(e.getMessage(), e.getCause());
}
super.preprocessSwagger(swagger);
}
super.preprocessSwagger(swagger);
}
@Override

View File

@@ -1,6 +1,7 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.codegen.languages.features.BeanValidationFeatures;
import io.swagger.models.Operation;
import java.util.*;
@@ -12,7 +13,7 @@ public class JavaJerseyServerCodegen extends AbstractJavaJAXRSServerCodegen {
protected static final String LIBRARY_JERSEY1 = "jersey1";
protected static final String LIBRARY_JERSEY2 = "jersey2";
/**
* Default library template to use. (Default:{@value #DEFAULT_LIBRARY})
*/
@@ -84,7 +85,7 @@ public class JavaJerseyServerCodegen extends AbstractJavaJAXRSServerCodegen {
if (StringUtils.isEmpty(library)) {
setLibrary(DEFAULT_LIBRARY);
}
if ( additionalProperties.containsKey(CodegenConstants.IMPL_FOLDER)) {
implFolder = (String) additionalProperties.get(CodegenConstants.IMPL_FOLDER);
}
@@ -160,5 +161,5 @@ public class JavaJerseyServerCodegen extends AbstractJavaJAXRSServerCodegen {
opList.add(co);
co.baseName = basePath;
}
}

View File

@@ -1,6 +1,7 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.codegen.languages.features.BeanValidationFeatures;
import io.swagger.codegen.languages.features.JbossFeature;
import io.swagger.models.Operation;
import org.apache.commons.lang3.BooleanUtils;
@@ -12,7 +13,7 @@ import java.util.*;
public class JavaResteasyServerCodegen extends AbstractJavaJAXRSServerCodegen implements JbossFeature {
protected boolean generateJbossDeploymentDescriptor = true;
public JavaResteasyServerCodegen() {
super();
@@ -58,7 +59,7 @@ public class JavaResteasyServerCodegen extends AbstractJavaJAXRSServerCodegen im
GENERATE_JBOSS_DEPLOYMENT_DESCRIPTOR);
this.setGenerateJbossDeploymentDescriptor(generateJbossDeploymentDescriptorProp);
}
writeOptional(outputFolder, new SupportingFile("pom.mustache", "", "pom.xml"));
writeOptional(outputFolder, new SupportingFile("gradle.mustache", "", "build.gradle"));
writeOptional(outputFolder, new SupportingFile("settingsGradle.mustache", "", "settings.gradle"));
@@ -214,7 +215,7 @@ public class JavaResteasyServerCodegen extends AbstractJavaJAXRSServerCodegen im
return objs;
}
public void setGenerateJbossDeploymentDescriptor(boolean generateJbossDeploymentDescriptor) {
this.generateJbossDeploymentDescriptor = generateJbossDeploymentDescriptor;
}

View File

@@ -84,7 +84,7 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
modelTestTemplateFiles.put("model_test.mustache", ".js");
apiTemplateFiles.put("api.mustache", ".js");
apiTestTemplateFiles.put("api_test.mustache", ".js");
templateDir = "Javascript";
embeddedTemplateDir = templateDir = "Javascript";
apiPackage = "api";
modelPackage = "model";
modelDocTemplateFiles.put("model_doc.mustache", ".md");
@@ -313,7 +313,10 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@@ -1021,6 +1024,10 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
@Override
public String toEnumVarName(String value, String datatype) {
if (value.length() == 0) {
return "empty";
}
// for symbol, e.g. $, #
if (getSymbolName(value) != null) {
return (getSymbolName(value)).toUpperCase();

View File

@@ -102,7 +102,10 @@ public class JavascriptClosureAngularClientCodegen extends DefaultCodegen implem
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@@ -1,20 +1,7 @@
package io.swagger.codegen.languages;
import static com.google.common.base.Strings.isNullOrEmpty;
import static io.swagger.codegen.CodegenConstants.OPTIONAL_PROJECT_FILE;
import static io.swagger.codegen.CodegenConstants.OPTIONAL_PROJECT_FILE_DESC;
import static io.swagger.codegen.CodegenConstants.PACKAGE_NAME;
import static io.swagger.codegen.CodegenConstants.PACKAGE_VERSION;
import static io.swagger.codegen.CodegenConstants.RETURN_ICOLLECTION;
import static io.swagger.codegen.CodegenConstants.RETURN_ICOLLECTION_DESC;
import static io.swagger.codegen.CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG;
import static io.swagger.codegen.CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC;
import static io.swagger.codegen.CodegenConstants.SOURCE_FOLDER;
import static io.swagger.codegen.CodegenConstants.SOURCE_FOLDER_DESC;
import static io.swagger.codegen.CodegenConstants.USE_COLLECTION;
import static io.swagger.codegen.CodegenConstants.USE_COLLECTION_DESC;
import static io.swagger.codegen.CodegenConstants.USE_DATETIME_OFFSET;
import static io.swagger.codegen.CodegenConstants.USE_DATETIME_OFFSET_DESC;
import static io.swagger.codegen.CodegenConstants.*;
import static io.swagger.codegen.CodegenType.SERVER;
import static java.util.Arrays.asList;
import static java.util.UUID.randomUUID;
@@ -71,6 +58,9 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen {
outputFolder = "generated-code" + File.separator + getName();
apiTemplateFiles.put("api.mustache", ".cs");
// Early versions use no prefix for interfaces. Defaulting to I- common practice would break existing users.
setInterfacePrefix("");
// contextually reserved words
setReservedWordsLowerCase(
asList("var", "async", "await", "dynamic", "yield")
@@ -82,6 +72,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen {
addOption(PACKAGE_NAME, "C# package name (convention: Title.Case).", packageName);
addOption(PACKAGE_VERSION, "C# package version.", packageVersion);
addOption(SOURCE_FOLDER, SOURCE_FOLDER_DESC, sourceFolder);
addOption(INTERFACE_PREFIX, INTERFACE_PREFIX_DESC, interfacePrefix);
// CLI Switches
addSwitch(SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_BY_REQUIRED_FLAG_DESC, sortParamsByRequiredFlag);
@@ -292,6 +283,10 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen {
@Override
public String toEnumVarName(final String name, final String datatype) {
if (name.length() == 0) {
return "Empty";
}
final String enumName = camelize(
sanitizeName(name)
.replaceFirst("^_", "")

View File

@@ -147,13 +147,16 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
/**
* 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
* those terms here. This logic is only called if a variable matches the reserved words
*
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
/**
@@ -307,7 +310,12 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
if (info.getTitle() != null) {
// when info.title is defined, use it for projectName
// used in package.json
projectName = dashize(info.getTitle());
projectName = info.getTitle()
.replaceAll("[^a-zA-Z0-9]", "-")
.replaceAll("^[-]*", "")
.replaceAll("[-]*$", "")
.replaceAll("[-]{2,}", "-")
.toLowerCase();
this.additionalProperties.put("projectName", projectName);
}
}

View File

@@ -539,8 +539,17 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
return toVarName(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 reserved words
*
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@@ -109,7 +109,8 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC).defaultValue(Boolean.TRUE.toString()));
cliOptions.add(CliOption.newBoolean(CodegenConstants.ENSURE_UNIQUE_PARAMS, CodegenConstants
.ENSURE_UNIQUE_PARAMS_DESC).defaultValue(Boolean.TRUE.toString()));
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP, CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC)
.defaultValue(Boolean.TRUE.toString()));
}
@@ -134,6 +135,14 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
additionalProperties.put("apiDocPath", apiDocPath);
additionalProperties.put("modelDocPath", modelDocPath);
// default HIDE_GENERATION_TIMESTAMP to true
if (!additionalProperties.containsKey(CodegenConstants.HIDE_GENERATION_TIMESTAMP)) {
additionalProperties.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, Boolean.TRUE.toString());
} else {
additionalProperties.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP,
Boolean.valueOf(additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP).toString()));
}
supportingFiles.add(new SupportingFile("ApiClient.mustache", ("lib/" + modulePathPart).replace('/', File.separatorChar), "ApiClient.pm"));
supportingFiles.add(new SupportingFile("Configuration.mustache", ("lib/" + modulePathPart).replace('/', File.separatorChar), "Configuration.pm"));
supportingFiles.add(new SupportingFile("ApiFactory.mustache", ("lib/" + modulePathPart).replace('/', File.separatorChar), "ApiFactory.pm"));
@@ -162,6 +171,9 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@@ -396,7 +408,7 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public void setParameterExampleValue(CodegenParameter p) {
if (Boolean.TRUE.equals(p.isString) || Boolean.TRUE.equals(p.isBinary) ||
if (Boolean.TRUE.equals(p.isString) || Boolean.TRUE.equals(p.isBinary) ||
Boolean.TRUE.equals(p.isByteArray) || Boolean.TRUE.equals(p.isFile)) {
p.example = "'" + p.example + "'";
} else if (Boolean.TRUE.equals(p.isBoolean)) {

View File

@@ -232,17 +232,25 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
this.setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE));
// Update the invokerPackage for the default apiPackage and modelPackage
apiPackage = invokerPackage + "\\" + apiDirName;
modelPackage = invokerPackage + "\\" + modelDirName;
} else {
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
}
if (!additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) {
additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage);
if (additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) {
// Update model package to contain the specified model package name and the invoker package
modelPackage = invokerPackage + "\\" + (String) additionalProperties.get(CodegenConstants.MODEL_PACKAGE);
}
additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage);
if (!additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
if (additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
// Update model package to contain the specified model package name and the invoker package
apiPackage = invokerPackage + "\\" + (String) additionalProperties.get(CodegenConstants.API_PACKAGE);
}
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
if (additionalProperties.containsKey(COMPOSER_PROJECT_NAME)) {
this.setComposerProjectName((String) additionalProperties.get(COMPOSER_PROJECT_NAME));
@@ -307,7 +315,10 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@@ -480,7 +491,13 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
// add prefix and/or suffic only if name does not start wth \ (e.g. \DateTime)
if (!name.matches("^\\\\.*")) {
name = modelNamePrefix + name + modelNameSuffix;
if (!StringUtils.isEmpty(modelNamePrefix)) {
name = modelNamePrefix + "_" + name;
}
if (!StringUtils.isEmpty(modelNameSuffix)) {
name = name + "_" + modelNameSuffix;
}
}
// camelize the model name
@@ -644,6 +661,10 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String toEnumVarName(String name, String datatype) {
if (name.length() == 0) {
return "EMPTY";
}
// number
if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) {
String varName = name;

View File

@@ -251,7 +251,10 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@@ -198,8 +198,11 @@ public class Qt5CPPGenerator extends DefaultCodegen implements CodegenConfig {
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
/**

View File

@@ -186,7 +186,10 @@ public class Rails5ServerCodegen extends DefaultCodegen implements CodegenConfig
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@@ -330,7 +330,10 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@@ -568,6 +571,10 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String toEnumVarName(String name, String datatype) {
if (name.length() == 0) {
return "EMPTY";
}
// number
if ("Integer".equals(datatype) || "Float".equals(datatype)) {
String varName = name;

View File

@@ -65,7 +65,6 @@ public class ScalatraServerCodegen extends AbstractScalaCodegen implements Codeg
// mapped to String as a workaround
typeMapping.put("binary", "String");
additionalProperties.put("appName", "Swagger Sample");
additionalProperties.put("appName", "Swagger Sample");
additionalProperties.put("appDescription", "A sample swagger server");
additionalProperties.put("infoUrl", "http://swagger.io");

View File

@@ -107,10 +107,13 @@ public class SilexServerCodegen extends DefaultCodegen implements CodegenConfig
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@Override
public String apiFileFolder() {
return (outputFolder + "/" + apiPackage()).replace('/', File.separatorChar);

View File

@@ -104,7 +104,10 @@ public class SinatraServerCodegen extends DefaultCodegen implements CodegenConfi
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@@ -118,7 +118,10 @@ public class SlimFrameworkServerCodegen extends DefaultCodegen implements Codege
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@@ -1,6 +1,7 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.codegen.languages.features.BeanValidationFeatures;
import io.swagger.models.Operation;
import io.swagger.models.Path;
import io.swagger.models.Swagger;
@@ -8,16 +9,18 @@ import io.swagger.models.Swagger;
import java.io.File;
import java.util.*;
public class SpringCodegen extends AbstractJavaCodegen {
public class SpringCodegen extends AbstractJavaCodegen implements BeanValidationFeatures {
public static final String DEFAULT_LIBRARY = "spring-boot";
public static final String TITLE = "title";
public static final String CONFIG_PACKAGE = "configPackage";
public static final String BASE_PACKAGE = "basePackage";
public static final String INTERFACE_ONLY = "interfaceOnly";
public static final String DELEGATE_PATTERN = "delegatePattern";
public static final String SINGLE_CONTENT_TYPES = "singleContentTypes";
public static final String JAVA_8 = "java8";
public static final String ASYNC = "async";
public static final String RESPONSE_WRAPPER = "responseWrapper";
public static final String USE_TAGS = "useTags";
public static final String SPRING_MVC_LIBRARY = "spring-mvc";
public static final String SPRING_CLOUD_LIBRARY = "spring-cloud";
@@ -25,10 +28,13 @@ public class SpringCodegen extends AbstractJavaCodegen {
protected String configPackage = "io.swagger.configuration";
protected String basePackage = "io.swagger";
protected boolean interfaceOnly = false;
protected boolean delegatePattern = false;
protected boolean singleContentTypes = false;
protected boolean java8 = false;
protected boolean async = false;
protected String responseWrapper = "";
protected boolean useTags = false;
protected boolean useBeanValidation = true;
public SpringCodegen() {
super();
@@ -50,10 +56,13 @@ public class SpringCodegen extends AbstractJavaCodegen {
cliOptions.add(new CliOption(CONFIG_PACKAGE, "configuration package for generated code"));
cliOptions.add(new CliOption(BASE_PACKAGE, "base package for generated code"));
cliOptions.add(CliOption.newBoolean(INTERFACE_ONLY, "Whether to generate only API interface stubs without the server files."));
cliOptions.add(CliOption.newBoolean(DELEGATE_PATTERN, "Whether to generate the server files using the delegate pattern"));
cliOptions.add(CliOption.newBoolean(SINGLE_CONTENT_TYPES, "Whether to select only one produces/consumes content-type by operation."));
cliOptions.add(CliOption.newBoolean(JAVA_8, "use java8 default interface"));
cliOptions.add(CliOption.newBoolean(ASYNC, "use async Callable controllers"));
cliOptions.add(new CliOption(RESPONSE_WRAPPER, "wrap the responses in given type (Future,Callable,CompletableFuture,ListenableFuture,DeferredResult,HystrixCommand,RxObservable,RxSingle or fully qualified type)"));
cliOptions.add(CliOption.newBoolean(USE_TAGS, "use tags for creating interface and controller classnames"));
cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations"));
supportedLibraries.put(DEFAULT_LIBRARY, "Spring-boot Server application using the SpringFox integration.");
supportedLibraries.put(SPRING_MVC_LIBRARY, "Spring-MVC Server application using the SpringFox integration.");
@@ -121,10 +130,18 @@ public class SpringCodegen extends AbstractJavaCodegen {
this.setInterfaceOnly(Boolean.valueOf(additionalProperties.get(INTERFACE_ONLY).toString()));
}
if (additionalProperties.containsKey(DELEGATE_PATTERN)) {
this.setDelegatePattern(Boolean.valueOf(additionalProperties.get(DELEGATE_PATTERN).toString()));
}
if (additionalProperties.containsKey(SINGLE_CONTENT_TYPES)) {
this.setSingleContentTypes(Boolean.valueOf(additionalProperties.get(SINGLE_CONTENT_TYPES).toString()));
}
if (additionalProperties.containsKey(JAVA_8)) {
this.setJava8(Boolean.valueOf(additionalProperties.get(JAVA_8).toString()));
}
if (additionalProperties.containsKey(ASYNC)) {
this.setAsync(Boolean.valueOf(additionalProperties.get(ASYNC).toString()));
}
@@ -133,9 +150,26 @@ public class SpringCodegen extends AbstractJavaCodegen {
this.setResponseWrapper((String) additionalProperties.get(RESPONSE_WRAPPER));
}
if (additionalProperties.containsKey(USE_TAGS)) {
this.setUseTags(Boolean.valueOf(additionalProperties.get(USE_TAGS).toString()));
}
if (additionalProperties.containsKey(USE_BEANVALIDATION)) {
this.setUseBeanValidation(convertPropertyToBoolean(USE_BEANVALIDATION));
}
if (useBeanValidation) {
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);
}
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
if (this.interfaceOnly && this.delegatePattern) {
throw new IllegalArgumentException(
String.format("Can not generate code with `%s` and `%s` both true.", DELEGATE_PATTERN, INTERFACE_ONLY));
}
if (!this.interfaceOnly) {
if (library.equals(DEFAULT_LIBRARY)) {
supportingFiles.add(new SupportingFile("homeController.mustache",
@@ -194,6 +228,16 @@ public class SpringCodegen extends AbstractJavaCodegen {
(sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "JacksonConfiguration.java"));
}
}
if (!this.delegatePattern && this.java8) {
additionalProperties.put("jdk8-no-delegate", true);
}
if (this.delegatePattern) {
additionalProperties.put("isDelegate", "true");
apiTemplateFiles.put("apiDelegate.mustache", "Delegate.java");
}
if (this.java8) {
additionalProperties.put("javaVersion", "1.8");
@@ -239,7 +283,7 @@ public class SpringCodegen extends AbstractJavaCodegen {
@Override
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
if(library.equals(DEFAULT_LIBRARY) || library.equals(SPRING_MVC_LIBRARY)) {
if((library.equals(DEFAULT_LIBRARY) || library.equals(SPRING_MVC_LIBRARY)) && !useTags) {
String basePath = resourcePath;
if (basePath.startsWith("/")) {
basePath = basePath.substring(1);
@@ -408,6 +452,8 @@ public class SpringCodegen extends AbstractJavaCodegen {
public void setInterfaceOnly(boolean interfaceOnly) { this.interfaceOnly = interfaceOnly; }
public void setDelegatePattern(boolean delegatePattern) { this.delegatePattern = delegatePattern; }
public void setSingleContentTypes(boolean singleContentTypes) {
this.singleContentTypes = singleContentTypes;
}
@@ -418,6 +464,10 @@ public class SpringCodegen extends AbstractJavaCodegen {
public void setResponseWrapper(String responseWrapper) { this.responseWrapper = responseWrapper; }
public void setUseTags(boolean useTags) {
this.useTags = useTags;
}
@Override
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
super.postProcessModelProperty(model, property);
@@ -462,5 +512,9 @@ public class SpringCodegen extends AbstractJavaCodegen {
return objs;
}
public void setUseBeanValidation(boolean useBeanValidation) {
this.useBeanValidation = useBeanValidation;
}
}

View File

@@ -77,7 +77,10 @@ public class StaticDocCodegen extends DefaultCodegen implements CodegenConfig {
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@@ -24,6 +24,8 @@ public class StaticHtml2Generator extends DefaultCodegen implements CodegenConfi
protected String artifactVersion = "1.0.0";
protected String jsProjectName;
protected String jsModuleName;
protected String perlModuleName = "WWW::SwaggerClient";
protected String pythonPackageName = "swagger_client";
public StaticHtml2Generator() {
super();
@@ -40,6 +42,8 @@ public class StaticHtml2Generator extends DefaultCodegen implements CodegenConfi
cliOptions.add(new CliOption("licenseUrl", "a URL pointing to the full license"));
cliOptions.add(new CliOption(CodegenConstants.INVOKER_PACKAGE, CodegenConstants.INVOKER_PACKAGE_DESC));
cliOptions.add(new CliOption(CodegenConstants.PHP_INVOKER_PACKAGE, CodegenConstants.PHP_INVOKER_PACKAGE_DESC));
cliOptions.add(new CliOption(CodegenConstants.PERL_MODULE_NAME, CodegenConstants.PERL_MODULE_NAME_DESC));
cliOptions.add(new CliOption(CodegenConstants.PYTHON_PACKAGE_NAME, CodegenConstants.PYTHON_PACKAGE_NAME_DESC));
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "C# package name"));
cliOptions.add(new CliOption(CodegenConstants.GROUP_ID, CodegenConstants.GROUP_ID_DESC));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_ID, CodegenConstants.ARTIFACT_ID_DESC));
@@ -53,6 +57,8 @@ public class StaticHtml2Generator extends DefaultCodegen implements CodegenConfi
additionalProperties.put("licenseUrl", "http://apache.org/licenses/LICENSE-2.0.html");
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
additionalProperties.put(CodegenConstants.PHP_INVOKER_PACKAGE, phpInvokerPackage);
additionalProperties.put(CodegenConstants.PERL_MODULE_NAME, perlModuleName);
additionalProperties.put(CodegenConstants.PYTHON_PACKAGE_NAME, pythonPackageName);
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);

View File

@@ -234,10 +234,13 @@ public class Swift3Codegen extends DefaultCodegen implements CodegenConfig {
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; // add an underscore to the name
}
@Override
public String modelFileFolder() {
return outputFolder + File.separator + sourceFolder + modelPackage().replace('.', File.separatorChar);
@@ -450,14 +453,7 @@ public class Swift3Codegen extends DefaultCodegen implements CodegenConfig {
@Override
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions, Swagger swagger) {
path = normalizePath(path); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
List<Parameter> parameters = operation.getParameters();
parameters = Lists.newArrayList(Iterators.filter(parameters.iterator(), new Predicate<Parameter>() {
@Override
public boolean apply(@Nullable Parameter parameter) {
return !(parameter instanceof HeaderParameter);
}
}));
operation.setParameters(parameters);
// issue 3914 - removed logic designed to remove any parameter of type HeaderParameter
return super.fromOperation(path, httpMethod, operation, definitions, swagger);
}
@@ -512,6 +508,10 @@ public class Swift3Codegen extends DefaultCodegen implements CodegenConfig {
@Override
public String toEnumVarName(String name, String datatype) {
if (name.length() == 0) {
return "empty";
}
// for symbol, e.g. $, #
if (getSymbolName(name) != null) {
return camelize(WordUtils.capitalizeFully(getSymbolName(name).toUpperCase()), true);

View File

@@ -232,11 +232,14 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
protected boolean isReservedWord(String word) {
return word != null && reservedWords.contains(word); //don't lowercase as super does
}
@Override
public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name
}
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; // add an underscore to the name
}
@Override
public String modelFileFolder() {
@@ -388,6 +391,10 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
@SuppressWarnings("static-method")
public String toSwiftyEnumName(String value) {
if (value.length() == 0) {
return "Empty";
}
if (value.matches("^-?\\d*\\.{0,1}\\d+.*")) { // starts with number
value = "Number" + value;
value = value.replaceAll("-", "Minus");
@@ -481,14 +488,7 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions, Swagger swagger) {
path = normalizePath(path); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
List<Parameter> parameters = operation.getParameters();
parameters = Lists.newArrayList(Iterators.filter(parameters.iterator(), new Predicate<Parameter>() {
@Override
public boolean apply(@Nullable Parameter parameter) {
return !(parameter instanceof HeaderParameter);
}
}));
operation.setParameters(parameters);
// issue 3914 - removed logic designed to remove any parameter of type HeaderParameter
return super.fromOperation(path, httpMethod, operation, definitions, swagger);
}

View File

@@ -264,7 +264,10 @@ public class TizenClientCodegen extends DefaultCodegen implements CodegenConfig
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@@ -3,6 +3,8 @@ package io.swagger.codegen.languages;
import java.io.File;
import io.swagger.codegen.SupportingFile;
import io.swagger.codegen.CodegenParameter;
import io.swagger.models.properties.Property;
public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCodegen {
@@ -19,7 +21,10 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
@Override
public void processOpts() {
super.processOpts();
supportingFiles.add(new SupportingFile("api.d.mustache", apiPackage().replace('.', File.separatorChar), "api.d.ts"));
supportingFiles.add(new SupportingFile("models.mustache", modelPackage().replace('.', File.separatorChar), "models.ts"));
supportingFiles.add(new SupportingFile("apis.mustache", apiPackage().replace('.', File.separatorChar), "api.ts"));
supportingFiles.add(new SupportingFile("index.mustache", getIndexDirectory(), "index.ts"));
supportingFiles.add(new SupportingFile("api.module.mustache", getIndexDirectory(), "api.module.ts"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));
@@ -29,9 +34,56 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
super();
outputFolder = "generated-code/typescript-angular";
modelTemplateFiles.put("model.mustache", ".ts");
apiTemplateFiles.put("api.mustache", ".ts");
apiTemplateFiles.put("api.mustache", ".ts");
embeddedTemplateDir = templateDir = "typescript-angular";
apiPackage = "API.Client";
modelPackage = "API.Client";
apiPackage = "api";
modelPackage = "model";
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
if(isLanguagePrimitive(swaggerType) || isLanguageGenericType(swaggerType)) {
return swaggerType;
}
return addModelPrefix(swaggerType);
}
@Override
public void postProcessParameter(CodegenParameter parameter) {
super.postProcessParameter(parameter);
parameter.dataType = addModelPrefix(parameter.dataType);
}
private String getIndexDirectory() {
String indexPackage = modelPackage.substring(0, Math.max(0, modelPackage.lastIndexOf('.')));
return indexPackage.replace('.', File.separatorChar);
}
private String addModelPrefix(String swaggerType) {
String type = null;
if (typeMapping.containsKey(swaggerType)) {
type = typeMapping.get(swaggerType);
} else {
type = swaggerType;
}
if (!isLanguagePrimitive(type) && !isLanguageGenericType(type)) {
type = "models." + swaggerType;
}
return type;
}
private boolean isLanguagePrimitive(String type) {
return languageSpecificPrimitives.contains(type);
}
private boolean isLanguageGenericType(String type) {
for (String genericType: languageGenericTypes) {
if (type.startsWith(genericType + "<")) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,216 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.models.Operation;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ZendExpressivePathHandlerServerCodegen extends AbstractPhpCodegen {
@Override
public CodegenType getTag() {
return CodegenType.SERVER;
}
@Override
public String getName() {
return "ze-ph";
}
@Override
public String getHelp() {
return "Generates PHP server stub using Zend Expressive ( https://zendframework.github.io/zend-expressive ) and Path Handler ( https://github.com/Articus/PathHandler ).";
}
public ZendExpressivePathHandlerServerCodegen() {
super();
embeddedTemplateDir = templateDir = "ze-ph";
invokerPackage = "App";
packagePath = "";
srcBasePath = "src" + File.separator + "App";
apiDirName = "Handler";
modelDirName = "DTO";
apiPackage = invokerPackage + "\\" + apiDirName;
modelPackage = invokerPackage + "\\" + modelDirName;
apiTestTemplateFiles.clear();
modelTestTemplateFiles.clear();
apiDocTemplateFiles.clear();
modelDocTemplateFiles.clear();
supportingFiles.add(new SupportingFile("README.md.mustache", packagePath, "README.md"));
supportingFiles.add(new SupportingFile("composer.json.mustache", packagePath, "composer.json"));
supportingFiles.add(new SupportingFile("index.php", packagePath + File.separator + "public", "index.php"));
supportingFiles.add(new SupportingFile("container.php", packagePath + File.separator + "application", "container.php"));
supportingFiles.add(new SupportingFile("config.yml", packagePath + File.separator + "application", "config.yml"));
supportingFiles.add(new SupportingFile("app.yml.mustache", packagePath + File.separator + "application" + File.separator + "config", "app.yml"));
supportingFiles.add(new SupportingFile("path_handler.yml.mustache", packagePath + File.separator + "application" + File.separator + "config", "path_handler.yml"));
supportingFiles.add(new SupportingFile("data_transfer.yml.mustache", packagePath + File.separator + "application" + File.separator + "config", "data_transfer.yml"));
supportingFiles.add(new SupportingFile("Date.php.mustache", packagePath + File.separator + srcBasePath + File.separator + "Strategy", "Date.php"));
supportingFiles.add(new SupportingFile("DateTime.php.mustache", packagePath + File.separator + srcBasePath + File.separator + "Strategy", "DateTime.php"));
supportingFiles.add(new SupportingFile("Type.php.mustache", packagePath + File.separator + srcBasePath + File.separator + "Validator", "Type.php"));
supportingFiles.add(new SupportingFile("ErrorMiddleware.php.mustache", packagePath + File.separator + srcBasePath, "ErrorMiddleware.php"));
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, "1.0.0");
}
/**
* Add operation to group
* Override of default grouping - group by resource path, not tag
*
* @param tag name of the tag
* @param resourcePath path of the resource
* @param operation Swagger Operation object
* @param co Codegen Operation object
* @param operations map of Codegen operations
*/
@Override
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
List<CodegenOperation> opList = operations.get(resourcePath);
if (opList == null) {
opList = new ArrayList<CodegenOperation>();
operations.put(resourcePath, opList);
}
//ignore duplicate operation ids - that means that operation has several tags
int counter = 0;
for (CodegenOperation op : opList) {
if (co.operationId.equals(op.operationId)) {
counter++;
}
}
if (counter == 0) {
co.operationIdLowerCase = co.operationId.toLowerCase();
opList.add(co);
co.baseName = tag;
}
}
/**
* Return the file name of the Api Test
*
* @param name the file name of the Api
* @return the file name of the Api
*/
@Override
public String toApiFilename(String name) {
return toApiName(name);
}
/**
* Output the API (class) name (capitalized) ending with "Api"
* Return DefaultApi if name is empty
*
* @param name the name of the Api
* @return capitalized Api name ending with "Api"
*/
@Override
public String toApiName(String name) {
//Remove }
name = name.replaceAll("[\\}]", "");
return super.toModelName(name);
}
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
objs = super.postProcessOperations(objs);
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
String interfaceToImplement;
StringBuilder interfacesToImplement = new StringBuilder();
String classMethod;
for (CodegenOperation op : operationList) {
switch (op.httpMethod) {
case "GET":
interfaceToImplement = "Operation\\GetInterface";
classMethod = "handleGet";
break;
case "POST":
interfaceToImplement = "Operation\\PostInterface";
classMethod = "handlePost";
break;
case "PATCH":
interfaceToImplement = "Operation\\PatchInterface";
classMethod = "handlePatch";
break;
case "PUT":
interfaceToImplement = "Operation\\PutInterface";
classMethod = "handlePut";
break;
case "DELETE":
interfaceToImplement = "Operation\\DeleteInterface";
classMethod = "handleDelete";
break;
default:
throw new RuntimeException("Unknown HTTP Method " + op.httpMethod + " not allowed");
}
if (interfacesToImplement.length() > 0) {
interfacesToImplement.append(", ");
}
interfacesToImplement.append(interfaceToImplement);
op.httpMethod = classMethod;
}
operations.put("interfacesToImplement", interfacesToImplement.toString());
return objs;
}
@Override
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
objs = super.postProcessSupportingFileData(objs);
Map<String, Object> apiInfo = (Map<String, Object>) objs.get("apiInfo");
List<Map<String, Object>> apis = (List<Map<String, Object>>) apiInfo.get("apis");
List<Map<String, Object>> routes = new ArrayList<Map<String, Object>>();
for (Map<String, Object> api : apis) {
String handler = (String) api.get("classname");
String url = (String) api.get("baseName");
if (url.charAt(0) == '/') {
url = url.substring(1);
}
insertRoute(routes, url.split("/"), 0, handler);
}
objs.put("routes", routes);
return objs;
}
private void insertRoute(List<Map<String, Object>> routes, String[] urlParts, int currentUrlPartIndex, String handler) {
if (urlParts.length > currentUrlPartIndex) {
String urlPart = urlParts[currentUrlPartIndex];
//List<Map<String, Object>> subRoutes = null;
Map<String, Object> currentRoute = null;
for (Map<String, Object> route : routes) {
if (urlPart.equals(route.get("name"))) {
currentRoute = route;
break;
}
}
if (currentRoute == null) {
currentRoute = new HashMap<String, Object>();
String routePart = urlPart.replaceAll("^\\{(\\w+)\\}$", ":$1");
boolean isLastUrlPart = currentUrlPartIndex == urlParts.length - 1;
currentRoute.put("name", urlPart);
currentRoute.put("route", "/" + routePart);
currentRoute.put("type", (urlPart == routePart) ? "Literal" : "Segment");
currentRoute.put("handler", isLastUrlPart ? handler : null);
currentRoute.put("hasChildren", false);
currentRoute.put("children", new ArrayList<Map<String, Object>>());
currentRoute.put("padding", StringUtils.repeat(' ', 4 * currentUrlPartIndex));
routes.add(currentRoute);
}
List<Map<String, Object>> subRoutes = (List<Map<String, Object>>) currentRoute.get("children");
insertRoute(subRoutes, urlParts, currentUrlPartIndex + 1, handler);
currentRoute.put("hasChildren", !subRoutes.isEmpty());
}
}
}

View File

@@ -15,10 +15,18 @@ public interface CXFServerFeatures
public static final String ADD_CONSUMES_PRODUCES_JSON = "addConsumesProducesJson";
public static final String USE_ANNOTATED_BASE_PATH = "useAnnotatedBasePath";
public static final String GENERATE_NON_SPRING_APPLICATION = "generateNonSpringApplication";
public void setUseWadlFeature(boolean useWadlFeature);
public void setUseMultipartFeature(boolean useMultipartFeature);
public void setAddConsumesProducesJson(boolean addConsumesProducesJson);
public void setUseAnnotatedBasePath(boolean useAnnotatedBasePath);
public void setGenerateNonSpringApplication(boolean generateNonSpringApplication);
}

View File

@@ -1,9 +1,10 @@
package io.swagger.codegen.utils;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import joptsimple.internal.Strings;
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
@@ -22,10 +23,10 @@ public class OptionUtils {
results.add(pair);
}
}
//Strings.isNullOrEmpty(input)
return results;
}
public static List<String> splitCommaSeparatedList(String input) {
List<String> results = new ArrayList<String>();
@@ -39,5 +40,4 @@ public class OptionUtils {
return results;
}
}