Java support for application/xml (#5962)

* WIP: CodegenProperty with XML

* WIP: CodegenModel XML bits

* WIP: Jackson XML

* WIP: Java templating

* WIP: Java client withXml flag

* WIP: resttemplate work

* WIP: withXml only when Jackson is used

* WIP: Tabs to spaces

* WIP: java-petstore-resttemplate-withxml sample

* WIP: language: spring

* WIP: language "spring" using library "spring-boot" should include apiPackage in @ComponentScan to detect the API

* WIP: javax.xml for non-Jackson Java and enabled payload logging for jersey2

* WIP: updated java petstore samples

* WIP: JavaSpring with non-jackson XML

* WIP: bin/spring-all-pestore.sh
This commit is contained in:
mobreza
2017-07-11 11:01:51 +02:00
committed by wing328
parent f2f303b2e8
commit 5d32edd964
135 changed files with 10625 additions and 44 deletions

View File

@@ -19,7 +19,7 @@ public class CodegenModel {
public List<CodegenModel> interfaceModels;
public List<CodegenModel> children;
public String name, classname, title, description, classVarName, modelJson, dataType;
public String name, classname, title, description, classVarName, modelJson, dataType, xmlPrefix, xmlNamespace, xmlName;
public String classFilename; // store the class file name, mainly used for import
public String unescapedDescription;
public String discriminator;
@@ -92,6 +92,12 @@ public class CodegenModel {
return false;
if (dataType != null ? !dataType.equals(that.dataType) : that.dataType != null)
return false;
if (xmlPrefix != null ? !xmlPrefix.equals(that.xmlPrefix) : that.xmlPrefix != null)
return false;
if (xmlNamespace != null ? !xmlNamespace.equals(that.xmlNamespace) : that.xmlNamespace != null)
return false;
if (xmlName != null ? !xmlName.equals(that.xmlName) : that.xmlName != null)
return false;
if (classFilename != null ? !classFilename.equals(that.classFilename) : that.classFilename != null)
return false;
if (unescapedDescription != null ? !unescapedDescription.equals(that.unescapedDescription) : that.unescapedDescription != null)
@@ -152,6 +158,9 @@ public class CodegenModel {
result = 31 * result + (classVarName != null ? classVarName.hashCode() : 0);
result = 31 * result + (modelJson != null ? modelJson.hashCode() : 0);
result = 31 * result + (dataType != null ? dataType.hashCode() : 0);
result = 31 * result + (xmlPrefix != null ? xmlPrefix.hashCode() : 0);
result = 31 * result + (xmlNamespace != null ? xmlNamespace.hashCode() : 0);
result = 31 * result + (xmlName != null ? xmlName.hashCode() : 0);
result = 31 * result + (classFilename != null ? classFilename.hashCode() : 0);
result = 31 * result + (unescapedDescription != null ? unescapedDescription.hashCode() : 0);
result = 31 * result + (discriminator != null ? discriminator.hashCode() : 0);

View File

@@ -55,6 +55,12 @@ public class CodegenProperty implements Cloneable {
public Integer maxItems;
public Integer minItems;
// XML
public boolean isXmlAttribute = false;
public String xmlPrefix;
public String xmlName;
public String xmlNamespace;
@Override
public String toString() {
@@ -125,6 +131,10 @@ public class CodegenProperty implements Cloneable {
result = prime * result + Objects.hashCode(enumName);
result = prime * result + ((maxItems == null) ? 0 : maxItems.hashCode());
result = prime * result + ((minItems == null) ? 0 : minItems.hashCode());
result = prime * result + ((isXmlAttribute ? 13:31));
result = prime * result + ((xmlPrefix == null) ? 0 : xmlPrefix.hashCode());
result = prime * result + ((xmlName == null) ? 0 : xmlName.hashCode());
result = prime * result + ((xmlNamespace == null) ? 0 : xmlNamespace.hashCode());
return result;
}
@@ -300,6 +310,18 @@ public class CodegenProperty implements Cloneable {
if (this.minItems != other.minItems && (this.minItems == null || !this.minItems.equals(other.minItems))) {
return false;
}
if (!Objects.equals(this.isXmlAttribute, other.isXmlAttribute)) {
return false;
}
if (!Objects.equals(this.xmlPrefix, other.xmlPrefix)) {
return false;
}
if (!Objects.equals(this.xmlName, other.xmlName)) {
return false;
}
if (!Objects.equals(this.xmlNamespace, other.xmlNamespace)) {
return false;
}
return true;
}

View File

@@ -75,7 +75,7 @@ import java.util.regex.Pattern;
public class DefaultCodegen {
protected static final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);
protected String inputSpec;
protected String outputFolder = "";
protected Set<String> defaultIncludes = new HashSet<String>();
@@ -228,7 +228,7 @@ public class DefaultCodegen {
/**
* post process enum defined in model's properties
*
*
* @param objs Map of models
* @return maps of models with better enum support
*/
@@ -275,7 +275,7 @@ public class DefaultCodegen {
/**
* Returns the common prefix of variables for enum naming
*
*
* @param vars List of variable names
* @return the common prefix for naming
*/
@@ -290,10 +290,10 @@ public class DefaultCodegen {
return "";
}
}
/**
* Return the enum default value in the language specified format
*
*
* @param value enum variable name
* @param datatype data type
* @return the default value for the enum
@@ -305,7 +305,7 @@ public class DefaultCodegen {
/**
* Return the enum value in the language specified format
* e.g. status becomes "status"
*
*
* @param value enum variable name
* @param datatype data type
* @return the sanitized value for enum
@@ -317,10 +317,10 @@ public class DefaultCodegen {
return "\"" + escapeText(value) + "\"";
}
}
/**
* Return the sanitized variable name for enum
*
*
* @param value enum variable name
* @param datatype data type
* @return the sanitized variable name for enum
@@ -369,7 +369,7 @@ public class DefaultCodegen {
@SuppressWarnings("unused")
public void processSwagger(Swagger swagger) {
}
// override with any special handling of the JMustache compiler
@SuppressWarnings("unused")
public Compiler processCompiler(Compiler compiler) {
@@ -414,7 +414,7 @@ public class DefaultCodegen {
}
/**
* Escape single and/or double quote to avoid code injection
* Escape single and/or double quote to avoid code injection
* @param input String to be cleaned up
* @return string with quotation mark removed or escaped
*/
@@ -491,7 +491,7 @@ public class DefaultCodegen {
public Map<String, String> modelDocTemplateFiles() {
return modelDocTemplateFiles;
}
public Map<String, String> reservedWordsMappings() {
return reservedWordsMappings;
}
@@ -621,8 +621,8 @@ public class DefaultCodegen {
}
/**
* Return the file name of the Api Documentation
*
* Return the file name of the Api Documentation
*
* @param name the file name of the Api
* @return the file name of the Api
*/
@@ -672,14 +672,14 @@ public class DefaultCodegen {
/**
* Return the capitalized file name of the model documentation
*
*
* @param name the model name
* @return the file name of the model
*/
public String toModelDocFilename(String name) {
return initialCaps(name);
}
/**
* Return the operation ID (method name)
*
@@ -844,9 +844,9 @@ public class DefaultCodegen {
importMapping.put("LocalDate", "org.joda.time.*");
importMapping.put("LocalTime", "org.joda.time.*");
// we've used the .swagger-codegen-ignore approach as
// we've used the .swagger-codegen-ignore approach as
// suppportingFiles can be cleared by code generator that extends
// the default codegen, leaving the commented code below for
// the default codegen, leaving the commented code below for
// future reference
//supportingFiles.add(new GlobalSupportingFile("LICENSE", "LICENSE"));
@@ -1000,7 +1000,7 @@ public class DefaultCodegen {
}
/**
* Return the example value of the parameter.
* Return the example value of the parameter.
*
* @param p Swagger property object
*/
@@ -1292,7 +1292,14 @@ public class DefaultCodegen {
m.vendorExtensions = model.getVendorExtensions();
if (model instanceof ModelImpl) {
m.discriminator = ((ModelImpl) model).getDiscriminator();
ModelImpl modelImpl = (ModelImpl) model;
m.discriminator = modelImpl.getDiscriminator();
if (modelImpl.getXml() != null) {
m.xmlPrefix = modelImpl.getXml().getPrefix();
m.xmlNamespace = modelImpl.getXml().getNamespace();
m.xmlName = modelImpl.getXml().getName();
}
}
if (model instanceof ArrayModel) {
@@ -1316,8 +1323,14 @@ public class DefaultCodegen {
int modelImplCnt = 0; // only one inline object allowed in a ComposedModel
for (Model innerModel: ((ComposedModel)model).getAllOf()) {
if (innerModel instanceof ModelImpl) {
ModelImpl modelImpl = (ModelImpl) innerModel;
if (m.discriminator == null) {
m.discriminator = ((ModelImpl) innerModel).getDiscriminator();
m.discriminator = modelImpl.getDiscriminator();
}
if (modelImpl.getXml() != null) {
m.xmlPrefix = modelImpl.getXml().getPrefix();
m.xmlNamespace = modelImpl.getXml().getNamespace();
m.xmlName = modelImpl.getXml().getName();
}
if (modelImplCnt++ > 1) {
LOGGER.warn("More than one inline schema specified in allOf:. Only the first one is recognized. All others are ignored.");
@@ -1517,6 +1530,14 @@ public class DefaultCodegen {
if (p.getReadOnly() != null) {
property.isReadOnly = p.getReadOnly();
}
if (p.getXml() != null) {
if (p.getXml().getAttribute() != null) {
property.isXmlAttribute = p.getXml().getAttribute();
}
property.xmlPrefix = p.getXml().getPrefix();
property.xmlName = p.getXml().getName();
property.xmlNamespace = p.getXml().getNamespace();
}
property.vendorExtensions = p.getVendorExtensions();
String type = getSwaggerType(p);
@@ -3026,7 +3047,7 @@ public class DefaultCodegen {
final int totalCount = propertyList.size();
for (int i = 0; i < totalCount; i++) {
Map.Entry<String, Property> entry = propertyList.get(i);
final String key = entry.getKey();
final Property prop = entry.getValue();
@@ -3247,7 +3268,7 @@ public class DefaultCodegen {
/**
* Set library template (sub-template).
*
* @param library Library template
* @param library Library template
*/
public void setLibrary(String library) {
if (library != null && !supportedLibraries.containsKey(library))
@@ -3267,7 +3288,7 @@ public class DefaultCodegen {
/**
* Set Git user ID.
*
* @param gitUserId Git user ID
* @param gitUserId Git user ID
*/
public void setGitUserId(String gitUserId) {
this.gitUserId = gitUserId;
@@ -3285,7 +3306,7 @@ public class DefaultCodegen {
/**
* Set Git repo ID.
*
* @param gitRepoId Git repo ID
* @param gitRepoId Git repo ID
*/
public void setGitRepoId(String gitRepoId) {
this.gitRepoId = gitRepoId;
@@ -3328,7 +3349,7 @@ public class DefaultCodegen {
}
/**
* HTTP user agent
* HTTP user agent
*
* @return HTTP user agent
*/
@@ -3509,7 +3530,7 @@ public class DefaultCodegen {
/**
* Update codegen property's enum by adding "enumVars" (with name and value)
*
*
* @param var list of CodegenProperty
*/
public void updateCodegenPropertyEnum(CodegenProperty var) {
@@ -3588,7 +3609,7 @@ public class DefaultCodegen {
* reads propertyKey from additionalProperties, converts it to a boolean and
* writes it back to additionalProperties to be usable as a boolean in
* mustache files.
*
*
* @param propertyKey
* @return property value as boolean
*/
@@ -3631,7 +3652,7 @@ public class DefaultCodegen {
return booleanValue;
}
public void writePropertyBack(String propertyKey, boolean value) {
additionalProperties.put(propertyKey, value);
}

View File

@@ -46,9 +46,11 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
public static final String DEFAULT_LIBRARY = "<default>";
public static final String DATE_LIBRARY = "dateLibrary";
public static final String JAVA8_MODE = "java8";
public static final String WITH_XML = "withXml";
public static final String SUPPORT_JAVA6 = "supportJava6";
protected boolean java8Mode = false;
protected boolean withXml = false;
protected String dateLibrary = "joda";
protected String invokerPackage = "io.swagger";
protected String groupId = "io.swagger";
@@ -147,6 +149,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
.SERIALIZE_BIG_DECIMAL_AS_STRING_DESC));
cliOptions.add(CliOption.newBoolean(FULL_JAVA_UTIL, "whether to use fully qualified name for classes under java.util. This option only works for Java API client"));
cliOptions.add(new CliOption("hideGenerationTimestamp", "hides the timestamp when files were generated"));
cliOptions.add(CliOption.newBoolean(WITH_XML, "whether to include support for application/xml content type. This option only works for Java API client"));
CliOption dateLibrary = new CliOption(DATE_LIBRARY, "Option. Date library to use");
Map<String, String> dateOptions = new HashMap<String, String>();
@@ -315,6 +318,11 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
additionalProperties.put(FULL_JAVA_UTIL, fullJavaUtil);
additionalProperties.put("javaUtilPrefix", javaUtilPrefix);
if (additionalProperties.containsKey(WITH_XML)) {
this.setWithXml(Boolean.valueOf(additionalProperties.get(WITH_XML).toString()));
}
additionalProperties.put(WITH_XML, withXml);
// make api and model doc path available in mustache template
additionalProperties.put("apiDocPath", apiDocPath);
additionalProperties.put("modelDocPath", modelDocPath);
@@ -378,6 +386,13 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
}
}
if(additionalProperties.containsKey(WITH_XML)) {
setWithXml(Boolean.parseBoolean(additionalProperties.get(WITH_XML).toString()));
if ( withXml ) {
additionalProperties.put(WITH_XML, "true");
}
}
if("joda".equals(dateLibrary)) {
additionalProperties.put("joda", "true");
typeMapping.put("date", "LocalDate");
@@ -746,7 +761,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
return super.toExampleValue(p);
}
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
@@ -1137,6 +1152,10 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
this.fullJavaUtil = fullJavaUtil;
}
public void setWithXml(boolean withXml) {
this.withXml = withXml;
}
public void setDateLibrary(String library) {
this.dateLibrary = library;
}