From ddb8eff5b8474e82f4f8189f811c5371edbbb2b5 Mon Sep 17 00:00:00 2001 From: Deepak Michael Date: Fri, 29 Jul 2011 21:54:47 +0530 Subject: [PATCH] Swagger Codegen: Split configuration classes into types of configurations and providers, with language agnostic under common --- .../wordnik/codegen/DriverCodeGenerator.java | 135 +++++++++++------- .../com/wordnik/codegen/MethodArgument.java | 8 +- .../com/wordnik/codegen/api/SwaggerApi.java | 50 ++----- .../codegen/config/ApiConfiguration.java | 131 +++++++++++++++++ .../wordnik/codegen/config/CodeGenConfig.java | 119 +-------------- ...pper.java => DataTypeMappingProvider.java} | 2 +- .../config/GenerationEnvironmentConfig.java | 40 ------ .../codegen/config/LanguageConfiguration.java | 86 +++++++++++ ...nerator.java => NamingPolicyProvider.java} | 2 +- ...verridingRules.java => RulesProvider.java} | 6 +- .../CamelCaseNamingPolicyProvider.java} | 6 +- .../config/java/JavaCodeGenConfig.java | 36 ----- ...les.java => JavaCodeGenRulesProvider.java} | 21 +-- ....java => JavaDataTypeMappingProvider.java} | 9 +- .../codegen/config/java/JavaGenEnvConfig.java | 24 ---- .../codegen/config/java/JavaLibCodeGen.java | 57 +++++++- .../codegen/resource/ApiModelDefn.java | 6 +- .../resource/ApiPropertyListWrapper.java | 6 +- .../wordnik/codegen/resource/Endpoint.java | 13 +- .../codegen/resource/EndpointOperation.java | 25 ++-- .../wordnik/codegen/resource/ModelField.java | 4 +- .../wordnik/codegen/resource/Resource.java | 15 +- .../java/com/wordnik/test/APITestRunner.java | 15 +- .../com/wordnik/test/TestCaseExecutor.java | 18 ++- 24 files changed, 450 insertions(+), 384 deletions(-) create mode 100644 code-gen/src/main/java/com/wordnik/codegen/config/ApiConfiguration.java rename code-gen/src/main/java/com/wordnik/codegen/config/{DataTypeMapper.java => DataTypeMappingProvider.java} (99%) delete mode 100644 code-gen/src/main/java/com/wordnik/codegen/config/GenerationEnvironmentConfig.java create mode 100644 code-gen/src/main/java/com/wordnik/codegen/config/LanguageConfiguration.java rename code-gen/src/main/java/com/wordnik/codegen/config/{ServiceAndMethodNameGenerator.java => NamingPolicyProvider.java} (98%) rename code-gen/src/main/java/com/wordnik/codegen/config/{CodeGenOverridingRules.java => RulesProvider.java} (78%) rename code-gen/src/main/java/com/wordnik/codegen/config/{java/JavaServiceAndMethodNameGenerator.java => common/CamelCaseNamingPolicyProvider.java} (95%) delete mode 100644 code-gen/src/main/java/com/wordnik/codegen/config/java/JavaCodeGenConfig.java rename code-gen/src/main/java/com/wordnik/codegen/config/java/{JavaCodeGenPverridingRules.java => JavaCodeGenRulesProvider.java} (52%) rename code-gen/src/main/java/com/wordnik/codegen/config/java/{JavaDataTypeMapper.java => JavaDataTypeMappingProvider.java} (94%) delete mode 100644 code-gen/src/main/java/com/wordnik/codegen/config/java/JavaGenEnvConfig.java 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 1aee4933eba..05adbce1713 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/DriverCodeGenerator.java +++ b/code-gen/src/main/java/com/wordnik/codegen/DriverCodeGenerator.java @@ -1,8 +1,8 @@ package com.wordnik.codegen; import com.wordnik.codegen.api.SwaggerApi; -import com.wordnik.codegen.config.CodeGenConfig; -import com.wordnik.codegen.config.GenerationEnvironmentConfig; +import com.wordnik.codegen.config.*; +import com.wordnik.codegen.config.ApiConfiguration; import com.wordnik.codegen.resource.*; import com.wordnik.exception.CodeGenerationException; import org.antlr.stringtemplate.StringTemplate; @@ -28,35 +28,22 @@ public class DriverCodeGenerator { private static final String ENUM_OBJECT_TEMPLATE = "EnumObject"; private static final String PACKAGE_NAME = "packageName"; - private CodeGenConfig config = null; - private GenerationEnvironmentConfig envConfig = null; + private ApiConfiguration config = null; + private LanguageConfiguration languageConfig = null; private SwaggerApi apiMarshaller; - - public CodeGenConfig getConfig() { - return config; - } - - public void setConfig(CodeGenConfig config) { - this.config = config; - } - - public GenerationEnvironmentConfig getEnvConfig() { - return envConfig; - } - - public void setEnvConfig(GenerationEnvironmentConfig config) { - this.envConfig = config; - } + protected DataTypeMappingProvider dataTypeMappingProvider; + protected RulesProvider codeGenRulesProvider; + protected NamingPolicyProvider nameGenerator; /** * Generate classes needed for the model and API invocation */ public void generateCode() { - apiMarshaller = new SwaggerApi(this.config); + apiMarshaller = new SwaggerApi(this.config, this.getDataTypeMappingProvider(), this.getNameGenerator()); //read resources and get their documentation List resources = apiMarshaller.readResourceDocumentation(); - StringTemplateGroup aTemplateGroup = new StringTemplateGroup("templates",envConfig.getTemplateLocation()); + StringTemplateGroup aTemplateGroup = new StringTemplateGroup("templates", languageConfig.getTemplateLocation()); if(resources.size() > 0) { generateVersionHelper(resources.get(0).getApiVersion(), aTemplateGroup); } @@ -75,8 +62,8 @@ public class DriverCodeGenerator { 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()); + File aFile = new File(languageConfig.getResourceClassLocation() + this.getNameGenerator().getVersionCheckerClassName() + + languageConfig.getClassFileExtension()); writeFile(aFile, template.toString(), "Version checker class"); } @@ -88,11 +75,11 @@ public class DriverCodeGenerator { for(Resource resource: resources) { for(Model model : resource.getModels()){ - if(!generatedClassNames.contains(model.getName()) && !config.getCodeGenOverridingRules().isModelIgnored(model.getName())){ + if(!generatedClassNames.contains(model.getName()) && !this.getCodeGenRulesProvider().isModelIgnored(model.getName())){ List imports = new ArrayList(); imports.addAll(this.config.getDefaultModelImports()); for(ModelField param : model.getFields()){ - for(String importDef : param.getFieldDefinition(config.getDataTypeMapper()).getImportDefinitions()){ + for(String importDef : param.getFieldDefinition(this.getDataTypeMappingProvider()).getImportDefinitions()){ if(!imports.contains(importDef)){ imports.add(importDef); } @@ -101,11 +88,11 @@ 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("annotationPackageName", languageConfig.getAnnotationPackageName()); + template.setAttribute("extends", config.getModelBaseClass()); template.setAttribute("className", model.getGenratedClassName()); template.setAttribute(PACKAGE_NAME, config.getModelPackageName()); - File aFile = new File(envConfig.getModelClassLocation()+model.getGenratedClassName()+config.getClassFileExtension()); + File aFile = new File(languageConfig.getModelClassLocation()+model.getGenratedClassName()+languageConfig.getClassFileExtension()); writeFile(aFile, template.toString(), "Model class"); generatedClassNames.add(model.getName()); } @@ -127,7 +114,7 @@ public class DriverCodeGenerator { for(Endpoint endpoint : resource.getEndPoints()){ if(endpoint.getOperations() != null) { for(EndpointOperation operation : endpoint.getOperations()){ - ResourceMethod method = operation.generateMethod(endpoint, resource, config); + ResourceMethod method = operation.generateMethod(endpoint, resource, dataTypeMappingProvider, nameGenerator); if(method.getInputModel() != null) { Model model = method.getInputModel(); if(model != null){ @@ -135,7 +122,7 @@ public class DriverCodeGenerator { List imports = new ArrayList(); imports.addAll(this.config.getDefaultModelImports()); for(ModelField param : model.getFields()){ - for(String importDef : param.getFieldDefinition(config.getDataTypeMapper()).getImportDefinitions()){ + for(String importDef : param.getFieldDefinition(this.getDataTypeMappingProvider()).getImportDefinitions()){ if(!imports.contains(importDef)){ imports.add(importDef); } @@ -145,11 +132,11 @@ 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("extends", config.getModelBaseClass()); + template.setAttribute("annotationPackageName", languageConfig.getAnnotationPackageName()); template.setAttribute("className", model.getGenratedClassName()); template.setAttribute(PACKAGE_NAME, config.getModelPackageName()); - File aFile = new File(envConfig.getModelClassLocation()+model.getGenratedClassName()+config.getClassFileExtension()); + File aFile = new File(languageConfig.getModelClassLocation()+model.getGenratedClassName()+languageConfig.getClassFileExtension()); writeFile(aFile, template.toString(), "Input model class"); generatedClasses.add(model.getName()); } @@ -187,10 +174,10 @@ public class DriverCodeGenerator { template = templateGroup.getInstanceOf(ENUM_OBJECT_TEMPLATE); List imports = new ArrayList(); imports.addAll(this.config.getDefaultModelImports()); - enumName = config.getNameGenerator().getEnumName(operationParam.getName()); + enumName = this.getNameGenerator().getEnumName(operationParam.getName()); template.setAttribute("className", enumName); template.setAttribute("description", operationParam.getDescription()); - template.setAttribute("enumValueType", config.getDataTypeMapper().getObjectType(operationParam.getDataType(), true)); + template.setAttribute("enumValueType", this.getDataTypeMappingProvider().getObjectType(operationParam.getDataType(), true)); for (String allowableValue : operationParam.getAllowableValues()) { if(operationParam.getDataType().equalsIgnoreCase("string")){ valuePrefix = valueSuffix = "\""; @@ -199,11 +186,11 @@ public class DriverCodeGenerator { valuePrefix = valueSuffix = ""; }; template.setAttribute("values.{name,value}", - config.getNameGenerator().applyClassNamingPolicy(allowableValue.replaceAll("-","_")), - config.getNameGenerator().applyMethodNamingPolicy(valuePrefix.concat(allowableValue).concat(valueSuffix))); + this.getNameGenerator().applyClassNamingPolicy(allowableValue.replaceAll("-","_")), + this.getNameGenerator().applyMethodNamingPolicy(valuePrefix.concat(allowableValue).concat(valueSuffix))); } template.setAttribute(PACKAGE_NAME, config.getModelPackageName()); - File aFile = new File(envConfig.getModelClassLocation()+enumName+config.getClassFileExtension()); + File aFile = new File(languageConfig.getModelClassLocation() + enumName + languageConfig.getClassFileExtension()); writeFile(aFile, template.toString(), "Enum class"); generatedEnums.add(operationParam.getName()); } @@ -229,25 +216,25 @@ public class DriverCodeGenerator { List methods = new ArrayList(); List imports = new ArrayList(); imports.addAll(this.config.getDefaultServiceImports()); - methods = resource.generateMethods(resource, config); + methods = resource.generateMethods(resource, dataTypeMappingProvider, nameGenerator); StringTemplate template = templateGroup.getInstanceOf(API_OBJECT_TEMPLATE); - String className = resource.generateClassName(config); + String className = resource.generateClassName(nameGenerator); List filteredMethods = new ArrayList(); for(ResourceMethod method:methods){ - if(!config.getCodeGenOverridingRules().isMethodIgnored(className, method.getName())){ + if(!this.getCodeGenRulesProvider().isMethodIgnored(className, method.getName())){ filteredMethods.add(method); } } template.setAttribute("imports", imports); template.setAttribute(PACKAGE_NAME, config.getApiPackageName()); - template.setAttribute("annotationPackageName", config.getAnnotationPackageName()); + template.setAttribute("annotationPackageName", languageConfig.getAnnotationPackageName()); template.setAttribute("modelPackageName", config.getModelPackageName()); - template.setAttribute("exceptionPackageName", config.getExceptionPackageName()); + template.setAttribute("exceptionPackageName", languageConfig.getExceptionPackageName()); template.setAttribute("resource", className); template.setAttribute("methods", filteredMethods); - template.setAttribute("extends", config.getCodeGenOverridingRules().getServiceExtendingClass(className)); + template.setAttribute("extends", config.getServiceBaseClass(className)); - File aFile = new File(envConfig.getResourceClassLocation()+ resource.generateClassName(config) +config.getClassFileExtension()); + File aFile = new File(languageConfig.getResourceClassLocation()+ resource.generateClassName(nameGenerator) +languageConfig.getClassFileExtension()); writeFile(aFile, template.toString(), "API CLasses"); } } @@ -264,22 +251,22 @@ public class DriverCodeGenerator { model.setFields(modelFields); for(String className : generatedClassNames){ ModelField aParam = new ModelField(); - aParam.setName(config.getNameGenerator().applyMethodNamingPolicy(className)+"List"); - aParam.setParamType(config.getDataTypeMapper().getListReturnTypeSignature(className)); + aParam.setName(this.getNameGenerator().applyMethodNamingPolicy(className)+"List"); + aParam.setParamType(this.getDataTypeMappingProvider().getListReturnTypeSignature(className)); modelFields.add(aParam); } //add missing class from models ModelField aParam = new ModelField(); aParam.setName("StringValueList"); - aParam.setParamType(config.getDataTypeMapper().getListReturnTypeSignature("StringValue")); + aParam.setParamType(this.getDataTypeMappingProvider().getListReturnTypeSignature("StringValue")); modelFields.add(aParam); List imports = new ArrayList(); imports.addAll(this.config.getDefaultModelImports()); - imports.addAll(this.config.getDataTypeMapper().getListImportPackages()); + imports.addAll(this.getDataTypeMappingProvider().getListImportPackages()); for(ModelField param : model.getFields()){ - for(String importDef : param.getFieldDefinition(config.getDataTypeMapper()).getImportDefinitions()){ + for(String importDef : param.getFieldDefinition(this.getDataTypeMappingProvider()).getImportDefinitions()){ if(!imports.contains(importDef)){ imports.add(importDef); } @@ -288,11 +275,11 @@ 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("annotationPackageName", languageConfig.getAnnotationPackageName()); + template.setAttribute("extends", config.getModelBaseClass()); template.setAttribute(PACKAGE_NAME, config.getModelPackageName()); template.setAttribute("className", model.getGenratedClassName()); - File aFile = new File(envConfig.getModelClassLocation()+model.getGenratedClassName()+config.getClassFileExtension()); + File aFile = new File(languageConfig.getModelClassLocation()+model.getGenratedClassName()+languageConfig.getClassFileExtension()); writeFile(aFile, template.toString(), "Wrapper class for test data file"); } @@ -306,4 +293,44 @@ public class DriverCodeGenerator { throw new CodeGenerationException("Error generating " + classType + " : " + ioe.getMessage()); } } + + public ApiConfiguration getConfig() { + return config; + } + + public void setApiConfig(ApiConfiguration config) { + this.config = config; + } + + public LanguageConfiguration getLanguageConfig() { + return languageConfig; + } + + public void setLanguageConfig(LanguageConfiguration config) { + this.languageConfig = config; + } + + public void setDataTypeMappingProvider(DataTypeMappingProvider dataTypeMappingProvider) { + this.dataTypeMappingProvider = dataTypeMappingProvider; + } + + public void setCodeGenRulesProvider(RulesProvider codeGenRulesProvider) { + this.codeGenRulesProvider = codeGenRulesProvider; + } + + public void setNameGenerator(NamingPolicyProvider nameGenerator) { + this.nameGenerator = nameGenerator; + } + + public DataTypeMappingProvider getDataTypeMappingProvider() { + return dataTypeMappingProvider; + } + + public RulesProvider getCodeGenRulesProvider() { + return codeGenRulesProvider; + } + + public NamingPolicyProvider getNameGenerator() { + return nameGenerator; + } } diff --git a/code-gen/src/main/java/com/wordnik/codegen/MethodArgument.java b/code-gen/src/main/java/com/wordnik/codegen/MethodArgument.java index 3a13d57b08b..c6c129286f0 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/MethodArgument.java +++ b/code-gen/src/main/java/com/wordnik/codegen/MethodArgument.java @@ -1,6 +1,6 @@ package com.wordnik.codegen; -import com.wordnik.codegen.config.CodeGenConfig; +import com.wordnik.codegen.config.NamingPolicyProvider; public class MethodArgument { @@ -55,10 +55,10 @@ public class MethodArgument { return inputModelClassArgument; } - public void setInputModelClassArgument(String inputModelClass, CodeGenConfig config) { - this.inputModelClassArgument = config.getNameGenerator().applyMethodNamingPolicy(inputModelClass); + public void setInputModelClassArgument(String inputModelClass, NamingPolicyProvider nameGenerator) { + this.inputModelClassArgument = nameGenerator.applyMethodNamingPolicy(inputModelClass); if(name != null) { - methodNameFromModelClass = config.getNameGenerator().createGetterMethodName(inputModelClassArgument, name); + methodNameFromModelClass = nameGenerator.createGetterMethodName(inputModelClassArgument, name); } } diff --git a/code-gen/src/main/java/com/wordnik/codegen/api/SwaggerApi.java b/code-gen/src/main/java/com/wordnik/codegen/api/SwaggerApi.java index 7c6bffb257b..8590dbbf2cf 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/api/SwaggerApi.java +++ b/code-gen/src/main/java/com/wordnik/codegen/api/SwaggerApi.java @@ -3,19 +3,15 @@ package com.wordnik.codegen.api; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.WebResource; -import com.wordnik.codegen.config.CodeGenConfig; +import com.wordnik.codegen.config.ApiConfiguration; +import com.wordnik.codegen.config.DataTypeMappingProvider; +import com.wordnik.codegen.config.NamingPolicyProvider; import com.wordnik.codegen.resource.Endpoint; import com.wordnik.codegen.resource.Resource; import com.wordnik.exception.CodeGenerationException; import org.codehaus.jackson.map.DeserializationConfig; import org.codehaus.jackson.map.ObjectMapper; -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.XMLStreamConstants; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -37,40 +33,22 @@ public class SwaggerApi { private String baseUrl; private String apiKey; private String apiListResource; - private CodeGenConfig codeGenConfig; + private ApiConfiguration apiConfiguration; + private final DataTypeMappingProvider dataTypeMappingProvider; + private final NamingPolicyProvider nameGenerator; - public SwaggerApi(CodeGenConfig driverCodeGenerator) { - codeGenConfig = driverCodeGenerator; + public SwaggerApi(ApiConfiguration apiConfiguration, DataTypeMappingProvider dataTypeMappingProvider, NamingPolicyProvider nameGenerator) { + this.apiConfiguration = apiConfiguration; + this.dataTypeMappingProvider = dataTypeMappingProvider; + this.nameGenerator = nameGenerator; readApiConfig(); } public void readApiConfig() { - try { - FileInputStream fileInputStream = new FileInputStream(API_CONFIG_LOCATION); - XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(fileInputStream); - int eventType = xmlStreamReader.getEventType(); - while(xmlStreamReader.hasNext()) { - eventType = xmlStreamReader.next(); - if(eventType == XMLStreamConstants.START_ELEMENT && - xmlStreamReader.getLocalName().equals(API_URL_CONFIG)){ - baseUrl = xmlStreamReader.getElementText().trim(); - } - if(eventType == XMLStreamConstants.START_ELEMENT && - xmlStreamReader.getLocalName().equals(API_KEY)){ - apiKey = xmlStreamReader.getElementText().trim(); - } - if(eventType == XMLStreamConstants.START_ELEMENT && - xmlStreamReader.getLocalName().equals(API_LISTING_URL)){ - apiListResource = xmlStreamReader.getElementText().trim(); - } - } - xmlStreamReader.close(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (XMLStreamException e) { - e.printStackTrace(); - } + baseUrl = apiConfiguration.getApiUrl(); + apiKey = apiConfiguration.getApiKey(); + apiListResource = apiConfiguration.getApiListResource(); } /** @@ -176,7 +154,7 @@ public class SwaggerApi { */ private Resource deserializeResource(String response, ObjectMapper mapper) throws IOException { Resource resource = mapper.readValue(response, Resource.class); - resource.generateModelsFromWrapper(codeGenConfig); + resource.generateModelsFromWrapper(nameGenerator); return resource; } diff --git a/code-gen/src/main/java/com/wordnik/codegen/config/ApiConfiguration.java b/code-gen/src/main/java/com/wordnik/codegen/config/ApiConfiguration.java new file mode 100644 index 00000000000..022b009d859 --- /dev/null +++ b/code-gen/src/main/java/com/wordnik/codegen/config/ApiConfiguration.java @@ -0,0 +1,131 @@ +package com.wordnik.codegen.config; + +import com.wordnik.exception.CodeGenerationException; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * User: ramesh + * Date: 5/31/11 + * Time: 7:04 AM + */ +public class ApiConfiguration { + + private Map baseClassNames = new HashMap(); + + private String defaultServiceBaseClass = "Object"; + + private String modelBaseClass = "Object"; + /** + * Default model imports that we need to include in all service classes. This is needed because some times, + * we may need to write custom classes and those classes will not be known to code generation. To import those + * classes in service classes we use this property + */ + private List defaultModelImports; + /** + * Default service imports that we need to include in all service classes. This is needed because some times, + * we may need to write custom classes ans those classes will not be known to code generation. To import those + * classes in service classes we use this property + */ + private List defaultServiceImports; + private String modelPackageName; + private String apiPackageName; + + private String apiUrl; + private String apiKey; + private String apiListResource; + + public ApiConfiguration() { + + } + + public void setServiceBaseClass(String defaultServiceBaseClass) { + this.defaultServiceBaseClass = defaultServiceBaseClass; + } + + public void setServiceBaseClass(String serviceName, String className) { + if(serviceName == null || serviceName.length() == 0){ + throw new CodeGenerationException("Error setting base class for service: service name was not provided"); + } + + if(className == null || className.length() == 0) { + throw new CodeGenerationException("Error settting base class for service: class name was not provided"); + } + + baseClassNames.put(serviceName, className); + } + + public String getServiceBaseClass(String serviceName) { + if(baseClassNames.containsKey(serviceName)){ + return baseClassNames.get(serviceName); + } + return defaultServiceBaseClass; + } + + public String getModelBaseClass() { + return modelBaseClass; + } + + public void setModelBaseClass(String modelBaseClass) { + this.modelBaseClass = modelBaseClass; + } + + + public List getDefaultModelImports() { + return defaultModelImports; + } + + public void setDefaultModelImports(List defaultModelImports) { + this.defaultModelImports = defaultModelImports; + } + + public List getDefaultServiceImports() { + return defaultServiceImports; + } + + public void setDefaultServiceImports(List defaultServiceImports) { + this.defaultServiceImports = defaultServiceImports; + } + + 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; + } + + public String getApiUrl() { + return apiUrl; + } + + public void setApiUrl(String apiUrl) { + this.apiUrl = apiUrl; + } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + public String getApiListResource() { + return apiListResource; + } + + public void setApiListResource(String apiListResource) { + this.apiListResource = apiListResource; + } +} 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 a893762cb6b..7db1cf3557c 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 @@ -1,7 +1,5 @@ package com.wordnik.codegen.config; -import java.util.List; - /** * Sets the configurations required for the code generation * @@ -9,116 +7,13 @@ import java.util.List; * Date: 5/25/11 * Time: 8:39 AM */ -public class CodeGenConfig { +public abstract class CodeGenConfig { + + private RulesProvider codeGenRulesProvider; + + private DataTypeMappingProvider dataTypeMapper; + + private NamingPolicyProvider nameGenerator; - private String classFileExtension; - - /** - * Default model imports that we need to include in all service classes. This is needed because some times, - * we may need to write custom classes and those classes will not be known to code generation. To import those - * classes in service classes we use this property - */ - private List defaultModelImports; - - /** - * Default service imports that we need to include in all service classes. This is needed because some times, - * we may need to write custom classes ans those classes will not be known to code generation. To import those - * classes in service classes we use this property - */ - private List defaultServiceImports; - - private String modelPackageName; - - private String apiPackageName; - - private String exceptionPackageName; - - private String annotationPackageName; - - private CodeGenOverridingRules codeGenOverridingRules; - - private DataTypeMapper dataTypeMapper; - - private ServiceAndMethodNameGenerator nameGenerator; - - public String getClassFileExtension() { - return classFileExtension; - } - - public void setClassFileExtension(String classFileExtension) { - this.classFileExtension = classFileExtension; - } - - public List getDefaultModelImports() { - return defaultModelImports; - } - - public void setDefaultModelImports(List defaultModelImports) { - this.defaultModelImports = defaultModelImports; - } - - public List getDefaultServiceImports() { - return defaultServiceImports; - } - - public void setDefaultServiceImports(List defaultServiceImports) { - this.defaultServiceImports = defaultServiceImports; - } - - public CodeGenOverridingRules getCodeGenOverridingRules() { - return codeGenOverridingRules; - } - - public void setCodeGenOverridingRules(CodeGenOverridingRules codeGenOverridingRules) { - this.codeGenOverridingRules = codeGenOverridingRules; - } - - public DataTypeMapper getDataTypeMapper() { - return dataTypeMapper; - } - - public void setDataTypeMapper(DataTypeMapper dataTypeMapper) { - this.dataTypeMapper = dataTypeMapper; - } - - public ServiceAndMethodNameGenerator getNameGenerator() { - return nameGenerator; - } - - 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/DataTypeMappingProvider.java similarity index 99% rename from code-gen/src/main/java/com/wordnik/codegen/config/DataTypeMapper.java rename to code-gen/src/main/java/com/wordnik/codegen/config/DataTypeMappingProvider.java index 322791025e6..5aef735cf0a 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/config/DataTypeMapper.java +++ b/code-gen/src/main/java/com/wordnik/codegen/config/DataTypeMappingProvider.java @@ -10,7 +10,7 @@ import java.util.List; * Date: 5/27/11 * Time: 7:39 AM */ -public interface DataTypeMapper { +public interface DataTypeMappingProvider { /** * Checks nature of data type. 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 deleted file mode 100644 index 1185160c4ca..00000000000 --- a/code-gen/src/main/java/com/wordnik/codegen/config/GenerationEnvironmentConfig.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.wordnik.codegen.config; - -/** - * User: deepakmichael - * Date: 23/07/11 - * Time: 8:01 AM - */ -public class GenerationEnvironmentConfig { - - private String templateLocation; - - private String modelClassLocation; - - private String resourceClassLocation; - - public String getTemplateLocation() { - return templateLocation; - } - - public void setTemplateLocation(String templateLocation) { - this.templateLocation = templateLocation; - } - - public String getModelClassLocation() { - return modelClassLocation; - } - - public void setModelClassLocation(String modelClassLocation) { - this.modelClassLocation = modelClassLocation; - } - - public String getResourceClassLocation() { - return resourceClassLocation; - } - - public void setResourceClassLocation(String resourceClassLocation) { - this.resourceClassLocation = resourceClassLocation; - } - -} diff --git a/code-gen/src/main/java/com/wordnik/codegen/config/LanguageConfiguration.java b/code-gen/src/main/java/com/wordnik/codegen/config/LanguageConfiguration.java new file mode 100644 index 00000000000..d1b7da75dbb --- /dev/null +++ b/code-gen/src/main/java/com/wordnik/codegen/config/LanguageConfiguration.java @@ -0,0 +1,86 @@ +package com.wordnik.codegen.config; + +import com.wordnik.exception.CodeGenerationException; + +/** + * User: deepakmichael + * Date: 23/07/11 + * Time: 8:01 AM + */ +public class LanguageConfiguration { + + private String classFileExtension; + + private String templateLocation; + + private String modelClassLocation; + + private String resourceClassLocation; + + private String exceptionPackageName; + + private String annotationPackageName; + + public String getClassFileExtension() { + return classFileExtension; + } + + public void setClassFileExtension(String classFileExtension) { + this.classFileExtension = classFileExtension; + } + + public String getTemplateLocation() { + return templateLocation; + } + + public void setTemplateLocation(String templateLocation) { + this.templateLocation = templateLocation; + } + + public void setOutputDirectory(String outputDirectory) { + + if(outputDirectory == null || outputDirectory.length() == 0){ + throw new CodeGenerationException("Error creating output path : Output path was null "); + } + outputDirectory = outputDirectory.endsWith("/") ? outputDirectory.substring(0, outputDirectory.lastIndexOf("/")) : outputDirectory; + + + this.modelClassLocation = outputDirectory + "/model/"; + this.resourceClassLocation = outputDirectory + "/api/"; + } + + public String getModelClassLocation() { + return modelClassLocation; + } + + public void setModelClassLocation(String modelClassLocation) { + this.modelClassLocation = modelClassLocation; + } + + public String getResourceClassLocation() { + return resourceClassLocation; + } + + public void setResourceClassLocation(String resourceClassLocation) { + this.resourceClassLocation = resourceClassLocation; + } + + 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; + } + + + +} diff --git a/code-gen/src/main/java/com/wordnik/codegen/config/ServiceAndMethodNameGenerator.java b/code-gen/src/main/java/com/wordnik/codegen/config/NamingPolicyProvider.java similarity index 98% rename from code-gen/src/main/java/com/wordnik/codegen/config/ServiceAndMethodNameGenerator.java rename to code-gen/src/main/java/com/wordnik/codegen/config/NamingPolicyProvider.java index 38274c214d9..76ff8e86053 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/config/ServiceAndMethodNameGenerator.java +++ b/code-gen/src/main/java/com/wordnik/codegen/config/NamingPolicyProvider.java @@ -8,7 +8,7 @@ package com.wordnik.codegen.config; * Date: 5/27/11 * Time: 7:36 AM */ -public interface ServiceAndMethodNameGenerator { +public interface NamingPolicyProvider { /** * Gets name of the version checker class. We need not provide extension for the class as that will be read diff --git a/code-gen/src/main/java/com/wordnik/codegen/config/CodeGenOverridingRules.java b/code-gen/src/main/java/com/wordnik/codegen/config/RulesProvider.java similarity index 78% rename from code-gen/src/main/java/com/wordnik/codegen/config/CodeGenOverridingRules.java rename to code-gen/src/main/java/com/wordnik/codegen/config/RulesProvider.java index 8329b20fb80..bed611ccc16 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/config/CodeGenOverridingRules.java +++ b/code-gen/src/main/java/com/wordnik/codegen/config/RulesProvider.java @@ -15,11 +15,7 @@ import java.util.Map; * Date: 4/26/11 * Time: 8:01 AM */ -public interface CodeGenOverridingRules { - - public String getServiceExtendingClass(String serviceName); - - public String getModelExtendingClass(); +public interface RulesProvider { public boolean isMethodIgnored(String serviceName, String methodName); diff --git a/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaServiceAndMethodNameGenerator.java b/code-gen/src/main/java/com/wordnik/codegen/config/common/CamelCaseNamingPolicyProvider.java similarity index 95% rename from code-gen/src/main/java/com/wordnik/codegen/config/java/JavaServiceAndMethodNameGenerator.java rename to code-gen/src/main/java/com/wordnik/codegen/config/common/CamelCaseNamingPolicyProvider.java index 1643a9c2d18..82b831138f4 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaServiceAndMethodNameGenerator.java +++ b/code-gen/src/main/java/com/wordnik/codegen/config/common/CamelCaseNamingPolicyProvider.java @@ -1,7 +1,7 @@ -package com.wordnik.codegen.config.java; +package com.wordnik.codegen.config.common; import com.wordnik.codegen.resource.Model; -import com.wordnik.codegen.config.ServiceAndMethodNameGenerator; +import com.wordnik.codegen.config.NamingPolicyProvider; import com.wordnik.exception.CodeGenerationException; /** @@ -9,7 +9,7 @@ import com.wordnik.exception.CodeGenerationException; * Date: 5/31/11 * Time: 7:03 AM */ -public class JavaServiceAndMethodNameGenerator implements ServiceAndMethodNameGenerator { +public class CamelCaseNamingPolicyProvider implements NamingPolicyProvider { /** * gets the name of class that is responsible for tracking current library version diff --git a/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaCodeGenConfig.java b/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaCodeGenConfig.java deleted file mode 100644 index dd9b40db551..00000000000 --- a/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaCodeGenConfig.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.wordnik.codegen.config.java; - -import com.wordnik.codegen.config.CodeGenConfig; - -import java.util.ArrayList; -import java.util.List; - -/** - * User: ramesh - * Date: 5/31/11 - * Time: 7:04 AM - */ -public class JavaCodeGenConfig extends CodeGenConfig { - - public JavaCodeGenConfig() { - this.setClassFileExtension(".java"); - List defaultModelImports = new ArrayList(); - defaultModelImports.add("com.wordnik.common.WordListType"); - defaultModelImports.add("com.wordnik.common.StringValue"); - defaultModelImports.add("com.wordnik.common.Size"); - 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/config/java/JavaCodeGenPverridingRules.java b/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaCodeGenRulesProvider.java similarity index 52% rename from code-gen/src/main/java/com/wordnik/codegen/config/java/JavaCodeGenPverridingRules.java rename to code-gen/src/main/java/com/wordnik/codegen/config/java/JavaCodeGenRulesProvider.java index ced727a7687..b45856e67c5 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaCodeGenPverridingRules.java +++ b/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaCodeGenRulesProvider.java @@ -1,42 +1,27 @@ package com.wordnik.codegen.config.java; -import com.wordnik.codegen.config.CodeGenOverridingRules; +import com.wordnik.codegen.config.RulesProvider; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; /** * User: ramesh * Date: 5/31/11 * Time: 7:04 AM */ -public class JavaCodeGenPverridingRules implements CodeGenOverridingRules { +public class JavaCodeGenRulesProvider implements RulesProvider { - private Map extendedClassNames = new HashMap(); private List ignoreMethods = new ArrayList(); private List ignoreModels = new ArrayList(); - public JavaCodeGenPverridingRules() { - extendedClassNames.put("WordAPI","AbstractWordAPI"); + public JavaCodeGenRulesProvider() { ignoreMethods.add("WordAPI.getWordFrequency"); ignoreMethods.add("WordAPI.getAudio"); ignoreMethods.add("WordAPI.getWordStats"); ignoreModels.add("wordStats"); } - public String getServiceExtendingClass(String serviceName) { - if(extendedClassNames.containsKey(serviceName)){ - return extendedClassNames.get(serviceName); - } - return "WordnikAPI"; - } - - public String getModelExtendingClass() { - return "WordnikObject"; - } - public boolean isMethodIgnored(String serviceName, String methodName){ return (ignoreMethods.contains(serviceName+"."+methodName)); } diff --git a/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaDataTypeMapper.java b/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaDataTypeMappingProvider.java similarity index 94% rename from code-gen/src/main/java/com/wordnik/codegen/config/java/JavaDataTypeMapper.java rename to code-gen/src/main/java/com/wordnik/codegen/config/java/JavaDataTypeMappingProvider.java index 8cd16d75a84..4971f51bc6e 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaDataTypeMapper.java +++ b/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaDataTypeMappingProvider.java @@ -1,7 +1,8 @@ package com.wordnik.codegen.config.java; -import com.wordnik.codegen.config.DataTypeMapper; -import com.wordnik.codegen.config.ServiceAndMethodNameGenerator; +import com.wordnik.codegen.config.DataTypeMappingProvider; +import com.wordnik.codegen.config.NamingPolicyProvider; +import com.wordnik.codegen.config.common.CamelCaseNamingPolicyProvider; import java.util.ArrayList; import java.util.HashMap; @@ -13,7 +14,7 @@ import java.util.Map; * Date: 5/31/11 * Time: 7:03 AM */ -public class JavaDataTypeMapper implements DataTypeMapper { +public class JavaDataTypeMappingProvider implements DataTypeMappingProvider { public static Map primitiveValueMap = new HashMap(); static{ @@ -49,7 +50,7 @@ public class JavaDataTypeMapper implements DataTypeMapper { primitiveObjectMap.put("date", "Date"); } - private ServiceAndMethodNameGenerator nameGenerator = new JavaServiceAndMethodNameGenerator(); + private NamingPolicyProvider nameGenerator = new CamelCaseNamingPolicyProvider(); public boolean isPrimitiveType(String type) { if(type.equalsIgnoreCase("String") || type.equalsIgnoreCase("int") || type.equalsIgnoreCase("integer") || diff --git a/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaGenEnvConfig.java b/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaGenEnvConfig.java deleted file mode 100644 index a39df16a98b..00000000000 --- a/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaGenEnvConfig.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.wordnik.codegen.config.java; - -import com.wordnik.codegen.config.GenerationEnvironmentConfig; -import com.wordnik.exception.CodeGenerationException; - -/** - * User: deepakmichael - * Date: 23/07/11 - * Time: 8:09 AM - */ -public class JavaGenEnvConfig extends GenerationEnvironmentConfig{ - - public JavaGenEnvConfig(String outputPath) { - if(outputPath == null){ - throw new CodeGenerationException("Error creating output path : Output path was null "); - } - - outputPath = outputPath.endsWith("/") ? outputPath.substring(0, outputPath.lastIndexOf("/")) : outputPath; - - this.setModelClassLocation(outputPath + "/model/"); - this.setResourceClassLocation(outputPath + "/api/"); - this.setTemplateLocation("conf/templates/java"); - } -} diff --git a/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaLibCodeGen.java b/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaLibCodeGen.java index afb00cd1cd8..37e2a81c1ce 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaLibCodeGen.java +++ b/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaLibCodeGen.java @@ -1,8 +1,14 @@ package com.wordnik.codegen.config.java; import com.wordnik.codegen.DriverCodeGenerator; +import com.wordnik.codegen.config.ApiConfiguration; +import com.wordnik.codegen.config.LanguageConfiguration; +import com.wordnik.codegen.config.common.CamelCaseNamingPolicyProvider; import com.wordnik.exception.CodeGenerationException; +import java.util.ArrayList; +import java.util.List; + /** * User: ramesh * Date: 6/16/11 @@ -21,7 +27,54 @@ public class JavaLibCodeGen extends DriverCodeGenerator { } public JavaLibCodeGen(String outputPath){ - this.setConfig(new JavaCodeGenConfig()); - this.setEnvConfig(new JavaGenEnvConfig(outputPath)); + + this.setApiConfig(initializeApiConfig()); + this.setLanguageConfig(initializeLangConfig(outputPath)); + + this.setDataTypeMappingProvider(new JavaDataTypeMappingProvider()); + this.setCodeGenRulesProvider(new JavaCodeGenRulesProvider()); + this.setNameGenerator(new CamelCaseNamingPolicyProvider()); } + + private ApiConfiguration initializeApiConfig() { + ApiConfiguration apiConfiguration = new ApiConfiguration(); + apiConfiguration.setServiceBaseClass("WordAPI","AbstractWordAPI"); + //default base class for services if not specified for a service + apiConfiguration.setServiceBaseClass("WordnikAPI"); + apiConfiguration.setModelBaseClass("WordnikObject"); + + List defaultModelImports = new ArrayList(); + defaultModelImports.add("com.wordnik.common.WordListType"); + defaultModelImports.add("com.wordnik.common.StringValue"); + defaultModelImports.add("com.wordnik.common.Size"); + 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.*"); + + apiConfiguration.setDefaultModelImports(defaultModelImports); + apiConfiguration.setDefaultServiceImports(defaultServiceImports); + + apiConfiguration.setModelPackageName("com.wordnik.model"); + apiConfiguration.setApiPackageName("com.wordnik.api"); + + apiConfiguration.setApiKey("myKey"); + apiConfiguration.setApiUrl("http://swagr.api.wordnik.com/v4/"); + apiConfiguration.setApiListResource("/list"); + + return apiConfiguration; + } + + private LanguageConfiguration initializeLangConfig(String outputPath) { + LanguageConfiguration javaConfiguration = new LanguageConfiguration(); + javaConfiguration.setClassFileExtension(".java"); + javaConfiguration.setOutputDirectory(outputPath); + javaConfiguration.setTemplateLocation("conf/templates/java"); + javaConfiguration.setExceptionPackageName("com.wordnik.exception"); + javaConfiguration.setAnnotationPackageName("com.wordnik.annotations"); + return javaConfiguration; + } + } diff --git a/code-gen/src/main/java/com/wordnik/codegen/resource/ApiModelDefn.java b/code-gen/src/main/java/com/wordnik/codegen/resource/ApiModelDefn.java index f2834fb7a0a..062664052ec 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/resource/ApiModelDefn.java +++ b/code-gen/src/main/java/com/wordnik/codegen/resource/ApiModelDefn.java @@ -1,6 +1,6 @@ package com.wordnik.codegen.resource; -import com.wordnik.codegen.config.CodeGenConfig; +import com.wordnik.codegen.config.NamingPolicyProvider; import org.codehaus.jackson.annotate.JsonProperty; /** @@ -43,11 +43,11 @@ public class ApiModelDefn { this.description = description; } - public Model toModel(String modelName, CodeGenConfig config) { + public Model toModel(String modelName, NamingPolicyProvider nameGenerator) { Model model = new Model(); model.setName(modelName); model.setDescription(this.getDescription()); - model.setFields( this.getProperties().toFieldList( config ) ); + model.setFields( this.getProperties().toFieldList( nameGenerator ) ); return model; } } diff --git a/code-gen/src/main/java/com/wordnik/codegen/resource/ApiPropertyListWrapper.java b/code-gen/src/main/java/com/wordnik/codegen/resource/ApiPropertyListWrapper.java index 38ca8c58da7..446330b3fe5 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/resource/ApiPropertyListWrapper.java +++ b/code-gen/src/main/java/com/wordnik/codegen/resource/ApiPropertyListWrapper.java @@ -1,6 +1,6 @@ package com.wordnik.codegen.resource; -import com.wordnik.codegen.config.CodeGenConfig; +import com.wordnik.codegen.config.NamingPolicyProvider; import org.codehaus.jackson.annotate.JsonAnyGetter; import org.codehaus.jackson.annotate.JsonAnySetter; import org.codehaus.jackson.map.annotate.JsonSerialize; @@ -27,7 +27,7 @@ public class ApiPropertyListWrapper implements Serializable this.propertyList.put(name, value); } - public List toFieldList(CodeGenConfig config) { + public List toFieldList(NamingPolicyProvider nameGenerator) { List fields = new ArrayList(); ModelField field; @@ -52,7 +52,7 @@ public class ApiPropertyListWrapper implements Serializable if(propertyDefn.getItems().getAdditionalProperties().get("$ref") != null) { arrayItemType = (String) propertyDefn.getItems().getAdditionalProperties().get("$ref"); } - field.setParamType("List[" + config.getNameGenerator().applyClassNamingPolicy(arrayItemType) + "]"); + field.setParamType("List[" + nameGenerator.applyClassNamingPolicy(arrayItemType) + "]"); } field.setDefaultValue(propertyDefn.getDefaultValue()); field.setInternalDescription(propertyDefn.getNotes()); diff --git a/code-gen/src/main/java/com/wordnik/codegen/resource/Endpoint.java b/code-gen/src/main/java/com/wordnik/codegen/resource/Endpoint.java index 3d5d426bbe4..d1801551201 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/resource/Endpoint.java +++ b/code-gen/src/main/java/com/wordnik/codegen/resource/Endpoint.java @@ -1,7 +1,8 @@ package com.wordnik.codegen.resource; import com.wordnik.codegen.ResourceMethod; -import com.wordnik.codegen.config.CodeGenConfig; +import com.wordnik.codegen.config.DataTypeMappingProvider; +import com.wordnik.codegen.config.NamingPolicyProvider; import java.util.ArrayList; import java.util.List; @@ -81,13 +82,13 @@ public class Endpoint { } } - public List generateMethods(Resource resource, CodeGenConfig config) { + public List generateMethods(Resource resource, DataTypeMappingProvider dataTypeMapper, NamingPolicyProvider nameGenerator) { if(methods == null){ methods = new ArrayList(); if(getOperations() != null) { for(EndpointOperation operation: getOperations()) { - if(!operation.isDeprecated() && areModelsAvailable(operation.getParameters(), resource, config)) { - methods.add(operation.generateMethod(this, resource, config)); + if(!operation.isDeprecated() && areModelsAvailable(operation.getParameters(), resource, dataTypeMapper)) { + methods.add(operation.generateMethod(this, resource, dataTypeMapper, nameGenerator)); } } } @@ -95,14 +96,14 @@ public class Endpoint { return methods; } - private boolean areModelsAvailable(List modelFields, Resource resource, CodeGenConfig config) { + private boolean areModelsAvailable(List modelFields, Resource resource, DataTypeMappingProvider dataTypeMapper) { Boolean isParamSetAvailable = true; if(modelFields == null) return true; for(ModelField modelField : modelFields){ if (modelField.getParamType().equalsIgnoreCase(EndpointOperation.PARAM_TYPE_BODY) ){ isParamSetAvailable = false; for(Model model : resource.getModels()){ - if(config.getDataTypeMapper().isPrimitiveType(modelField.getDataType())){ + if(dataTypeMapper.isPrimitiveType(modelField.getDataType())){ isParamSetAvailable = true; break; } 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 fa361d1e0bd..ddd5de9422f 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 @@ -2,7 +2,8 @@ package com.wordnik.codegen.resource; import com.wordnik.codegen.MethodArgument; import com.wordnik.codegen.ResourceMethod; -import com.wordnik.codegen.config.CodeGenConfig; +import com.wordnik.codegen.config.DataTypeMappingProvider; +import com.wordnik.codegen.config.NamingPolicyProvider; import java.util.ArrayList; import java.util.List; @@ -144,7 +145,7 @@ public class EndpointOperation { } - public ResourceMethod generateMethod(Endpoint endPoint, Resource resource, CodeGenConfig config) { + public ResourceMethod generateMethod(Endpoint endPoint, Resource resource, DataTypeMappingProvider dataTypeMapper, NamingPolicyProvider nameGenerator) { if(method == null){ method = new ResourceMethod(); //add method description @@ -164,7 +165,7 @@ public class EndpointOperation { * 8. */ - String inputobjectName = config.getNameGenerator().getInputObjectName(resource.generateClassName(config), endPoint.getPath()); + String inputobjectName = nameGenerator.getInputObjectName(resource.generateClassName(nameGenerator), endPoint.getPath()); String[] pathElements = endPoint.getPath().split("/"); StringBuilder urlPath = new StringBuilder(""); @@ -187,7 +188,7 @@ public class EndpointOperation { } } method.setResourcePath(endPoint.getPath()); - method.setName(config.getNameGenerator().getMethodName(endPoint.getPath(), this.getSuggestedName())); + method.setName(nameGenerator.getMethodName(endPoint.getPath(), this.getSuggestedName())); //create method argument /** @@ -239,17 +240,17 @@ public class EndpointOperation { modelField.setName("postObject"); } anArgument.setName(modelField.getName()); - anArgument.setDataType(config.getDataTypeMapper().getReturnValueType(modelField.getDataType())); + anArgument.setDataType(dataTypeMapper.getReturnValueType(modelField.getDataType())); anArgument.setDescription(modelField.getDescription()); arguments.add(anArgument); method.setPostObject(true); } - if(modelField.isAllowMultiple() && config.getDataTypeMapper().isPrimitiveType(modelField.getDataType())){ - anArgument.setDataType(config.getDataTypeMapper().getListReturnTypeSignature( - config.getDataTypeMapper().getReturnValueType(modelField.getDataType()))); + if(modelField.isAllowMultiple() && dataTypeMapper.isPrimitiveType(modelField.getDataType())){ + anArgument.setDataType(dataTypeMapper.getListReturnTypeSignature( + dataTypeMapper.getReturnValueType(modelField.getDataType()))); } - anArgument.setInputModelClassArgument(inputobjectName, config); + anArgument.setInputModelClassArgument(inputobjectName, nameGenerator); } } } @@ -276,7 +277,7 @@ public class EndpointOperation { MethodArgument anArgument = new MethodArgument(); anArgument.setDataType(inputobjectName); - anArgument.setName(config.getNameGenerator().applyMethodNamingPolicy(inputobjectName)); + anArgument.setName(nameGenerator.applyMethodNamingPolicy(inputobjectName)); arguments.add(anArgument); method.setArguments(arguments); method.setInputModel(modelforMethodInput); @@ -301,8 +302,8 @@ public class EndpointOperation { //get return value List response = this.getResponse(); - method.setReturnValue(config.getDataTypeMapper().getReturnValueType(response.get(0).getValueType())); - method.setReturnClassName(config.getDataTypeMapper().getReturnClassType(response.get(0).getValueType())); + method.setReturnValue(dataTypeMapper.getReturnValueType(response.get(0).getValueType())); + method.setReturnClassName(dataTypeMapper.getReturnClassType(response.get(0).getValueType())); //get description string for exception 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 3c5e2b09fb1..bd4e999369d 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 @@ -1,7 +1,7 @@ package com.wordnik.codegen.resource; import com.wordnik.codegen.FieldDefinition; -import com.wordnik.codegen.config.DataTypeMapper; +import com.wordnik.codegen.config.DataTypeMappingProvider; import java.util.ArrayList; import java.util.List; @@ -154,7 +154,7 @@ public class ModelField { return fieldDefinition; } - public FieldDefinition getFieldDefinition(DataTypeMapper dataTypeMapper) { + public FieldDefinition getFieldDefinition(DataTypeMappingProvider dataTypeMapper) { if(fieldDefinition == null) { fieldDefinition = new FieldDefinition(); String type = paramType.trim(); diff --git a/code-gen/src/main/java/com/wordnik/codegen/resource/Resource.java b/code-gen/src/main/java/com/wordnik/codegen/resource/Resource.java index 1abc229bee6..25fde6ee06b 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/resource/Resource.java +++ b/code-gen/src/main/java/com/wordnik/codegen/resource/Resource.java @@ -1,7 +1,8 @@ package com.wordnik.codegen.resource; import com.wordnik.codegen.ResourceMethod; -import com.wordnik.codegen.config.CodeGenConfig; +import com.wordnik.codegen.config.DataTypeMappingProvider; +import com.wordnik.codegen.config.NamingPolicyProvider; import org.codehaus.jackson.annotate.JsonCreator; import org.codehaus.jackson.annotate.JsonProperty; @@ -87,34 +88,34 @@ public class Resource { this.models = models; }*/ - public String generateClassName(CodeGenConfig config) { + public String generateClassName(NamingPolicyProvider nameGenerator) { if (generatedClassName == null) { String endPointPath = endPoints.get(0).getPath(); - generatedClassName = config.getNameGenerator().getServiceName(endPointPath); + generatedClassName = nameGenerator.getServiceName(endPointPath); } return generatedClassName; } - public List generateMethods(Resource resource, CodeGenConfig config) { + public List generateMethods(Resource resource, DataTypeMappingProvider dataTypeMapper, NamingPolicyProvider nameGenerator) { if(methods == null){ methods = new ArrayList(); if(getEndPoints() != null) { for(Endpoint endpoint: getEndPoints()){ - methods.addAll(endpoint.generateMethods(resource, config)); + methods.addAll(endpoint.generateMethods(resource, dataTypeMapper, nameGenerator)); } } } return methods; } - public void generateModelsFromWrapper(CodeGenConfig config) { + public void generateModelsFromWrapper(NamingPolicyProvider nameGenerator) { String modelName; ApiModelDefn modelDefn; if (modelListWrapper != null) { for (Map.Entry entry : modelListWrapper.getModelList().entrySet()) { modelName = entry.getKey(); modelDefn = entry.getValue(); - models.add (modelDefn.toModel(modelName, config) ); + models.add (modelDefn.toModel(modelName, nameGenerator) ); } } diff --git a/java/src/test/java/com/wordnik/test/APITestRunner.java b/java/src/test/java/com/wordnik/test/APITestRunner.java index 703f05f0692..5f4991708e8 100644 --- a/java/src/test/java/com/wordnik/test/APITestRunner.java +++ b/java/src/test/java/com/wordnik/test/APITestRunner.java @@ -1,14 +1,19 @@ package com.wordnik.test; -import java.io.*; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import com.wordnik.codegen.config.CodeGenConfig; -import com.wordnik.codegen.config.java.JavaCodeGenConfig; +import java.io.File; +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.InputStreamReader; + +import com.wordnik.codegen.config.ApiConfiguration; +import com.wordnik.codegen.config.NamingPolicyProvider; +import com.wordnik.codegen.config.common.CamelCaseNamingPolicyProvider; import com.wordnik.common.*; import com.wordnik.exception.APIException; import org.apache.commons.beanutils.MethodUtils; @@ -67,7 +72,7 @@ public class APITestRunner { mapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false); } - private CodeGenConfig config = new JavaCodeGenConfig(); + private NamingPolicyProvider namingPolicyProvider = new CamelCaseNamingPolicyProvider(); /** * Follow the following argument pattern @@ -194,7 +199,7 @@ public class APITestRunner { //2 TestResource resource = resourceMap.get(testCase.getResourceId()); String path = resource.getPath(); - String className = config.getNameGenerator().getServiceName(path); + String className = namingPolicyProvider.getServiceName(path); String methodName = resource.getSuggestedMethodName(); //3 diff --git a/java/src/test/java/com/wordnik/test/TestCaseExecutor.java b/java/src/test/java/com/wordnik/test/TestCaseExecutor.java index 74cf0c2890d..8cc69e29d8e 100644 --- a/java/src/test/java/com/wordnik/test/TestCaseExecutor.java +++ b/java/src/test/java/com/wordnik/test/TestCaseExecutor.java @@ -2,8 +2,11 @@ package com.wordnik.test; import com.wordnik.annotations.MethodArgumentNames; import com.wordnik.api.WordAPI; -import com.wordnik.codegen.config.CodeGenConfig; -import com.wordnik.codegen.config.java.JavaCodeGenConfig; +import com.wordnik.codegen.config.ApiConfiguration; +import com.wordnik.codegen.config.RulesProvider; +import com.wordnik.codegen.config.java.JavaCodeGenRulesProvider; +import com.wordnik.codegen.config.NamingPolicyProvider; +import com.wordnik.codegen.config.common.CamelCaseNamingPolicyProvider; import com.wordnik.exception.APIException; import com.wordnik.exception.APIExceptionCodes; import org.apache.commons.beanutils.BeanUtils; @@ -23,7 +26,9 @@ import java.util.Map; */ public class TestCaseExecutor { - private CodeGenConfig config = new JavaCodeGenConfig(); + public ApiConfiguration config = new ApiConfiguration(); + private NamingPolicyProvider namingPolicyProvider = new CamelCaseNamingPolicyProvider(); + private RulesProvider rulesProvider = new JavaCodeGenRulesProvider(); /** * Follow the following argument pattern @@ -41,6 +46,7 @@ public class TestCaseExecutor { public static void main(String[] args) throws Exception { WordAPI.initialize("c23b746d074135dc9500c0a61300a3cb7647e53ec2b9b658e", "http://beta.wordnik.com/v4/", false); TestCaseExecutor runner = new TestCaseExecutor(); + runner.config.setModelBaseClass("WordnikObject"); String apiKey = args[0]; String authToken = args[1]; String resource = args[2]; @@ -67,7 +73,7 @@ public class TestCaseExecutor { private void executeTestCase(String resourceName, String httpMethod, String suggestedName, String apiKey, String authToken, Map queryAndPathParameters, String postData) { - String className = config.getNameGenerator().getServiceName(resourceName); + String className = namingPolicyProvider.getServiceName(resourceName); String methodName = suggestedName; //3 @@ -154,7 +160,7 @@ public class TestCaseExecutor { // post data or input wrapper object created by code generator. If it is wrpper object then use the // individual query and path parameters to create the wrapper object. If it is post data directly // convert input JSON string to post data object - if(superclass != null && superclass.getSimpleName().equalsIgnoreCase(config.getCodeGenOverridingRules().getModelExtendingClass())){ + if(superclass != null && superclass.getSimpleName().equalsIgnoreCase(config.getModelBaseClass())){ if(argNamesArray[i].trim().equals("postObject")){ argument = APITestRunner.convertJSONStringToObject(postData, argTypesArray[i]); }else{ @@ -193,7 +199,7 @@ public class TestCaseExecutor { if(method.getName().startsWith("get")){ String methodName = method.getName(); String fieldName = methodName.substring(3); - fieldName = config.getNameGenerator().applyMethodNamingPolicy(fieldName); + fieldName = namingPolicyProvider.applyMethodNamingPolicy(fieldName); Object value = inputDefinitions.get(fieldName); BeanUtils.setProperty(object, fieldName, value); }