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) {