/** * Generates an Enum class for method params that have an allowed values list. * * @param resources * @param templateGroup */ private void generateEnumForAllowedValues( List<Resource> resources, StringTemplateGroup templateGroup) { List<String> generatedEnums = new ArrayList<String>(); 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() .getClass() .isAssignableFrom(AllowableListValues.class)) { if (!generatedEnums.contains(operationParam.getName())) { // generate enum template = templateGroup.getInstanceOf(ENUM_OBJECT_TEMPLATE); List<String> imports = new ArrayList<String>(); imports.addAll(this.config.getDefaultModelImports()); enumName = this.getNameGenerator().getEnumName(operationParam.getName()); template.setAttribute("className", enumName); template.setAttribute("description", operationParam.getDescription()); template.setAttribute( "enumValueType", this.getDataTypeMappingProvider() .getClassType(operationParam.getDataType(), true)); for (String allowableValue : ((AllowableListValues) operationParam.getAllowableValues()).getValues()) { if (operationParam.getDataType().equalsIgnoreCase("string")) { valuePrefix = valueSuffix = "\""; } else { valuePrefix = valueSuffix = ""; } ; String namePrefix = ""; if (isNameStartsWithInteger(allowableValue) && !canEnumNameStartsWithNumber()) { namePrefix = "ENUM_"; } template.setAttribute( "values.{name,value}", namePrefix + this.getNameGenerator() .applyClassNamingPolicy(allowableValue.replaceAll("-", "_")), this.getNameGenerator() .applyMethodNamingPolicy( valuePrefix.concat(allowableValue).concat(valueSuffix))); } template.setAttribute(PACKAGE_NAME, config.getModelPackageName()); File aFile = new File( languageConfig.getModelClassLocation() + enumName + languageConfig.getClassFileExtension()); writeFile(aFile, template.toString(), "Enum class"); generatedEnums.add(operationParam.getName()); } } } } } } } } } }
public ResourceMethod generateMethod( Endpoint endPoint, Resource resource, DataTypeMappingProvider dataTypeMapper, NamingPolicyProvider nameGenerator) { if (method == null) { method = new ResourceMethod(); // add method description method.setTitle(this.getSummary()); method.setDescription(this.getNotes()); // add method name // get resource path for making web service call /** * Logic for method names 1. remove all path parameters 2. Remove format path parameter 3. For * POST add save 4. For PUT add update 5. For DELETE add delete 6. For GET add get 7. * Concatenate rest of the path with init caps 8. */ String inputobjectName = nameGenerator.getInputObjectName( resource.generateClassName(nameGenerator), endPoint.getPath()); String[] pathElements = endPoint.getPath().split("/"); StringBuilder urlPath = new StringBuilder(""); if (pathElements != null) { for (int i = 0; i < pathElements.length; i++) { String pathElement = pathElements[i]; if (pathElement != null && pathElement.length() > 0) { int position = pathElement.indexOf("{"); if (urlPath.length() > 0) { urlPath.append("+"); } if (position < 0) { urlPath.append("\"/" + pathElement + "\""); } else if (position == 0) { urlPath.append("\"/\"+" + pathElement.substring(1, pathElement.length() - 1)); } else { urlPath.append("\"/" + pathElement.replace("{format}", "json") + "\""); } } } } method.setResourcePath(endPoint.getPath()); method.setName(nameGenerator.getMethodName(endPoint.getPath(), this.getNickname())); // create method argument /** * 1. API token need not be included as that is always added to the calls as HTTP headers 2. * We need to handle auth token specially, hence need to differentiate that 3. Query * parameters needs to be added as query string hence need to separate them out 4. Post * parameters are usually WordnikObjects, hence we need to handle them separately */ List<String> argNames = new ArrayList<String>(); if (this.getParameters() != null) { List<MethodArgument> arguments = new ArrayList<MethodArgument>(); List<MethodArgument> queryParams = new ArrayList<MethodArgument>(); List<MethodArgument> pathParams = new ArrayList<MethodArgument>(); List<MethodArgument> headerParams = new ArrayList<MethodArgument>(); method.setArguments(arguments); method.setQueryParameters(queryParams); method.setPathParameters(pathParams); method.setHeaderParameters(headerParams); for (ModelField modelField : this.getParameters()) { if (!argNames.contains(modelField.getName())) { argNames.add(modelField.getName()); MethodArgument anArgument = new MethodArgument(); anArgument.setAllowedValues(modelField.getAllowedValuesString()); // check if arguments has auth token if (modelField.getParamType().equalsIgnoreCase(PARAM_TYPE_HEADER) && modelField.getName().equals(AUTH_TOKEN_PARAM_NAME)) { method.setAuthToken(true); anArgument.setName(AUTH_TOKEN_ARGUMENT_NAME); anArgument.setDataType( dataTypeMapper.getClassType(MethodArgument.ARGUMENT_STRING, true)); anArgument.setDescription(modelField.getDescription()); anArgument.setRequired(modelField.isRequired()); anArgument.setDefaultValue(modelField.getDefaultValue()); arguments.add(anArgument); headerParams.add(anArgument); } else if (modelField.getParamType().equalsIgnoreCase(PARAM_TYPE_HEADER) && modelField.getName().equals(API_KEY_PARAM_NAME)) { anArgument.setName(API_KEY_PARAM_NAME); anArgument.setDataType( dataTypeMapper.getClassType(MethodArgument.ARGUMENT_STRING, true)); anArgument.setRequired(true); arguments.add(anArgument); headerParams.add(anArgument); } else if (modelField.getParamType().equalsIgnoreCase(PARAM_TYPE_PATH) && !modelField.getName().equalsIgnoreCase(FORMAT_PARAM_NAME)) { anArgument.setName(modelField.getName()); anArgument.setDataType( dataTypeMapper.getClassType(MethodArgument.ARGUMENT_STRING, true)); anArgument.setDescription(modelField.getDescription()); anArgument.setRequired(true); // always true anArgument.setDefaultValue(modelField.getDefaultValue()); arguments.add(anArgument); pathParams.add(anArgument); } else if (modelField.getParamType().equalsIgnoreCase(PARAM_TYPE_QUERY)) { anArgument.setName(modelField.getName()); anArgument.setDataType( dataTypeMapper.getClassType(MethodArgument.ARGUMENT_STRING, true)); anArgument.setDescription(modelField.getDescription()); anArgument.setRequired(modelField.isRequired()); anArgument.setDefaultValue(modelField.getDefaultValue()); queryParams.add(anArgument); arguments.add(anArgument); } else if (modelField.getParamType().equalsIgnoreCase(PARAM_TYPE_BODY)) { if (modelField.getName() == null) { modelField.setName(POST_PARAM_NAME); } anArgument.setName(modelField.getName()); anArgument.setDataType(dataTypeMapper.getClassType(modelField.getDataType(), false)); anArgument.setDescription(modelField.getDescription()); anArgument.setRequired(modelField.isRequired()); anArgument.setDefaultValue(modelField.getDefaultValue()); arguments.add(anArgument); method.setPostObject(true); } if (modelField.isAllowMultiple() && dataTypeMapper.isPrimitiveType(modelField.getDataType())) { anArgument.setDataType( dataTypeMapper.getListReturnTypeSignature( dataTypeMapper.getClassType(modelField.getDataType(), false))); } anArgument.setInputModelClassArgument(inputobjectName, nameGenerator); } } } // check if input model with the given name is already generated for some other path boolean inputModelAlreadyGenerated = false; if (alreadyGeneratedModels.containsKey(inputobjectName)) { if (!alreadyGeneratedModels.get(inputobjectName).equals(endPoint.getPath())) { inputModelAlreadyGenerated = true; } } // check for number of arguments, if we have more than 4 then send the arguments as input // object if (method.getArguments() != null && method.getArguments().size() > ARG_COUNT_FOR_INPUT_MODEL && !inputModelAlreadyGenerated) { List<MethodArgument> arguments = new ArrayList<MethodArgument>(); Model modelforMethodInput = new Model(); modelforMethodInput.setName(inputobjectName); List<ModelField> fields = new ArrayList<ModelField>(); for (MethodArgument argument : method.getArguments()) { if (!argument.getName().equals(POST_PARAM_NAME)) { ModelField aModelField = new ModelField(); aModelField.setAllowedValues(argument.getAllowedValues()); aModelField.setDescription(argument.getDescription()); aModelField.setName(argument.getName()); aModelField.setParamType(argument.getDataType()); fields.add(aModelField); } else { arguments.add(argument); } } modelforMethodInput.setFields(fields); MethodArgument anArgument = new MethodArgument(); anArgument.setDataType(inputobjectName); anArgument.setName(nameGenerator.applyMethodNamingPolicy(inputobjectName)); arguments.add(anArgument); method.setArguments(arguments); method.setInputModel(modelforMethodInput); alreadyGeneratedModels.put(inputobjectName, endPoint.getPath()); } List<String> argumentDefinitions = new ArrayList<String>(); List<String> argumentNames = new ArrayList<String>(); if (method.getArguments() != null && method.getArguments().size() > 0) { for (MethodArgument arg : method.getArguments()) { if (!arg.getName().equalsIgnoreCase(FORMAT_PARAM_NAME)) { argumentDefinitions.add( dataTypeMapper.getArgumentDefinition(arg.getDataType(), arg.getName())); argumentNames.add(arg.getName()); } } method.setArgumentDefinitions(argumentDefinitions); method.setArgumentNames(argumentNames); } // get method type method.setMethodType(this.getHttpMethod()); // get return value String returnType = dataTypeMapper.getClassType(responseClass, false); if ("".equals(returnType)) { method.setHasResponseValue(false); } else { method.setHasResponseValue(true); } // set the original response name, this is used in identifying if the respone is single valued // or multi valued method.setReturnValueFromOperationJson(responseClass); method.setReturnValue(dataTypeMapper.getClassType(responseClass, false)); method.setReturnClassName(dataTypeMapper.getGenericType(responseClass)); // if this is a list return type if (method .getReturnClassName() .equals(dataTypeMapper.getListReturnTypeSignature(responseClass))) { String returnValueTypeName = method.getReturnValue(); Model listWrapperModel = new Model(); listWrapperModel.setName(nameGenerator.getListWrapperName(returnValueTypeName)); List<ModelField> fields = new ArrayList<ModelField>(); ModelField aModelField = new ModelField(); aModelField.setName(nameGenerator.applyMethodNamingPolicy(returnValueTypeName)); aModelField.setParamType(responseClass); fields.add(aModelField); listWrapperModel.setFields(fields); method.setListWrapperModel(listWrapperModel); } // get description string for exception method.setExceptionDescription(calculateExceptionMessage()); } return method; }