Add alias type definitions for Java

When a spec defines a Model at the top level that is a non-aggretate type (such
as string, number or boolean), it essentially represents an alias for the simple
type. For example, the following spec snippet creates an alias of the boolean
type that for all intents and purposes acts just like a regular boolean.

    definitions:
      JustABoolean:
        type: boolean

This can be modeled in some languages through built-in mechanisms, such as
typedefs in C++. Java, however, just not have a clean way of representing this.

This change introduces an internal mechanism for representing aliases. It
maintains a map in DefaultCodegen that tracks these types of definitions, and
wherever it sees the "JustABoolean" type in the spec, it generates code that
uses the built-in "Boolean" instead.

This functionality currenlty only applies to Java, but could be extended to
other languages later.

The change adds a few examples of this to the fake endpoint spec for testing,
which means all of the samples change as well.
This commit is contained in:
Benjamin Douglas
2017-04-17 12:39:49 -07:00
parent b1a39ac820
commit 9058099e5b
279 changed files with 25635 additions and 1370 deletions

View File

@@ -25,6 +25,7 @@ public class CodegenModel {
public String discriminator;
public String defaultValue;
public String arrayModelType;
public boolean isAlias; // Is this effectively an alias of another simple type
public List<CodegenProperty> vars = new ArrayList<CodegenProperty>();
public List<CodegenProperty> requiredVars = new ArrayList<CodegenProperty>(); // a list of required properties
public List<CodegenProperty> optionalVars = new ArrayList<CodegenProperty>(); // a list of optional properties

View File

@@ -115,6 +115,8 @@ public class DefaultCodegen {
// They are translated to words like "Dollar" and prefixed with '
// Then translated back during JSON encoding and decoding
protected Map<String, String> specialCharReplacements = new HashMap<String, String>();
// When a model is an alias for a simple type
protected Map<String, String> typeAliases = new HashMap<>();
protected String ignoreFilePathOverride;
@@ -1209,6 +1211,18 @@ public class DefaultCodegen {
return swaggerType;
}
/**
* Determine the type alias for the given type if it exists. This feature
* is only used for Java, because the language does not have a aliasing
* mechanism of its own.
* @param name The type name.
* @return The alias of the given type, if it exists. If there is no alias
* for this type, then returns the input type name.
*/
public String getAlias(String name) {
return name;
}
/**
* Output the API (class) name (capitalized) ending with "Api"
* Return DefaultApi if name is empty
@@ -1373,6 +1387,10 @@ public class DefaultCodegen {
ModelImpl impl = (ModelImpl) model;
if (impl.getType() != null) {
Property p = PropertyBuilder.build(impl.getType(), impl.getFormat(), null);
if (!impl.getType().equals("object") && impl.getEnum() == null) {
typeAliases.put(name, impl.getType());
m.isAlias = true;
}
m.dataType = getSwaggerType(p);
}
if(impl.getEnum() != null && impl.getEnum().size() > 0) {
@@ -2517,6 +2535,7 @@ public class DefaultCodegen {
Model sub = bp.getSchema();
if (sub instanceof RefModel) {
String name = ((RefModel) sub).getSimpleRef();
name = getAlias(name);
if (typeMapping.containsKey(name)) {
name = typeMapping.get(name);
} else {

View File

@@ -318,7 +318,19 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
if(config.importMapping().containsKey(modelName)) {
continue;
}
allModels.add(((List<Object>) models.get("models")).get(0));
Map<String, Object> modelTemplate = (Map<String, Object>) ((List<Object>) models.get("models")).get(0);
if (config.getName().contains("java") || config.getName().contains("jaxrs")
|| config.getName().contains("spring") || config.getName().endsWith("4j")
|| config.getName().equals("inflector")) {
// Special handling of aliases only applies to Java
if (modelTemplate != null && modelTemplate.containsKey("model")) {
CodegenModel m = (CodegenModel) modelTemplate.get("model");
if (m.isAlias) {
continue; // Don't create user-defined classes for aliases
}
}
}
allModels.add(modelTemplate);
for (String templateName : config.modelTemplateFiles().keySet()) {
String suffix = config.modelTemplateFiles().get(templateName);
String filename = config.modelFileFolder() + File.separator + config.toModelFilename(modelName) + suffix;

View File

@@ -568,6 +568,14 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
return super.getTypeDeclaration(p);
}
@Override
public String getAlias(String name) {
if (typeAliases.containsKey(name)) {
return typeAliases.get(name);
}
return name;
}
@Override
public String toDefaultValue(Property p) {
if (p instanceof ArrayProperty) {
@@ -708,6 +716,8 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
swaggerType = getAlias(swaggerType);
// don't apply renaming on types from the typeMapping
if (typeMapping.containsKey(swaggerType)) {
return typeMapping.get(swaggerType);