From 18b06fd8c3c99c6feff9c6d3ea3462d2d04de5b9 Mon Sep 17 00:00:00 2001 From: Deepak Michael Date: Mon, 25 Jul 2011 12:03:18 +0530 Subject: [PATCH] Swagr code-gen: Refactoring tasks, imports configurable, enum classes generation, sets handled and allowMultiple handling for params --- code-gen/build.xml | 3 + code-gen/conf/templates/java/EnumObject.st | 30 ++++++ code-gen/conf/templates/java/ModelObject.st | 6 +- .../conf/templates/java/ResourceObject.st | 51 +++++++--- .../conf/templates/java/VersionChecker.st | 2 +- .../wordnik/codegen/DriverCodeGenerator.java | 96 ++++++++++++++++--- .../wordnik/codegen/config/CodeGenConfig.java | 40 ++++++++ .../codegen/config/DataTypeMapper.java | 41 +++++++- .../config/GenerationEnvironmentConfig.java | 6 +- .../config/ServiceAndMethodNameGenerator.java | 10 ++ .../codegen/java/JavaCodeGenConfig.java | 6 ++ .../codegen/java/JavaDataTypeMapper.java | 27 +++++- .../JavaServiceAndMethodNameGenerator.java | 16 ++++ .../codegen/resource/EndpointOperation.java | 5 + .../wordnik/codegen/resource/ModelField.java | 28 +++++- java/conf/templates/ResourceObject.st | 8 +- .../java/com/wordnik/common/WordnikAPI.java | 2 +- 17 files changed, 332 insertions(+), 45 deletions(-) create mode 100644 code-gen/conf/templates/java/EnumObject.st diff --git a/code-gen/build.xml b/code-gen/build.xml index d973319047e..57dfc57115b 100644 --- a/code-gen/build.xml +++ b/code-gen/build.xml @@ -24,6 +24,9 @@ + + + diff --git a/code-gen/conf/templates/java/EnumObject.st b/code-gen/conf/templates/java/EnumObject.st new file mode 100644 index 00000000000..94811ac04d0 --- /dev/null +++ b/code-gen/conf/templates/java/EnumObject.st @@ -0,0 +1,30 @@ +package $packageName$; + +$imports:{ import | +import $import$; +}$ + +/** + * $enum.description$ + * NOTE: This class is auto generated by the drive code generator program so please do not edit the program manually. + * @author deepak + * + */ +public enum $className$ { + + $values: { value | $value.name$($value.value$)};separator=", "$; + + final $enumValueType$ value; + + $className$($enumValueType$ value) { + this.value = value; + } + + public $enumValueType$ getValue() { + return value; + } + + @Override public String toString() { + return String.valueOf(this.getValue()); + } +}; \ No newline at end of file diff --git a/code-gen/conf/templates/java/ModelObject.st b/code-gen/conf/templates/java/ModelObject.st index fb4d86e869c..afbba6d4ec6 100644 --- a/code-gen/conf/templates/java/ModelObject.st +++ b/code-gen/conf/templates/java/ModelObject.st @@ -1,7 +1,7 @@ -package com.wordnik.model; +package $packageName$; -import com.wordnik.annotations.AllowableValues; -import com.wordnik.annotations.Required; +import $annotationPackageName$.AllowableValues; +import $annotationPackageName$.Required; $imports:{ import | import $import$; diff --git a/code-gen/conf/templates/java/ResourceObject.st b/code-gen/conf/templates/java/ResourceObject.st index 6e5bedc0bb0..685362b16bf 100644 --- a/code-gen/conf/templates/java/ResourceObject.st +++ b/code-gen/conf/templates/java/ResourceObject.st @@ -1,16 +1,16 @@ -package com.wordnik.api; +package $packageName$; -import com.wordnik.common.*; -import com.wordnik.common.ext.*; -import com.wordnik.exception.APIExceptionCodes; -import com.wordnik.exception.APIException; -import com.wordnik.model.*; -import java.util.*; -import com.wordnik.annotations.MethodArgumentNames; +import $annotationPackageName$.MethodArgumentNames; +import $exceptionPackageName$.APIExceptionCodes; +import $exceptionPackageName$.APIException; +import $modelPackageName$.*; + import org.codehaus.jackson.map.DeserializationConfig.Feature; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; + +import java.util.*; import java.io.IOException; $imports:{ import | @@ -57,7 +57,7 @@ $endif$ $if(!method.inputModel)$ $method.queryParameters:{ argument | if( $argument.name$ != null) { - queryParams.put("$argument.name$", $argument.name$); + queryParams.put("$argument.name$", toPathValue($argument.name$)); } }$ $method.pathParameters:{ argument | @@ -119,7 +119,34 @@ $if(method.returnValueList)$ $endif$ $endif$ } - - -}$ + +}$ + + /** + * Overloaded method for returning the path value + * For a string value an empty value is returned if the value is null + * @param value + * @return + */ + private static String toPathValue(String value) { + return value == null ? "" : value; + } + + /** + * Overloaded method for returning a path value + * For a list of objects a comma separated string is returned + * @param objects + * @return + */ + private static String toPathValue(List objects) { + StringBuilder out = new StringBuilder(); + for(Object o: objects){ + out.append(o.toString()); + out.append(","); + } + if(out.indexOf(",") != -1) { + return out.substring(0, out.lastIndexOf(",") ); + } + return out.toString(); + } } diff --git a/code-gen/conf/templates/java/VersionChecker.st b/code-gen/conf/templates/java/VersionChecker.st index 69365de2aca..1044bd190cb 100644 --- a/code-gen/conf/templates/java/VersionChecker.st +++ b/code-gen/conf/templates/java/VersionChecker.st @@ -1,4 +1,4 @@ -package com.wordnik.api; +package $packageName$; /** * Maintains the compatible server version against which the drive is written diff --git a/code-gen/src/main/java/com/wordnik/codegen/DriverCodeGenerator.java b/code-gen/src/main/java/com/wordnik/codegen/DriverCodeGenerator.java index a4f1df3cda8..06d4f614d4f 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/DriverCodeGenerator.java +++ b/code-gen/src/main/java/com/wordnik/codegen/DriverCodeGenerator.java @@ -32,11 +32,13 @@ public class DriverCodeGenerator { private static String VERSION_OBJECT_TEMPLATE = "VersionChecker"; private static String MODEL_OBJECT_TEMPLATE = "ModelObject"; private static String API_OBJECT_TEMPLATE = "ResourceObject"; - public static final String API_CONFIG_LOCATION = "conf/apiConfig.xml"; + private static final String ENUM_OBJECT_TEMPLATE = "EnumObject"; + private static final String API_CONFIG_LOCATION = "conf/apiConfig.xml"; private static final String API_URL_CONFIG = "apiUrl"; private static final String API_KEY = "apiKey"; private static final String API_LISTING_URL = "apiListResource"; + private static final String PACKAGE_NAME = "packageName"; private CodeGenConfig config = null; private GenerationEnvironmentConfig envConfig = null; private String baseUrl; @@ -72,6 +74,7 @@ public class DriverCodeGenerator { } generateModelClasses(resources, aTemplateGroup); generateModelClassesForInput(resources, aTemplateGroup); + generateEnumForAllowedValues(resources, aTemplateGroup); generateAPIClasses(resources, aTemplateGroup); } @@ -212,23 +215,24 @@ public class DriverCodeGenerator { /** * Generates version file based on the version number received from the doc calls. This version file is used - * while making the API calls to make sure Client and back end are compatible. + * while making the API calls to make sure Client and back end are compatible. * @param version */ private void generateVersionHelper(String version, StringTemplateGroup templateGroup) { StringTemplate template = templateGroup.getInstanceOf(VERSION_OBJECT_TEMPLATE); template.setAttribute("apiVersion", version); + template.setAttribute(PACKAGE_NAME, config.getApiPackageName()); File aFile = new File(envConfig.getResourceClassLocation() + config.getNameGenerator().getVersionCheckerClassName() + config.getClassFileExtension()); writeFile(aFile, template.toString(), "Version checker class"); } - + /** * Generates model classes. If the class is already generated then ignores the same. */ private void generateModelClasses(List resources, StringTemplateGroup templateGroup) { List generatedClassNames = new ArrayList(); - + for(Resource resource: resources) { for(Model model : resource.getModels()){ if(!generatedClassNames.contains(model.getName()) && !config.getCodeGenOverridingRules().isModelIgnored(model.getName())){ @@ -244,20 +248,22 @@ public class DriverCodeGenerator { StringTemplate template = templateGroup.getInstanceOf(MODEL_OBJECT_TEMPLATE); template.setAttribute("fields", model.getFields()); template.setAttribute("imports", imports); + template.setAttribute("annotationPackageName", config.getAnnotationPackageName()); template.setAttribute("extends", config.getCodeGenOverridingRules().getModelExtendingClass()); template.setAttribute("className", model.getGenratedClassName()); + template.setAttribute(PACKAGE_NAME, config.getModelPackageName()); File aFile = new File(envConfig.getModelClassLocation()+model.getGenratedClassName()+config.getClassFileExtension()); writeFile(aFile, template.toString(), "Model class"); generatedClassNames.add(model.getName()); } } } - + generateWrapperClassForTestData(generatedClassNames, templateGroup); - } + } /** - * Generates assembler classes if the API returns more than one objects. + * Generates assembler classes if the API returns more than one objects. * @param resources * @param templateGroup */ @@ -287,11 +293,13 @@ public class DriverCodeGenerator { template.setAttribute("fields", model.getFields()); template.setAttribute("imports", imports); template.setAttribute("extends", config.getCodeGenOverridingRules().getModelExtendingClass()); + template.setAttribute("annotationPackageName", config.getAnnotationPackageName()); template.setAttribute("className", model.getGenratedClassName()); + template.setAttribute(PACKAGE_NAME, config.getModelPackageName()); File aFile = new File(envConfig.getModelClassLocation()+model.getGenratedClassName()+config.getClassFileExtension()); writeFile(aFile, template.toString(), "Input model class"); generatedClasses.add(model.getName()); - } + } } } } @@ -299,15 +307,71 @@ public class DriverCodeGenerator { } } } - } - + } + /** - * Generates one API class for each resource and each end point in the resource is translated as method. + * Generates an Enum class for method params that have an allowed values list. + * @param resources + * @param templateGroup + */ + private void generateEnumForAllowedValues(List resources, StringTemplateGroup templateGroup) { + List generatedEnums = new ArrayList(); + StringTemplate template; + String valuePrefix, valueSuffix = ""; + String enumName; + for(Resource resource: resources) { + if(resource.getEndPoints() != null) { + for(Endpoint endpoint : resource.getEndPoints()){ + if(endpoint.getOperations() != null) { + for(EndpointOperation operation : endpoint.getOperations()){ + //ResourceMethod method = operation.generateMethod(endpoint, resource, config); + if(operation.getParameters() != null){ + for(ModelField operationParam : operation.getParameters()){ + //skipping the case where there is just one item - TODO process case of allowableValue like '0 to 1000' + if(operationParam.getAllowableValues() != null && operationParam.getAllowableValues().size() > 1) { + if(!generatedEnums.contains(operationParam.getName())){ + //generate enum + template = templateGroup.getInstanceOf(ENUM_OBJECT_TEMPLATE); + List imports = new ArrayList(); + imports.addAll(this.config.getDefaultModelImports()); + enumName = config.getNameGenerator().getEnumName(operationParam.getName()); + template.setAttribute("className", enumName); + template.setAttribute("description", operationParam.getDescription()); + template.setAttribute("enumValueType", config.getDataTypeMapper().getObjectType(operationParam.getDataType(), true)); + for (String allowableValue : operationParam.getAllowableValues()) { + if(operationParam.getDataType().equalsIgnoreCase("string")){ + valuePrefix = valueSuffix = "\""; + } + else{ + valuePrefix = valueSuffix = ""; + }; + template.setAttribute("values.{name,value}", + config.getNameGenerator().applyClassNamingPolicy(allowableValue.replaceAll("-","_")), + config.getNameGenerator().applyMethodNamingPolicy(valuePrefix.concat(allowableValue).concat(valueSuffix))); + } + template.setAttribute(PACKAGE_NAME, config.getModelPackageName()); + File aFile = new File(envConfig.getModelClassLocation()+enumName+config.getClassFileExtension()); + writeFile(aFile, template.toString(), "Enum class"); + generatedEnums.add(operationParam.getName()); + } + } + } + } + } + } + } + } + + } + } + + /** + * Generates one API class for each resource and each end point in the resource is translated as method. * @param resources * @param templateGroup */ private void generateAPIClasses(List resources, StringTemplateGroup templateGroup) { - + for(Resource resource : resources) { List methods = new ArrayList(); List imports = new ArrayList(); @@ -322,6 +386,10 @@ public class DriverCodeGenerator { } } template.setAttribute("imports", imports); + template.setAttribute(PACKAGE_NAME, config.getApiPackageName()); + template.setAttribute("annotationPackageName", config.getAnnotationPackageName()); + template.setAttribute("modelPackageName", config.getModelPackageName()); + template.setAttribute("exceptionPackageName", config.getExceptionPackageName()); template.setAttribute("resource", className); template.setAttribute("methods", filteredMethods); template.setAttribute("extends", config.getCodeGenOverridingRules().getServiceExtendingClass(className)); @@ -330,7 +398,7 @@ public class DriverCodeGenerator { writeFile(aFile, template.toString(), "API CLasses"); } } - + /** * Creates a wrapper model class that contains all model classes as list of objects. * This class is used for storing test data @@ -367,7 +435,9 @@ public class DriverCodeGenerator { StringTemplate template = templateGroup.getInstanceOf(MODEL_OBJECT_TEMPLATE); template.setAttribute("fields", model.getFields()); template.setAttribute("imports", imports); + template.setAttribute("annotationPackageName", config.getAnnotationPackageName()); template.setAttribute("extends", config.getCodeGenOverridingRules().getModelExtendingClass()); + template.setAttribute(PACKAGE_NAME, config.getModelPackageName()); template.setAttribute("className", model.getGenratedClassName()); File aFile = new File(envConfig.getModelClassLocation()+model.getGenratedClassName()+config.getClassFileExtension()); writeFile(aFile, template.toString(), "Wrapper class for test data file"); diff --git a/code-gen/src/main/java/com/wordnik/codegen/config/CodeGenConfig.java b/code-gen/src/main/java/com/wordnik/codegen/config/CodeGenConfig.java index a46a395193c..a893762cb6b 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/config/CodeGenConfig.java +++ b/code-gen/src/main/java/com/wordnik/codegen/config/CodeGenConfig.java @@ -28,6 +28,14 @@ public class CodeGenConfig { */ private List defaultServiceImports; + private String modelPackageName; + + private String apiPackageName; + + private String exceptionPackageName; + + private String annotationPackageName; + private CodeGenOverridingRules codeGenOverridingRules; private DataTypeMapper dataTypeMapper; @@ -81,4 +89,36 @@ public class CodeGenConfig { public void setNameGenerator(ServiceAndMethodNameGenerator nameGenerator) { this.nameGenerator = nameGenerator; } + + public String getExceptionPackageName() { + return exceptionPackageName; + } + + public void setExceptionPackageName(String exceptionPackageName) { + this.exceptionPackageName = exceptionPackageName; + } + + public String getAnnotationPackageName() { + return annotationPackageName; + } + + public void setAnnotationPackageName(String annotationPackageName) { + this.annotationPackageName = annotationPackageName; + } + + public String getModelPackageName() { + return modelPackageName; + } + + public void setModelPackageName(String modelPackageName) { + this.modelPackageName = modelPackageName; + } + + public String getApiPackageName() { + return apiPackageName; + } + + public void setApiPackageName(String apiPackageName) { + this.apiPackageName = apiPackageName; + } } diff --git a/code-gen/src/main/java/com/wordnik/codegen/config/DataTypeMapper.java b/code-gen/src/main/java/com/wordnik/codegen/config/DataTypeMapper.java index 7f23fe6918d..322791025e6 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/config/DataTypeMapper.java +++ b/code-gen/src/main/java/com/wordnik/codegen/config/DataTypeMapper.java @@ -35,7 +35,7 @@ public interface DataTypeMapper { /** * Signature that should be used when returning list of given object type. * - * Example: in java this output will look as List for methods that returns list of user objects + * Example: in java this output will look as List for methods that returns a list of user objects * @param typeClass of class that list object contains. * @return */ @@ -44,12 +44,21 @@ public interface DataTypeMapper { /** * Signature that should be used when returning map of given object type. * - * Example: in java this output will look as Map for methods that returns list of user objects + * Example: in java this output will look as Map for methods that returns maps * @param typeClass of class that list object contains. * @return */ public String getMapReturnTypeSignature(String typeClass); + /** + * Signature that should be used when returning set of given object type. + * + * Example: in java this output will look as Set for methods that returns a set of user objects + * @param typeClass of class that the set object contains. + * @return + */ + public String getSetReturnTypeSignature(String typeClass); + /** * Initialization need for list objects. Example. If it is java list the initialization will look as * @@ -63,7 +72,7 @@ public interface DataTypeMapper { public String generateListInitialization(String typeClass); /** - * Initialization need for map objects. Example. If it is java list the initialization will look as + * Initialization need for map objects. Example. If it is java map the initialization will look as * * * new HashMap() @@ -74,6 +83,18 @@ public interface DataTypeMapper { */ public String generateMapInitialization(String typeClass); + /** + * Initialization need for set objects. Example. If it is java set the initialization will look as + * + * + * new HashSet() + * + * + * @param typeClass + * @return + */ + public String generateSetInitialization(String typeClass); + /** * Gets list of imports that needs to be included when used objects of type List. * @@ -102,6 +123,20 @@ public interface DataTypeMapper { */ public List getMapImportPackages(); + /** + * Gets list of imports that needs to be included when used objects of type Set. + * + * Example: in java while using sets we use an interface of Set and implementation of + * HashSet. SO the output will as follows: + * + * List imports = new ArrayList(); + imports.add("java.util.Set"); + imports.add("java.util.HashSet"); + * + * @return + */ + public List getSetImportPackages(); + /** * Gets list of imports that needs to be included when used objects of type Date. * diff --git a/code-gen/src/main/java/com/wordnik/codegen/config/GenerationEnvironmentConfig.java b/code-gen/src/main/java/com/wordnik/codegen/config/GenerationEnvironmentConfig.java index e7e32febca5..1185160c4ca 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/config/GenerationEnvironmentConfig.java +++ b/code-gen/src/main/java/com/wordnik/codegen/config/GenerationEnvironmentConfig.java @@ -7,11 +7,11 @@ package com.wordnik.codegen.config; */ public class GenerationEnvironmentConfig { - private String templateLocation; //lang config + private String templateLocation; - private String modelClassLocation; //output config + private String modelClassLocation; - private String resourceClassLocation; //output config + private String resourceClassLocation; public String getTemplateLocation() { return templateLocation; diff --git a/code-gen/src/main/java/com/wordnik/codegen/config/ServiceAndMethodNameGenerator.java b/code-gen/src/main/java/com/wordnik/codegen/config/ServiceAndMethodNameGenerator.java index f8c9e3c2062..38274c214d9 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/config/ServiceAndMethodNameGenerator.java +++ b/code-gen/src/main/java/com/wordnik/codegen/config/ServiceAndMethodNameGenerator.java @@ -81,6 +81,16 @@ public interface ServiceAndMethodNameGenerator { */ public String getInputObjectName(String serviceName, String resourcePath); + /** + * Generates a name for an enum for the param or field name. + * + * Example: for a param source the return could be SourceEnum + * + * @param input + * @return + */ + public String getEnumName(String input); + /** * Gets the signature of the method that gets value for give attribute name. * diff --git a/code-gen/src/main/java/com/wordnik/codegen/java/JavaCodeGenConfig.java b/code-gen/src/main/java/com/wordnik/codegen/java/JavaCodeGenConfig.java index 85dfa0676d5..c07d2eca78f 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/java/JavaCodeGenConfig.java +++ b/code-gen/src/main/java/com/wordnik/codegen/java/JavaCodeGenConfig.java @@ -21,8 +21,14 @@ public class JavaCodeGenConfig extends CodeGenConfig { defaultModelImports.add("com.wordnik.common.WordnikObject"); List defaultServiceImports = new ArrayList(); defaultServiceImports.add("com.wordnik.model.Long"); + defaultServiceImports.add("com.wordnik.common.*"); + defaultServiceImports.add("com.wordnik.common.ext.*"); this.setDefaultModelImports(defaultModelImports); this.setDefaultServiceImports(defaultServiceImports); + this.setModelPackageName("com.wordnik.model"); + this.setApiPackageName("com.wordnik.api"); + this.setExceptionPackageName("com.wordnik.exception"); + this.setAnnotationPackageName("com.wordnik.annotations"); this.setCodeGenOverridingRules(new JavaCodeGenPverridingRules()); this.setDataTypeMapper(new JavaDataTypeMapper()); this.setNameGenerator(new JavaServiceAndMethodNameGenerator()); diff --git a/code-gen/src/main/java/com/wordnik/codegen/java/JavaDataTypeMapper.java b/code-gen/src/main/java/com/wordnik/codegen/java/JavaDataTypeMapper.java index 3b275ced6e9..8cfaa4c1547 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/java/JavaDataTypeMapper.java +++ b/code-gen/src/main/java/com/wordnik/codegen/java/JavaDataTypeMapper.java @@ -90,6 +90,10 @@ public class JavaDataTypeMapper implements DataTypeMapper { return "Map<"+nameGenerator.applyClassNamingPolicy(typeClass)+">"; } + public String getSetReturnTypeSignature(String typeClass) { + return "Set<"+nameGenerator.applyClassNamingPolicy(typeClass)+">"; + } + public String generateListInitialization(String typeClass) { return " new ArrayList<"+nameGenerator.applyClassNamingPolicy(typeClass)+">()"; } @@ -98,6 +102,10 @@ public class JavaDataTypeMapper implements DataTypeMapper { return " new HashMap<"+nameGenerator.applyClassNamingPolicy(typeClass)+">()"; } + public String generateSetInitialization(String typeClass) { + return " new HashSet<"+nameGenerator.applyClassNamingPolicy(typeClass)+">()"; + } + public List getListImportPackages() { List imports = new ArrayList(); imports.add("java.util.List"); @@ -112,6 +120,12 @@ public class JavaDataTypeMapper implements DataTypeMapper { return imports; } + public List getSetImportPackages() { + List imports = new ArrayList(); + imports.add("java.util.Set"); + imports.add("java.util.HashSet"); + return imports; } + public List getDateImports() { List imports = new ArrayList(); @@ -134,6 +148,9 @@ public class JavaDataTypeMapper implements DataTypeMapper { }else if (type.startsWith("Map[")) { classShortName = type.substring(4, type.length()-1); classShortName = getObjectType(classShortName, true); + }else if (type.startsWith("Set[")) { + classShortName = type.substring(4, type.length()-1); + classShortName = getObjectType(classShortName, true); }else if (type.equals("ok")) { classShortName = "void"; }else{ @@ -143,9 +160,10 @@ public class JavaDataTypeMapper implements DataTypeMapper { } /** - * Gets the short name of the class the class. - * Input can be MAP, LIST or regular string. In case of map or list the class name will be class name + * Gets the class of the expected return value for a type string. Examples of type Strings are int, User, List[User] + * If the type string is a collection type like a map or list the string value returned would be the class * that map or list is returning. + * * @param type * @return */ @@ -159,7 +177,10 @@ public class JavaDataTypeMapper implements DataTypeMapper { classShortName = "List<"+getObjectType(classShortName, true)+">"; }else if (type.startsWith("Map[")) { classShortName = type.substring(4, type.length()-1); - classShortName = "List<"+getObjectType(classShortName, true) +">"; + classShortName = "Map<"+getObjectType(classShortName, true) +">"; + }else if (type.startsWith("Set[")) { + classShortName = type.substring(4, type.length()-1); + classShortName = "Set<"+getObjectType(classShortName, true) +">"; }else{ classShortName = getObjectType(type, true); } diff --git a/code-gen/src/main/java/com/wordnik/codegen/java/JavaServiceAndMethodNameGenerator.java b/code-gen/src/main/java/com/wordnik/codegen/java/JavaServiceAndMethodNameGenerator.java index 5e742ab9ae7..26ede1ebba9 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/java/JavaServiceAndMethodNameGenerator.java +++ b/code-gen/src/main/java/com/wordnik/codegen/java/JavaServiceAndMethodNameGenerator.java @@ -100,6 +100,22 @@ public class JavaServiceAndMethodNameGenerator implements ServiceAndMethodNameGe return inputobjectName; } + /** + * Generates a name for an enum for the param or field name. + *

+ * Example: for a param source the return could be SourceEnum + * + * @param input + * @return + */ + public String getEnumName(String input) { + if (input != null && input.length() > 0) { + return this.applyClassNamingPolicy(input).concat("Values"); + } else { + throw new CodeGenerationException("Error getting Enum name becuase of null input"); + } + } + /** * Gets the signature of the method that gets value for give attribute name. * diff --git a/code-gen/src/main/java/com/wordnik/codegen/resource/EndpointOperation.java b/code-gen/src/main/java/com/wordnik/codegen/resource/EndpointOperation.java index bc91f9c85cc..97f98358292 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/resource/EndpointOperation.java +++ b/code-gen/src/main/java/com/wordnik/codegen/resource/EndpointOperation.java @@ -244,6 +244,11 @@ public class EndpointOperation { arguments.add(anArgument); method.setPostObject(true); } + + if(modelField.isAllowMultiple() && config.getDataTypeMapper().isPrimitiveType(modelField.getDataType())){ + anArgument.setDataType(config.getDataTypeMapper().getListReturnTypeSignature( + config.getDataTypeMapper().getReturnValueType(modelField.getDataType()))); + } anArgument.setInputModelClassArgument(inputobjectName, config); } } diff --git a/code-gen/src/main/java/com/wordnik/codegen/resource/ModelField.java b/code-gen/src/main/java/com/wordnik/codegen/resource/ModelField.java index 3f6c91c9116..532f74614e7 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/resource/ModelField.java +++ b/code-gen/src/main/java/com/wordnik/codegen/resource/ModelField.java @@ -24,6 +24,8 @@ public class ModelField { private boolean required = false; + private boolean allowMultiple = false; + private List allowableValues = null; private String paramType; @@ -80,6 +82,14 @@ public class ModelField { return allowableValues; } + public boolean isAllowMultiple() { + return allowMultiple; + } + + public void setAllowMultiple(boolean allowMultiple) { + this.allowMultiple = allowMultiple; + } + public void setAllowableValues(List allowableValues) { this.allowableValues = allowableValues; } @@ -159,7 +169,20 @@ public class ModelField { }else{ fieldDefinition.setName(this.getName()); } - + + }else if(type.startsWith("Set[")){ + fieldDefinition.getImportDefinitions().addAll(dataTypeMapper.getSetImportPackages()); + String entryType = type.substring(4, type.length()-1); + entryType = dataTypeMapper.getObjectType(entryType, true); + String returnType = dataTypeMapper.getSetReturnTypeSignature(entryType); + fieldDefinition.setReturnType(returnType); + fieldDefinition.setInitialization(" = " + dataTypeMapper.generateSetInitialization(entryType)); + if(this.getWrapperName() != null){ + fieldDefinition.setName(this.getWrapperName()); + }else{ + fieldDefinition.setName(this.getName()); + } + }else if (type.startsWith("Map[")) { fieldDefinition.getImportDefinitions().addAll(dataTypeMapper.getMapImportPackages()); String keyClass, entryClass = ""; @@ -180,9 +203,8 @@ public class ModelField { fieldDefinition.setReturnType(dataTypeMapper.getObjectType(type, false)); fieldDefinition.setName(this.getName()); } - + } return fieldDefinition; } - } diff --git a/java/conf/templates/ResourceObject.st b/java/conf/templates/ResourceObject.st index f0cae1db418..65a7570b9e4 100644 --- a/java/conf/templates/ResourceObject.st +++ b/java/conf/templates/ResourceObject.st @@ -3,14 +3,16 @@ package com.wordnik.api; import com.wordnik.common.*; import com.wordnik.common.ext.*; -import com.wordnik.exception.APIExceptionCodes; -import com.wordnik.exception.APIException; import com.wordnik.model.*; -import java.util.*; import com.wordnik.annotations.MethodArgumentNames; +import $exceptionPackageName$.APIExceptionCodes; +import $exceptionPackageName$.APIException; + import org.codehaus.jackson.map.DeserializationConfig.Feature; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; + +import java.util.*; import java.io.IOException; /** diff --git a/java/src/main/java/com/wordnik/common/WordnikAPI.java b/java/src/main/java/com/wordnik/common/WordnikAPI.java index 812c73aad92..0669ce1ab03 100644 --- a/java/src/main/java/com/wordnik/common/WordnikAPI.java +++ b/java/src/main/java/com/wordnik/common/WordnikAPI.java @@ -52,7 +52,7 @@ public class WordnikAPI { * used while building the driver. This value should be provided while testing the APIs against * test servers or if there is any changes in production server URLs. * @param enableLogging This will enable the logging using Jersey logging filter. Refer the following documentation - * for more details. {@link LoggingFilter}. Default output is sent to system.out. + * for more details. {@link LoggingFilter}. Default output is sent to system.out. * Create a logger ({@link Logger} class and set using setLogger method. */ public static void initialize(String apiKey, String apiServer, boolean enableLogging) {