refactored directory structure

This commit is contained in:
rpidikiti 2011-08-01 23:21:53 -07:00
parent 48e54e8baa
commit 53af227680
45 changed files with 3905 additions and 23 deletions

25
.gitignore vendored
View File

@ -1,28 +1,7 @@
java/wordnik*.zip
java/*.ipr
java/*.iml
java/*.iws
java/dist/
java/build/
java/lib/*.jar
java/META-INF/
java/web/
java/index
java/reports/
java/lib/*.zip
java/logs
java/src/main/java/com/wordnik/env/Version.scala
java/lib/*.pom
java/version.properties
java/out
android/codegen/build/
*.iml
out/
*.ipr
*.iws
version.properties
android/codegen/lib/
android/driver/lib/
android/driver/build/
android/driver-test/build/
android/driver-test/lib/*.jar
lib/*
build/*

17
bin/runjava.sh Executable file
View File

@ -0,0 +1,17 @@
#!/bin/bash
echo "" > classpath.txt
for file in `ls lib`;
do echo -n 'lib/' >> classpath.txt;
echo -n $file >> classpath.txt;
echo -n ':' >> classpath.txt;
done
for file in `ls build`;
do echo -n 'build/' >> classpath.txt;
echo -n $file >> classpath.txt;
echo -n ':' >> classpath.txt;
done
export CLASSPATH=$(cat classpath.txt)
export JAVA_OPTS="${JAVA_OPTS} -DrulePath=data -Dproperty=Xmx2g -DloggerPath=$BUILD_COMMON/test-config/log4j.properties"
java $WORDNIK_OPTS $JAVA_CONFIG_OPTIONS $JAVA_OPTS -cp $CLASSPATH "$@"

17
bin/runscala.sh Executable file
View File

@ -0,0 +1,17 @@
#!/bin/bash
echo "" > classpath.txt
for file in `ls lib`;
do echo -n 'lib/' >> classpath.txt;
echo -n $file >> classpath.txt;
echo -n ':' >> classpath.txt;
done
for file in `ls build`;
do echo -n 'build/' >> classpath.txt;
echo -n $file >> classpath.txt;
echo -n ':' >> classpath.txt;
done
export CLASSPATH=$(cat classpath.txt)
export JAVA_OPTS="${JAVA_OPTS} -DrulePath=data -Dproperty=Xmx2g -DloggerPath=$BUILD_COMMON/test-config/log4j.properties"
scala $WORDNIK_OPTS $JAVA_CONFIG_OPTIONS $JAVA_OPTS -cp $CLASSPATH "$@"

58
build.xml Normal file
View File

@ -0,0 +1,58 @@
<project name="wordnik-libs-gen" default="compile" basedir=".">
<property environment="env" />
<property name="version.identifier" value="1.0" />
<condition property="build.common.dir" value="${env.BUILD_COMMON}">
<isset property="env.BUILD_COMMON" />
</condition>
<mkdir dir="lib"/>
<mkdir dir="lib/ext"/>
<mkdir dir="build"/>
<mkdir dir="src/main/scala"/>
<echo message="using build common dir: ${build.common.dir}"/>
<import file="${build.common.dir}/ant/ant-common.xml" />
<import file="${build.common.dir}/ant/ant-server.xml" />
<import file="${build.common.dir}/ant/ant-test.xml" />
<condition property="outputPath.set">
<and>
<isset property="outputPath"/>
<isset property="apiServerRootDir"/>
</and>
</condition>
<!-- generates the classes -->
<target name="generate-java" depends="compile" description="generates APIs and model classes for java language">
<fail unless="outputPath.set">
Must specify the parameters: outputPath and apiServerRootDir eg. -DoutputPath=../../api-server-lib/java/src/main/java/com/wordnik/
-DapiServerRootDir=../../api-server-lib/java/
These are the output path of the Apis and the root directory that will be created for the api server (directory where structure is created)
</fail>
<mkdir dir="${outputPath}/api"/>
<mkdir dir="${outputPath}/model"/>
<echo>
outputPath for Api = ${outputPath}
</echo>
<echo>
apiServerRootDir = ${apiServerRootDir}
</echo>
<delete>
<fileset dir="${outputPath}" includes="*.java"/>
</delete>
<java classname="com.wordnik.swagger.codegen.config.java.JavaLibCodeGen">
<classpath>
<pathelement location="build/main/java" />
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
</classpath>
<arg value="${outputPath}"/>
</java>
<copy todir="${apiServerRootDir}" overwrite="true">
<fileset dir="conf/java/structure"/>
</copy>
</target>
</project>

View File

@ -0,0 +1,45 @@
<?xml version="1.0"?>
<project name="wordnik-java-driver" xmlns:ivy="antlib:org.apache.ivy.ant" default="fastdist" basedir=".">
<property environment="env" />
<property name="version.identifier" value="4.04" />
<!-- property name="application.description" value="Wordnik Java Driver"/>
<property name="application.name" value="java-driver"/ -->
<condition property="build.common.dir" value="${env.BUILD_COMMON}">
<isset property="env.BUILD_COMMON" />
</condition>
<echo message="using build common dir: ${build.common.dir}"/>
<target name="runtests" description="runs the test cases" depends="compile, test.compile">
<java classname="com.wordnik.swagger.test.APITestRunner">
<arg value="JAVA" />
<classpath>
<pathelement location="build/main/java" />
<pathelement location="build/test/java" />
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
</classpath>
</java>
</target>
<!-- Creating directories used in app structure if required-->
<mkdir dir="build/main"/>
<mkdir dir="build/test"/>
<mkdir dir="lib/ext"/>
<mkdir dir="bin"/>
<mkdir dir="src/main/scala"/>
<mkdir dir="src/main/java"/>
<mkdir dir="src/test/java"/>
<mkdir dir="src/test/scala"/>
<target name="merge.custom" description="Copying from the lang folder to merge with generated">
<copy todir="../java/src/main/java/" overwrite="true">
<fileset dir="../java/src/lang"/>
</copy>
</target>
<import file="${build.common.dir}/ant/ant-common.xml" />
<import file="${build.common.dir}/ant/ant-test.xml" />
<import file="${build.common.dir}/ant/ant-server.xml" />
</project>

View File

@ -0,0 +1,41 @@
<ivy-module version="2.0">
<info organisation="wordnik" module="wordnik-java-driver"/>
<configurations>
<conf name="build" description="build wordnik-java"/>
<conf name="test" visibility="public"/>
<conf name="source" visibility="public"/>
<conf name="pom" visibility="public"/>
</configurations>
<publications>
<artifact name="wordnik-java-driver" type="jar" conf="build" ext="jar"/>
<artifact name="wordnik-java-driver" type="pom" conf="pom" ext="pom"/>
<artifact name="wordnik-java-driver-source" type="source" conf="source" ext="zip"/>
<artifact name="wordnik-java-driver-test" type="jar" conf="test" ext="jar"/>
</publications>
<dependencies>
<dependency org="wordnik" name="wordnik-libs-gen" rev="1.0.+"/>
<!-- jersey dependencies -->
<dependency org="junit" name="junit" rev="4.4" conf="build->default"/>
<dependency org="com.sun.jersey" name="jersey-json" rev="1.4" conf="build->default"/>
<dependency org="com.sun.jersey" name="jersey-client" rev="1.4" conf="build->default"/>
<dependency org="com.sun.jersey" name="jersey-server" rev="1.4" conf="build->default"/>
<dependency org="com.sun.jersey" name="jersey-core" rev="1.4" conf="build->default"/>
<dependency org="asm" name="asm-parent" rev="3.1" conf="build->default"/>
<dependency org="commons-beanutils" name="commons-beanutils" rev="1.8.0" conf="build->default"/>
<dependency org="org.antlr" name="stringtemplate" rev="3.2" conf="build->default"/>
<!-- jackson jars -->
<dependency org="org.codehaus.jackson" name="jackson-jaxrs" rev="1.7.1" conf="build->default"/>
<dependency org="org.codehaus.jackson" name="jackson-xc" rev="1.7.1" conf="build->default"/>
<dependency org="org.codehaus.jackson" name="jackson-mapper-asl" rev="1.7.1" conf="build->default"/>
<dependency org="net.sourceforge.cobertura" name="cobertura" rev="1.9.2" conf="test->default">
<exclude org="asm" name="asm-tree"/>
<exclude org="asm" name="asm"/>
</dependency>
</dependencies>
</ivy-module>

View File

@ -0,0 +1,19 @@
package com.wordnik.swagger.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation used to provide list of possible values
* @author ramesh
*
*/
@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AllowableValues {
String value() default "";
}

View File

@ -0,0 +1,13 @@
package com.wordnik.swagger.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodArgumentNames {
String value() default "";
}

View File

@ -0,0 +1,17 @@
package com.wordnik.swagger.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation used to indicate given property or field is required or not
* @author ramesh
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Required {
}

View File

@ -0,0 +1,22 @@
package com.wordnik.swagger.common;
/**
* Created by IntelliJ IDEA.
* User: ramesh
* Date: 4/12/11
* Time: 5:46 PM
* To change this template use File | Settings | File Templates.
*/
public class StringValue {
String word;
public String getWord() {
return word;
}
public void setWord(String value) {
this.word = value;
}
}

View File

@ -0,0 +1,216 @@
package com.wordnik.swagger.common;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Logger;
import javax.ws.rs.core.MultivaluedMap;
import com.wordnik.swagger.exception.APIException;
import com.wordnik.swagger.exception.APIExceptionCodes;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.DeserializationConfig.Feature;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.type.TypeReference;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.WebResource.Builder;
import com.sun.jersey.api.client.filter.LoggingFilter;
/**
* Provides way to initialize the communication with Wordnik API server.
* This is also a Base class for all API classes
* @author ramesh
*
*/
public class WordnikAPI {
private static String apiServer = "http://api.wordnik.com/v4";
private static String apiKey = "";
private static boolean loggingEnabled;
private static Logger logger = null;
protected static String POST = "POST";
protected static String GET = "GET";
protected static String PUT = "PUT";
protected static String DELETE = "DELETE";
protected static ObjectMapper mapper = new ObjectMapper();
static{
mapper.getDeserializationConfig().set(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.getSerializationConfig().set(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);
mapper.configure(SerializationConfig.Feature.WRITE_NULL_PROPERTIES, false);
mapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);
}
/**
* Initializes the API communication with required inputs.
* @param apiKey provide the key provided as part of registration
* @param apiServer Sets the URL for the API server. It is defaulted to the server
* 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 com.sun.jersey.api.client.filter.LoggingFilter}. Default output is sent to system.out.
* Create a logger ({@link java.util.logging.Logger} class and set using setLogger method.
*/
public static void initialize(String apiKey, String apiServer, boolean enableLogging) {
setApiKey(apiKey);
if(apiServer != null && apiServer.length() > 0) {
if(apiServer.substring(apiServer.length()-1).equals("/")){
apiServer = apiServer.substring(0, apiServer.length()-1);
}
setApiServer(apiServer);
}
loggingEnabled = enableLogging;
}
/**
* Set the logger instance used for Jersey logging.
* @param aLogger
*/
public static void setLogger(Logger aLogger) {
logger = aLogger;
}
/**
* Gets the API key used for server communication.
* This value is set using initialize method.
* @return
*/
public static String getApiKey() {
return apiKey;
}
private static void setApiKey(String apiKey) {
WordnikAPI.apiKey = apiKey;
}
/**
* Sets the URL for the API server. It is defaulted to the server used while building the driver.
* @return
*/
private static String getApiServer() {
return apiServer;
}
private static void setApiServer(String server) {
WordnikAPI.apiServer = server;
}
/**
* Invokes the API and returns the response as json string.
* This is an internal method called by individual APIs for communication. It sets the required HTTP headers
* based on API key and auth token.
* @param authToken - token that is received as part of authentication call. This is only needed for the calls that are secure.
* @param resourceURL - URL for the rest resource
* @param method - Method we should use for communicating to the back end.
* @param postObject - if the method is POST, provide the object that should be sent as part of post request.
* @return JSON response of the API call.
* @throws com.wordnik.swagger.exception.APIException if the call to API server fails.
*/
protected static String invokeAPI(String authToken, String resourceURL, String method, Map<String,
String> queryParams, Object postObject) throws APIException {
Client apiClient = Client.create();
//check for app key and server values
if(getApiKey() == null || getApiKey().length() == 0) {
String[] args = {getApiKey()};
throw new APIException(APIExceptionCodes.API_KEY_NOT_VALID, args);
}
if(getApiServer() == null || getApiServer().length() == 0) {
String[] args = {getApiServer()};
throw new APIException(APIExceptionCodes.API_SERVER_NOT_VALID, args);
}
//initialize the logger if needed
if(loggingEnabled) {
if(logger == null) {
apiClient.addFilter(new LoggingFilter());
}else{
apiClient.addFilter(new LoggingFilter(logger));
}
}
//make the communication
resourceURL = getApiServer() + resourceURL;
if(queryParams.keySet().size() > 0){
int i=0;
for(String paramName : queryParams.keySet()){
String symbol = "&";
if(i==0){
symbol = "?";
}
resourceURL = resourceURL + symbol + paramName + "=" + queryParams.get(paramName);
i++;
}
}
WebResource aResource = apiClient.resource(resourceURL);
// aResource.queryParams(queryParams);
//set the required HTTP headers
Builder builder = aResource.type("application/json");
builder.header("api_key", getApiKey());
if(authToken != null){
builder.header("auth_token", authToken);
}
ClientResponse clientResponse = null;
if(method.equals(GET)) {
clientResponse = builder.get(ClientResponse.class);
}else if (method.equals(POST)) {
clientResponse = builder.post(ClientResponse.class, serialize(postObject));
}else if (method.equals(PUT)) {
clientResponse = builder.put(ClientResponse.class, serialize(postObject));
}else if (method.equals(DELETE)) {
clientResponse = builder.delete(ClientResponse.class);
}
//process the response
if(clientResponse.getClientResponseStatus() == ClientResponse.Status.OK) {
String response = clientResponse.getEntity(String.class);
return response;
}else{
int responseCode = clientResponse.getClientResponseStatus().getStatusCode() ;
throw new APIException(responseCode, clientResponse.getEntity(String.class));
}
}
/**
* De-serialize the object from String to object of type input class name.
* @param response
* @param inputClassName
* @return
*/
public static Object deserialize(String response, Class inputClassName) throws APIException {
try {
System.out.println("Input :::::" + response);
Object responseObject = mapper.readValue(response, inputClassName);
return responseObject;
} catch (IOException ioe) {
String[] args = new String[]{response, inputClassName.toString()};
throw new APIException(APIExceptionCodes.ERROR_CONVERTING_JSON_TO_JAVA, args, "Error in coversting response json value to java object : " + ioe.getMessage(), ioe);
}
}
/**
* serialize the object from String to input object.
* @param input
* @return
*/
public static String serialize(Object input) throws APIException {
try {
if(input != null) {
return mapper.writeValueAsString(input);
}else{
return "";
}
} catch (IOException ioe) {
throw new APIException(APIExceptionCodes.ERROR_CONVERTING_JAVA_TO_JSON, "Error in coverting input java to json : " + ioe.getMessage(), ioe);
}
}
}

View File

@ -0,0 +1,84 @@
package com.wordnik.swagger.exception;
import com.sun.jersey.api.client.ClientResponse;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonCreator;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.annotate.JsonProperty;
/**
* Exception that is thrown if there are any issues in invoking Wordnik API.
*
* Each exception carries a code and message. Code can be either HTTP error response code {@link com.sun.jersey.api.client.ClientResponse.Status}
* or The list of possible Wordnik exception code that are listed in the interface {@link APIExceptionCodes}.
* User: ramesh
* Date: 3/31/11
* Time: 9:27 AM
*/
public class APIException extends Exception {
private String message;
private int code;
private String[] args;
@JsonCreator
public APIException() {
}
public APIException(String message) {
super(message);
}
public APIException(int code) {
this.code = code;
}
public APIException(int code, String message, Throwable t) {
super(message, t);
this.message = message;
this.code = code;
}
public APIException(int code, String[] args, String message, Throwable t) {
super(message, t);
this.message = message;
this.code = code;
this.args = args;
}
public APIException(int code, String message) {
super(message);
this.message = message;
this.code = code;
}
public APIException(int code, String[] args, String message) {
super(message);
this.message = message;
this.code = code;
this.args = args;
}
public APIException(int code, String[] args) {
this.code = code;
this.args = args;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
}

View File

@ -0,0 +1,38 @@
package com.wordnik.swagger.exception;
/**
* Lists all the possible exception codes
* @author ramesh
*
*/
public interface APIExceptionCodes {
/**
* System exception.
*/
public static final int SYSTEM_EXCEPTION = 0;
/**
* With Arguments as current key.
*/
public static final int API_KEY_NOT_VALID = 1000;
/**
* With arguments as current token value
*/
public static final int AUTH_TOKEN_NOT_VALID = 1001;
/**
* With arguments as input JSON and output class anme
*/
public static final int ERROR_CONVERTING_JSON_TO_JAVA = 1002;
/**
* With arguments as JAVA class name
*/
public static final int ERROR_CONVERTING_JAVA_TO_JSON = 1003;
public static final int ERROR_FROM_WEBSERVICE_CALL = 1004;
/**
* With arguments as current API server name
*/
public static final int API_SERVER_NOT_VALID = 1005;
}

View File

@ -0,0 +1,25 @@
package com.wordnik.swagger.exception;
/**
* Exception raised while generating code for java driver.
* User: ramesh
* Date: 3/31/11
* Time: 9:29 AM
*/
public class CodeGenerationException extends RuntimeException {
private String message;
public CodeGenerationException(String message){
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -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 class 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());
}
};

View File

@ -0,0 +1,40 @@
package $packageName$;
import $annotationPackageName$.AllowableValues;
import $annotationPackageName$.Required;
$imports:{ import |
import $import$;
}$
/**
* $model.description$
* NOTE: This class is auto generated by the drive code generator program so please do not edit the class manually.
* @author ramesh
*
*/
public class $className$ extends $extends$ {
$fields:{ field |
/**
* $field.description$
*/
private $field.fieldDefinition.returnType$ $field.fieldDefinition.name$ $field.fieldDefinition.initialization$;$\r$}$
$fields:{ field |
/**
* $field.description$
* $if(field.required)$@Required$endif$
* $if(field.allowableValues)$@AllowableValues(value="$field.allowedValuesString$")$endif$
*/
public $field.fieldDefinition.returnType$ get$field.fieldDefinition.NameForMethod$() {
return $field.fieldDefinition.name$;
}
public void set$field.fieldDefinition.NameForMethod$($field.fieldDefinition.returnType$ $field.fieldDefinition.name$) {
this.$field.fieldDefinition.name$ = $field.fieldDefinition.name$;
}
}$
}

View File

@ -0,0 +1,153 @@
package $packageName$;
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 |
import $import$;
}$
/**
* NOTE: This class is auto generated by the drive code generator program so please do not edit the class manually.
* @author ramesh
*
*/
public class $resource$ extends $extends$ {
$methods:{ method |
/**
* $method.description$
$method.arguments:{ argument |
* @param $argument.name$ $argument.description$
$if(argument.allowedValues)$
* Allowed values are - $argument.allowedValues$
$endif$
}$
*
$if(!method.responseVoid)$
* @return $method.returnValue$ {@link $method.returnClassName$} $endif$
* @throws APIException $method.exceptionDescription$
*/
$if(method.hasArguments)$
@MethodArgumentNames(value="$method.argumentNames; separator=", "$")
$endif$
public static $method.returnValue$ $method.name$($method.argumentDefinitions; separator=", "$) throws APIException {
$if(method.authToken)$
if(authToken == null || authToken.length() == 0) {
throw new APIException(APIExceptionCodes.AUTH_TOKEN_NOT_VALID);
}
$endif$
//parse inputs
String resourcePath = "$method.resourcePath$";
resourcePath = resourcePath.replace("{format}","json");
String method = "$method.methodType$";
Map<String, String> queryParams = new HashMap<String, String>();
$if(!method.inputModel)$
$method.queryParameters:{ argument |
if( $argument.name$ != null) {
queryParams.put("$argument.name$", toPathValue($argument.name$));
}
}$
$method.pathParameters:{ argument |
if( $argument.name$ != null) {
resourcePath = resourcePath.replace("{$argument.name$}", $argument.name$);
}
}$
$endif$
$if(method.inputModel)$
$method.queryParameters:{ argument |
if( $argument.inputModelClassArgument$ != null && $argument.methodNameFromModelClass$ != null) {
queryParams.put("$argument.name$", $argument.methodNameFromModelClass$);
}
}$
$method.pathParameters:{ argument |
if( $argument.inputModelClassArgument$ != null && $argument.methodNameFromModelClass$ != null) {
resourcePath = resourcePath.replace("{$argument.name$}", $argument.methodNameFromModelClass$);
}
}$
$endif$
//make the API Call
$if(method.postObject)$
$if(method.authToken)$
String response = invokeAPI(authToken, resourcePath, method, queryParams, postObject);
$endif$
$if(!method.authToken)$
String response = invokeAPI(null, resourcePath, method, queryParams, postObject);
$endif$
$endif$
$if(!method.postObject)$
$if(method.authToken)$
String response = invokeAPI(authToken, resourcePath, method, queryParams, null);
$endif$
$if(!method.authToken)$
String response = invokeAPI(null, resourcePath, method, queryParams, null);
$endif$
$endif$
//create output objects if the response has more than one object
$if(!method.responseVoid)$
if(response == null || response.length() == 0){
return null;
}
$if(!method.returnValueList)$
$method.returnValue$ responseObject = ($method.returnValue$)deserialize(response, $method.returnClassName$.class);
return responseObject;
$endif$
$if(method.returnValueList)$
TypeReference<ArrayList<$method.returnClassName$>> typeRef = new TypeReference<ArrayList<$method.returnClassName$>>() {
};
try {
List<$method.returnClassName$> responseObject = (List<$method.returnClassName$>) mapper.readValue(response, typeRef);
return responseObject;
} catch (IOException ioe) {
String[] args = new String[]{response, typeRef.toString()};
throw new APIException(APIExceptionCodes.ERROR_CONVERTING_JSON_TO_JAVA, args, "Error in converting response json value to java object : " + ioe.getMessage(), ioe);
}
$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();
}
}

View File

@ -0,0 +1,18 @@
package $packageName$;
/**
* Maintains the compatible server version against which the drive is written
* @author ramesh
*
*/
public class VersionChecker {
private String compatibleVersion = "$apiVersion$";
/**
* Gets the version against which the driver code was written
*/
public String getCompatibleVersion() {
return compatibleVersion;
}
}

37
ivy.xml Normal file
View File

@ -0,0 +1,37 @@
<ivy-module version="2.0">
<info organisation="wordnik" module="wordnik-libs-gen"/>
<configurations>
<conf name="build" visibility="public"/>
<conf name="test" visibility="public"/>
<conf name="source" visibility="public"/>
<conf name="pom" visibility="public"/>
<conf name="tools" visibility="public" extends="build"/>
</configurations>
<publications>
<artifact name="wordnik-libs-gen" type="jar" conf="build" ext="jar"/>
<artifact name="wordnik-libs-gen-test" type="jar" conf="test" ext="jar"/>
<artifact name="wordnik-libs-gen-tools" type="jar" conf="tools" ext="jar"/>
<artifact name="wordnik-libs-gen-source" type="zip" conf="source" ext="zip"/>
<artifact name="wordnik-libs-gen" type="pom" conf="pom" ext="pom"/>
</publications>
<dependencies>
<!-- jersey dependencies -->
<dependency org="junit" name="junit" rev="4.4" conf="build->default"/>
<dependency org="com.sun.jersey" name="jersey-json" rev="1.4" conf="build->default"/>
<dependency org="com.sun.jersey" name="jersey-client" rev="1.4" conf="build->default"/>
<dependency org="com.sun.jersey" name="jersey-server" rev="1.4" conf="build->default"/>
<dependency org="com.sun.jersey" name="jersey-core" rev="1.4" conf="build->default"/>
<dependency org="asm" name="asm-parent" rev="3.1" conf="build->default"/>
<dependency org="commons-beanutils" name="commons-beanutils" rev="1.8.0" conf="build->default"/>
<dependency org="org.antlr" name="stringtemplate" rev="3.2" conf="build->default"/>
<!-- jackson jars -->
<dependency org="org.codehaus.jackson" name="jackson-jaxrs" rev="1.7.1" conf="build->default"/>
<dependency org="org.codehaus.jackson" name="jackson-xc" rev="1.7.1" conf="build->default"/>
<dependency org="org.codehaus.jackson" name="jackson-mapper-asl" rev="1.7.1" conf="build->default"/>
<dependency org="net.sourceforge.cobertura" name="cobertura" rev="1.9.2" conf="test->default">
<exclude org="asm" name="asm-tree"/>
<exclude org="asm" name="asm"/>
</dependency>
</dependencies>
</ivy-module>

View File

@ -0,0 +1,336 @@
package com.wordnik.swagger.codegen;
import com.wordnik.swagger.codegen.api.SwaggerResourceDocReader;
import com.wordnik.swagger.codegen.config.*;
import com.wordnik.swagger.codegen.config.ApiConfiguration;
import com.wordnik.swagger.codegen.resource.*;
import com.wordnik.swagger.exception.CodeGenerationException;
import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* User: ramesh
* Date: 3/30/11
* Time: 6:59 PM
*/
public class DriverCodeGenerator {
private static String VERSION_OBJECT_TEMPLATE = "VersionChecker";
private static String MODEL_OBJECT_TEMPLATE = "ModelObject";
private static String API_OBJECT_TEMPLATE = "ResourceObject";
private static final String ENUM_OBJECT_TEMPLATE = "EnumObject";
private static final String PACKAGE_NAME = "packageName";
private ApiConfiguration config = null;
private LanguageConfiguration languageConfig = null;
private SwaggerResourceDocReader apiMarshaller;
protected DataTypeMappingProvider dataTypeMappingProvider;
protected RulesProvider codeGenRulesProvider;
protected NamingPolicyProvider nameGenerator;
/**
* Generate classes needed for the model and API invocation
*/
public void generateCode() {
apiMarshaller = new SwaggerResourceDocReader(this.config, this.getDataTypeMappingProvider(), this.getNameGenerator());
//read resources and get their documentation
List<Resource> resources = apiMarshaller.readResourceDocumentation();
StringTemplateGroup aTemplateGroup = new StringTemplateGroup("templates", languageConfig.getTemplateLocation());
if(resources.size() > 0) {
generateVersionHelper(resources.get(0).getApiVersion(), aTemplateGroup);
}
generateModelClasses(resources, aTemplateGroup);
generateModelClassesForInput(resources, aTemplateGroup);
generateEnumForAllowedValues(resources, aTemplateGroup);
generateAPIClasses(resources, aTemplateGroup);
}
/**
* 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.
* @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(languageConfig.getResourceClassLocation() + this.getNameGenerator().getVersionCheckerClassName()
+ languageConfig.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<Resource> resources, StringTemplateGroup templateGroup) {
List<String> generatedClassNames = new ArrayList();
for(Resource resource: resources) {
for(Model model : resource.getModels()){
if(!generatedClassNames.contains(model.getName()) && !this.getCodeGenRulesProvider().isModelIgnored(model.getName())){
List<String> imports = new ArrayList<String>();
imports.addAll(this.config.getDefaultModelImports());
for(ModelField param : model.getFields()){
for(String importDef : param.getFieldDefinition(this.getDataTypeMappingProvider()).getImportDefinitions()){
if(!imports.contains(importDef)){
imports.add(importDef);
}
}
}
StringTemplate template = templateGroup.getInstanceOf(MODEL_OBJECT_TEMPLATE);
template.setAttribute("fields", model.getFields());
template.setAttribute("imports", imports);
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(languageConfig.getModelClassLocation()+model.getGenratedClassName()+languageConfig.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.
* @param resources
* @param templateGroup
*/
private void generateModelClassesForInput(List<Resource> resources, StringTemplateGroup templateGroup) {
List<String> generatedClasses = new ArrayList<String>();
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, dataTypeMappingProvider, nameGenerator);
if(method.getInputModel() != null) {
Model model = method.getInputModel();
if(model != null){
if(!generatedClasses.contains(model.getName())) {
List<String> imports = new ArrayList<String>();
imports.addAll(this.config.getDefaultModelImports());
for(ModelField param : model.getFields()){
for(String importDef : param.getFieldDefinition(this.getDataTypeMappingProvider()).getImportDefinitions()){
if(!imports.contains(importDef)){
imports.add(importDef);
}
}
}
StringTemplate template = templateGroup.getInstanceOf(MODEL_OBJECT_TEMPLATE);
template.setAttribute("fields", model.getFields());
template.setAttribute("imports", imports);
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(languageConfig.getModelClassLocation()+model.getGenratedClassName()+languageConfig.getClassFileExtension());
writeFile(aFile, template.toString(), "Input model class");
generatedClasses.add(model.getName());
}
}
}
}
}
}
}
}
}
/**
* 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().size() > 1) {
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().getObjectType(operationParam.getDataType(), true));
for (String allowableValue : operationParam.getAllowableValues()) {
if(operationParam.getDataType().equalsIgnoreCase("string")){
valuePrefix = valueSuffix = "\"";
}
else{
valuePrefix = valueSuffix = "";
};
template.setAttribute("values.{name,value}",
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());
}
}
}
}
}
}
}
}
}
}
/**
* 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<Resource> resources, StringTemplateGroup templateGroup) {
for(Resource resource : resources) {
List<ResourceMethod> methods = new ArrayList<ResourceMethod>();
List<String> imports = new ArrayList<String>();
imports.addAll(this.config.getDefaultServiceImports());
methods = resource.generateMethods(resource, dataTypeMappingProvider, nameGenerator);
StringTemplate template = templateGroup.getInstanceOf(API_OBJECT_TEMPLATE);
String className = resource.generateClassName(nameGenerator);
List<ResourceMethod> filteredMethods = new ArrayList<ResourceMethod>();
for(ResourceMethod method:methods){
if(!this.getCodeGenRulesProvider().isMethodIgnored(className, method.getName())){
filteredMethods.add(method);
}
}
template.setAttribute("imports", imports);
template.setAttribute(PACKAGE_NAME, config.getApiPackageName());
template.setAttribute("annotationPackageName", languageConfig.getAnnotationPackageName());
template.setAttribute("modelPackageName", config.getModelPackageName());
template.setAttribute("exceptionPackageName", languageConfig.getExceptionPackageName());
template.setAttribute("resource", className);
template.setAttribute("methods", filteredMethods);
template.setAttribute("extends", config.getServiceBaseClass(className));
File aFile = new File(languageConfig.getResourceClassLocation()+ resource.generateClassName(nameGenerator) +languageConfig.getClassFileExtension());
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
*/
private void generateWrapperClassForTestData(List<String> generatedClassNames, StringTemplateGroup templateGroup) {
Model model = new Model();
model.setName("TestData");
model.setDescription("Class used to store all the test data. This should not be used for any development");
List<ModelField> modelFields = new ArrayList<ModelField>();
model.setFields(modelFields);
for(String className : generatedClassNames){
ModelField aParam = new ModelField();
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(this.getDataTypeMappingProvider().getListReturnTypeSignature("StringValue"));
modelFields.add(aParam);
List<String> imports = new ArrayList<String>();
imports.addAll(this.config.getDefaultModelImports());
imports.addAll(this.getDataTypeMappingProvider().getListImportPackages());
for(ModelField param : model.getFields()){
for(String importDef : param.getFieldDefinition(this.getDataTypeMappingProvider()).getImportDefinitions()){
if(!imports.contains(importDef)){
imports.add(importDef);
}
}
}
StringTemplate template = templateGroup.getInstanceOf(MODEL_OBJECT_TEMPLATE);
template.setAttribute("fields", model.getFields());
template.setAttribute("imports", imports);
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(languageConfig.getModelClassLocation()+model.getGenratedClassName()+languageConfig.getClassFileExtension());
writeFile(aFile, template.toString(), "Wrapper class for test data file");
}
private void writeFile(File aFile, String content, String classType){
try{
FileWriter aWriter = new FileWriter(aFile);
BufferedWriter bufWriter = new BufferedWriter(aWriter);
bufWriter.write(content);
bufWriter.close();
}catch(IOException ioe){
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;
}
}

View File

@ -0,0 +1,49 @@
package com.wordnik.swagger.codegen;
import java.util.ArrayList;
import java.util.List;
public class FieldDefinition {
private String returnType;
private String name;
private String initialization;
private List<String> importDefinitions = new ArrayList<String>();
public String getReturnType() {
return returnType;
}
public void setReturnType(String returnType) {
this.returnType = returnType;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getInitialization() {
return initialization;
}
public void setInitialization(String initialization) {
this.initialization = initialization;
}
public List<String> getImportDefinitions() {
return importDefinitions;
}
public String getNameForMethod() {
return name.substring(0,1).toUpperCase() + name.substring(1);
}
}

View File

@ -0,0 +1,68 @@
package com.wordnik.swagger.codegen;
import com.wordnik.swagger.codegen.config.NamingPolicyProvider;
public class MethodArgument {
public static String ARGUMENT_STRING = "String";
public static String ARGUMENT_INTEGER = "int";
public static String ARGUMENT_OBJECT = "Object";
private String name;
private String description;
private String dataType;
private String allowedValues;
private String inputModelClassArgument;
private String methodNameFromModelClass;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getDataType() {
return dataType;
}
public void setDataType(String dataType) {
this.dataType = dataType;
}
public String getAllowedValues() {
return allowedValues;
}
public void setAllowedValues(String allowedValues) {
this.allowedValues = allowedValues;
}
public String getInputModelClassArgument() {
return inputModelClassArgument;
}
public void setInputModelClassArgument(String inputModelClass, NamingPolicyProvider nameGenerator) {
this.inputModelClassArgument = nameGenerator.applyMethodNamingPolicy(inputModelClass);
if(name != null) {
methodNameFromModelClass = nameGenerator.createGetterMethodName(inputModelClassArgument, name);
}
}
public String getMethodNameFromModelClass() {
return methodNameFromModelClass;
}
}

View File

@ -0,0 +1,177 @@
package com.wordnik.swagger.codegen;
import com.wordnik.swagger.codegen.resource.Model;
import java.util.List;
public class ResourceMethod {
private String description;
private List<MethodArgument> arguments;
private List<MethodArgument> queryParameters;
private List<MethodArgument> pathParameters;
private String returnValue;
private String returnClassName;
private String exceptionDescription;
private List<String> argumentDefinitions;
private List<String> argumentNames;
private String name;
private boolean authToken;
private String resourcePath;
private String methodType;
private boolean postObject;
private Model inputModel;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<MethodArgument> getArguments() {
return arguments;
}
public void setArguments(List<MethodArgument> arguments) {
this.arguments = arguments;
}
public List<MethodArgument> getQueryParameters() {
return queryParameters;
}
public void setQueryParameters(List<MethodArgument> queryParameters) {
this.queryParameters = queryParameters;
}
public List<MethodArgument> getPathParameters() {
return pathParameters;
}
public void setPathParameters(List<MethodArgument> pathParameters) {
this.pathParameters = pathParameters;
}
public String getReturnValue() {
return returnValue;
}
public void setReturnValue(String returnValue) {
this.returnValue = returnValue;
}
public String getReturnClassName() {
return returnClassName;
}
public void setReturnClassName(String returnClassName) {
this.returnClassName = returnClassName;
}
public String getExceptionDescription() {
return exceptionDescription;
}
public void setExceptionDescription(String exceptionDescription) {
this.exceptionDescription = exceptionDescription;
}
public List<String> getArgumentDefinitions() {
return argumentDefinitions;
}
public void setArgumentDefinitions(List<String> argumentDefinitions) {
this.argumentDefinitions = argumentDefinitions;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isAuthToken() {
return authToken;
}
public void setAuthToken(boolean authToken) {
this.authToken = authToken;
}
public String getResourcePath() {
return resourcePath;
}
public void setResourcePath(String resourcePath) {
this.resourcePath = resourcePath;
}
public String getMethodType() {
return methodType;
}
public void setMethodType(String methodType) {
this.methodType = methodType;
}
public boolean isPostObject() {
return postObject;
}
public void setPostObject(boolean postObject) {
this.postObject = postObject;
}
public boolean isResponseVoid() {
return (this.getReturnClassName().equalsIgnoreCase("void"));
}
public Model getInputModel() {
return inputModel;
}
public void setInputModel(Model inputModel) {
this.inputModel = inputModel;
}
public List<String> getArgumentNames() {
return argumentNames;
}
public void setArgumentNames(List<String> argumentNames) {
this.argumentNames = argumentNames;
}
public boolean getHasArguments() {
if(this.getArgumentNames() != null && this.getArgumentNames().size() > 0){
return true;
}
return false;
}
public boolean isReturnValueList() {
if(this.getReturnValue().startsWith("List")){
return true;
}
return false;
}
}

View File

@ -0,0 +1,156 @@
package com.wordnik.swagger.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.swagger.codegen.config.DataTypeMappingProvider;
import com.wordnik.swagger.codegen.resource.Endpoint;
import com.wordnik.swagger.codegen.resource.Resource;
import com.wordnik.swagger.codegen.config.ApiConfiguration;
import com.wordnik.swagger.codegen.config.NamingPolicyProvider;
import com.wordnik.swagger.exception.CodeGenerationException;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* User: deepakmichael
* Date: 27/07/11
* Time: 9:32 PM
*/
public class SwaggerResourceDocReader {
private static String HEADER_NAME_API_VERSION = "Wordnik-Api-Version";
private String baseUrl;
private String apiKey;
private String apiListResource;
private ApiConfiguration apiConfiguration;
private final DataTypeMappingProvider dataTypeMappingProvider;
private final NamingPolicyProvider nameGenerator;
public SwaggerResourceDocReader(ApiConfiguration apiConfiguration, DataTypeMappingProvider dataTypeMappingProvider, NamingPolicyProvider nameGenerator) {
this.apiConfiguration = apiConfiguration;
this.dataTypeMappingProvider = dataTypeMappingProvider;
this.nameGenerator = nameGenerator;
readApiConfig();
}
public void readApiConfig() {
baseUrl = apiConfiguration.getApiUrl();
apiKey = apiConfiguration.getApiKey();
apiListResource = apiConfiguration.getApiListResource();
}
/**
* Reads the documentation of the resources and constructs the resource object that can be used
* for generating the driver related classes. The resource list string should be "," separated
*/
public List<Resource> readResourceDocumentation() {
List<Resource> resourceDocs = new ArrayList<Resource>();
Client apiClient = Client.create();
String resourceList = retrieveResourceList(apiClient);
//valid for input
if (baseUrl == null || resourceList == null ||
baseUrl.trim().length() == 0 ||
resourceList.trim().length() == 0) {
throw new CodeGenerationException("Base URL or Resource list input is null");
}
//create list of resource URL
String[] resources = resourceList.split(",");
List<String> resourceURLs = new ArrayList<String>();
for (String resource : resources) {
resource = trimResourceName(resource);
if (!resource.equals(trimResourceName( apiListResource ))) {
if(!resource.endsWith(".json")){
resource = resource.concat(".json");
}
resourceURLs.add(baseUrl + resource);
}
}
//make connection to resource and get the documentation
for (String resourceURL : resourceURLs) {
WebResource aResource = apiClient.resource(resourceURL);
aResource.header("api_key", apiKey);
ClientResponse clientResponse = aResource.header("api_key", apiKey).get(ClientResponse.class);
String version = clientResponse.getHeaders().get(HEADER_NAME_API_VERSION).get(0);//TODO - check if this is required
String response = clientResponse.getEntity(String.class);
try {
ObjectMapper mapper = new ObjectMapper();
mapper.getDeserializationConfig().set(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Resource aResourceDoc = deserializeResource(response, mapper);
aResourceDoc.setApiVersion(version);
resourceDocs.add(aResourceDoc);
} catch (IOException ioe) {
ioe.printStackTrace();
throw new CodeGenerationException("Error in coverting resource json documentation to java object");
}
}
return resourceDocs;
}
private String trimResourceName(String resource) {
if(resource.startsWith("/")){
resource = resource.substring(1,resource.length());
}
return resource;
}
private String retrieveResourceList(Client apiClient) {
String resourceCsv = "";
Resource resourceApi;
String apiResourceUrl = null;
if(apiListResource == null){
throw new CodeGenerationException("apiListingUrl needs to be defined in api configuration object");
}
if(!apiListResource.endsWith(".json")){
apiResourceUrl = trimResourceName( apiListResource.concat(".json") );
}
apiResourceUrl = baseUrl.concat(apiResourceUrl);
WebResource aResource = apiClient.resource(apiResourceUrl);
aResource.header("api_key", apiKey);
ClientResponse clientResponse = aResource.header("api_key", apiKey).get(ClientResponse.class);
String response = clientResponse.getEntity(String.class);
try {
ObjectMapper mapper = new ObjectMapper();
mapper.getDeserializationConfig().set(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
resourceApi = deserializeResource(response, mapper);
for(Endpoint api: resourceApi.getEndPoints()){
resourceCsv += (api.getPath() + ",");
}
}
catch (IOException ex) {
throw new CodeGenerationException("Error in coverting resource listing json documentation to java object");
}
return resourceCsv;
}
/**
* Deserializes the response and returns a Response object
* @param response
* @param mapper
* @return
* @throws IOException
*/
private Resource deserializeResource(String response, ObjectMapper mapper) throws IOException {
Resource resource = mapper.readValue(response, Resource.class);
resource.generateModelsFromWrapper(nameGenerator);
return resource;
}
}

View File

@ -0,0 +1,131 @@
package com.wordnik.swagger.codegen.config;
import com.wordnik.swagger.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<String, String> baseClassNames = new HashMap<String, String>();
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<String> 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<String> 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<String> getDefaultModelImports() {
return defaultModelImports;
}
public void setDefaultModelImports(List<String> defaultModelImports) {
this.defaultModelImports = defaultModelImports;
}
public List<String> getDefaultServiceImports() {
return defaultServiceImports;
}
public void setDefaultServiceImports(List<String> 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;
}
}

View File

@ -0,0 +1,187 @@
package com.wordnik.swagger.codegen.config;
import java.util.List;
/**
* Implementations of this class is responsible for generating mapping between rest data types and language
* specific data type
*
* User: ramesh
* Date: 5/27/11
* Time: 7:39 AM
*/
public interface DataTypeMappingProvider {
/**
* Checks nature of data type.
*
* This is needed in generating return values, input and model class generations.
*
* Example: in java <Code>String</Code>, <Code>Integer</Code>, <Code>Boolean</Code> are considered as primitive
* types
* @param type
* @return
*/
public boolean isPrimitiveType(String type);
/**
* provide the sttring that needs to be used when defining methods that returns no values
*
* Example: in java this value will be <code>void</code>
* @return
*/
public String getReturnTypeForVoidMethods();
/**
* Signature that should be used when returning list of given object type.
*
* Example: in java this output will look as <Code> List<User> </Code> for methods that returns a list of user objects
* @param typeClass of class that list object contains.
* @return
*/
public String getListReturnTypeSignature(String typeClass);
/**
* Signature that should be used when returning map of given object type.
*
* Example: in java this output will look as <Code> Map<User> </Code> 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 <Code> Set<User> </Code> 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
*
* <Code>
* new ArrayList<ClassName>()
* </Code>
*
* @param typeClass
* @return
*/
public String generateListInitialization(String typeClass);
/**
* Initialization need for map objects. Example. If it is java map the initialization will look as
*
* <Code>
* new HashMap<ClassName>()
* </Code>
*
* @param typeClass
* @return
*/
public String generateMapInitialization(String typeClass);
/**
* Initialization need for set objects. Example. If it is java set the initialization will look as
*
* <Code>
* new HashSet<ClassName>()
* </Code>
*
* @param typeClass
* @return
*/
public String generateSetInitialization(String typeClass);
/**
* Gets list of imports that needs to be included when used objects of type List.
*
* Example: in java while using lists we use an interface of <Code>List</Code> and implementation of
* <Code>ArrayList</Code>. SO the output will as follows:
* <Code>
* List<String> imports = new ArrayList<String>();
imports.add("java.util.List");
imports.add("java.util.ArrayList");
* </Code>
* @return
*/
public List<String> getListImportPackages();
/**
* Gets list of imports that needs to be included when used objects of type Map.
*
* Example: in java while using maps we use an interface of <Code>Map</Code> and implementation of
* <Code>HashMap</Code>. SO the output will as follows:
* <Code>
* List<String> imports = new ArrayList<String>();
imports.add("java.util.Map");
imports.add("java.util.HashMap");
* </Code>
* @return
*/
public List<String> 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 <Code>Set</Code> and implementation of
* <Code>HashSet</Code>. SO the output will as follows:
* <Code>
* List<String> imports = new ArrayList<String>();
imports.add("java.util.Set");
imports.add("java.util.HashSet");
* </Code>
* @return
*/
public List<String> getSetImportPackages();
/**
* Gets list of imports that needs to be included when used objects of type Date.
*
* Example: in java while using Data we use <Codejava.util.Date</Code>. So the output will as follows:
* <Code>
* List<String> imports = new ArrayList<String>();
imports.add("java.util.Date");
* </Code>
* @return
*/
public List<String> getDateImports();
/**
* Object type definition for a given input
*
* @param type
* @param primitiveObject
* @return
*/
public String getObjectType(String type, boolean primitiveObject);
/**
* Gets the value of return type converted from web service response documentation.
*
* Example: If the resource documentation ays return type as List[User] the equivalent translation for java will be
*
* <Code> List<User ></Code>
*
* If the input is Map[int, String] the equivalent java translation will be <Code> Map<Integer, String> </Code>
* @param type
* @return
*/
public String getReturnValueType(String type);
/**
* Gets the class of return values from web service response documentation. If the service returns list the class
* indicates type of object in the list
*
* Example: If the resource documentation ays return type as List[User] the equivalent translation for java will be
*
* <Code> User </Code>
*
* If the input is Map[int] the equivalent java translation will be <Code> Int </Code>
* @param type
* @return
*/
public String getReturnClassType(String type);
}

View File

@ -0,0 +1,78 @@
package com.wordnik.swagger.codegen.config;
import com.wordnik.swagger.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 String getResourceClassLocation() {
return 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;
}
}

View File

@ -0,0 +1,105 @@
package com.wordnik.swagger.codegen.config;
/**
* Implementor of this class is responsible for generating the names for service classes and methods in
* each of those service classes
*
* User: ramesh
* Date: 5/27/11
* Time: 7:36 AM
*/
public interface NamingPolicyProvider {
/**
* Gets name of the version checker class. We need not provide extension for the class as that will be read
* through a class extention configuration value.
*
* Example: In java this is VersionChecker.
*
* @return
*/
public String getVersionCheckerClassName();
/**
* Convert input string into class name format.
*
* Example: in java this will be init caps.
*
* @param input
* @return
*/
public String applyClassNamingPolicy(String input);
/**
* Transform the input string into method naming convention format.
*
* Example: In java, the will be Camel case
*
* @param input
* @return
*/
public String applyMethodNamingPolicy(String input);
/**
* Generates the name of service based on resource path.
*
* Example: for a resource path of http://beta.wordnik.com/v4/word.json the service name can be WordAPI
*
* @param resourcePath
* @return
*/
public String getServiceName(String resourcePath);
/**
* Generates the name of service methods.
*
* Resource documentation provides suggested names. Individual language can choose to use suggested name or
* generate the name based on end point path. Example: IN java we use suggested name
*
* @param endPoint
* @param suggestedName
* @return
*/
public String getMethodName(String endPoint, String suggestedName);
/**
* Generate of the input object using the resource path name.
*
* When the number of arguments for a method increases beyond certain limit, we want to capture all the arguments
* as a single input objects so that it is easy for client to understand the API.
*
* Example: get examples API on words resource takes inputs as : word, limit, include duplicates, content provider,
* use canonical, skip, limit. Instead of having all these as individual arguments create an input object with name
* WordsExampleInput and have above arguments as properties fo the object.
*
* @param serviceName
* @param resourcePath
* @return
*/
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.
*
* Example: If class name is user and attibute name is email the out in java language will be
* <code>user.getEmail()</code>
*
* @param className
* @param attributeName
* @return
*/
public String createGetterMethodName(String className, String attributeName);
}

View File

@ -0,0 +1,23 @@
package com.wordnik.swagger.codegen.config;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Maintains the overriding rules that we should use while generating the code.
*
* Example; If we need to ignore any REST methods or if we need special service extention classes they can be
* supplied through this configuration
*
* User: ramesh
* Date: 4/26/11
* Time: 8:01 AM
*/
public interface RulesProvider {
public boolean isMethodIgnored(String serviceName, String methodName);
public boolean isModelIgnored(String modelName);
}

View File

@ -0,0 +1,133 @@
package com.wordnik.swagger.codegen.config.common;
import com.wordnik.swagger.codegen.resource.Model;
import com.wordnik.swagger.codegen.config.NamingPolicyProvider;
import com.wordnik.swagger.exception.CodeGenerationException;
/**
* User: ramesh
* Date: 5/31/11
* Time: 7:03 AM
*/
public class CamelCaseNamingPolicyProvider implements NamingPolicyProvider {
/**
* gets the name of class that is responsible for tracking current library version
* @return
*/
public String getVersionCheckerClassName() {
return "VersionChecker";
}
/**
* Converts the first character of the input into string.
* Example: If the input is word, the return value will be Word
* @param input
* @return
*/
public String applyClassNamingPolicy(String input) {
if(input != null && input.length() > 0) {
return input.substring(0,1).toUpperCase() + input.substring(1);
}else{
throw new CodeGenerationException("Error converting input to first letter caps becuase of null input");
}
}
/**
* Converts the first character of the input into string.
* Example: If the input is word, the return value will be Word
* @param input
* @return
*/
public String applyMethodNamingPolicy(String input) {
if(input != null && input.length() > 0) {
return input.substring(0,1).toLowerCase() + input.substring(1);
}else{
throw new CodeGenerationException("Error converting input to first letter to lower because of null input");
}
}
public String getServiceName(String resourcePath) {
String className = null;
int index = resourcePath.indexOf(".");
if(index >= 0) {
String resourceName = resourcePath.substring(1,index);
className = applyClassNamingPolicy(resourceName);
}else{
String[] paths = resourcePath.split("/");
for(String path : paths) {
if(path != null && path.length() > 0) {
className = applyClassNamingPolicy(path);
break;
}
}
}
return className+ "API";
}
/**
* Generates the name of service methods.
*
* Resource documentation provides suggested names. Individual language can choose to use suggested name or
* generate the name based on end point path. Example: IN java we use suggested name
*
* @param endPoint
* @param suggestedName
* @return
*/
public String getMethodName(String endPoint, String suggestedName) {
return suggestedName;
}
public String getInputObjectName(String serviceName, String resourcePath) {
String inputobjectName = serviceName.substring(0, serviceName.length() - 3);
String[] pathElements = resourcePath.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(position < 0) {
inputobjectName = inputobjectName + applyClassNamingPolicy(pathElement) + Model.INPUT_OBJECT_SUFFIX;
}
}
}
}
return inputobjectName;
}
/**
* Generates a name for an enum for the param or field name.
* <p/>
* 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.
*
* Example: If class name is user and attibute name is email the out in java language will be
* <code>user.getEmail()</code>
*
* @param className
* @param attributeName
* @return
*/
public String createGetterMethodName(String className, String attributeName) {
return className+".get"+ applyClassNamingPolicy(attributeName)+"()";
}
}

View File

@ -0,0 +1,33 @@
package com.wordnik.swagger.codegen.config.java;
import com.wordnik.swagger.codegen.config.RulesProvider;
import java.util.ArrayList;
import java.util.List;
/**
* User: ramesh
* Date: 5/31/11
* Time: 7:04 AM
*/
public class JavaCodeGenRulesProvider implements RulesProvider {
private List<String> ignoreMethods = new ArrayList<String>();
private List<String> ignoreModels = new ArrayList<String>();
public JavaCodeGenRulesProvider() {
ignoreMethods.add("WordAPI.getWordFrequency");
ignoreMethods.add("WordAPI.getAudio");
ignoreMethods.add("WordAPI.getWordStats");
ignoreModels.add("wordStats");
}
public boolean isMethodIgnored(String serviceName, String methodName){
return (ignoreMethods.contains(serviceName+"."+methodName));
}
public boolean isModelIgnored(String modelName) {
return ignoreModels.contains(modelName);
}
}

View File

@ -0,0 +1,190 @@
package com.wordnik.swagger.codegen.config.java;
import com.wordnik.swagger.codegen.config.DataTypeMappingProvider;
import com.wordnik.swagger.codegen.config.NamingPolicyProvider;
import com.wordnik.swagger.codegen.config.common.CamelCaseNamingPolicyProvider;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* User: ramesh
* Date: 5/31/11
* Time: 7:03 AM
*/
public class JavaDataTypeMappingProvider implements DataTypeMappingProvider {
public static Map<String, String> primitiveValueMap = new HashMap<String, String>();
static{
primitiveValueMap.put("string", "String");
primitiveValueMap.put("String", "String");
primitiveValueMap.put("int", "int");
primitiveValueMap.put("integer", "int");
primitiveValueMap.put("Integer", "int");
primitiveValueMap.put("boolean", "boolean");
primitiveValueMap.put("Boolean", "boolean");
primitiveValueMap.put("long", "long");
primitiveValueMap.put("Long", "long");
primitiveValueMap.put("float", "float");
primitiveValueMap.put("Float", "float");
primitiveValueMap.put("Date", "Date");
primitiveValueMap.put("date", "Date");
}
public static Map<String, String> primitiveObjectMap = new HashMap<String, String>();
static{
primitiveObjectMap.put("string", "String");
primitiveObjectMap.put("String", "String");
primitiveObjectMap.put("int", "Integer");
primitiveObjectMap.put("integer", "Integer");
primitiveObjectMap.put("Integer", "Integer");
primitiveObjectMap.put("boolean", "Boolean");
primitiveObjectMap.put("Boolean", "Boolean");
primitiveObjectMap.put("long", "Long");
primitiveObjectMap.put("Long", "Long");
primitiveObjectMap.put("float", "Float");
primitiveObjectMap.put("Float", "Float");
primitiveObjectMap.put("Date", "Date");
primitiveObjectMap.put("date", "Date");
}
private NamingPolicyProvider nameGenerator = new CamelCaseNamingPolicyProvider();
public boolean isPrimitiveType(String type) {
if(type.equalsIgnoreCase("String") || type.equalsIgnoreCase("int") || type.equalsIgnoreCase("integer") ||
type.equalsIgnoreCase("boolean") || type.equalsIgnoreCase("float")|| type.equalsIgnoreCase("long") ){
return true;
}
return false;
}
/**
* If the data type is primitive and it is expecting object structure then return primitive objects
* else return primitive types
* @param type
* @param primitiveObject -- indicates if the object is primitive or not
* @return
*/
public String getObjectType(String type, boolean primitiveObject) {
if(isPrimitiveType(type)){
if(primitiveObject){
return primitiveObjectMap.get(type);
}else{
return primitiveValueMap.get(type);
}
}else{
return nameGenerator.applyClassNamingPolicy(type);
}
}
public String getListReturnTypeSignature(String typeClass) {
return "List<"+nameGenerator.applyClassNamingPolicy(typeClass)+">";
}
public String getReturnTypeForVoidMethods() {
return "void";
}
public String getMapReturnTypeSignature(String typeClass) {
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)+">()";
}
public String generateMapInitialization(String typeClass) {
return " new HashMap<"+nameGenerator.applyClassNamingPolicy(typeClass)+">()";
}
public String generateSetInitialization(String typeClass) {
return " new HashSet<"+nameGenerator.applyClassNamingPolicy(typeClass)+">()";
}
public List<String> getListImportPackages() {
List<String> imports = new ArrayList<String>();
imports.add("java.util.List");
imports.add("java.util.ArrayList");
return imports;
}
public List<String> getMapImportPackages() {
List<String> imports = new ArrayList<String>();
imports.add("java.util.Map");
imports.add("java.util.HashMap");
return imports;
}
public List<String> getSetImportPackages() {
List<String> imports = new ArrayList<String>();
imports.add("java.util.Set");
imports.add("java.util.HashSet");
return imports; }
public List<String> getDateImports() {
List<String> imports = new ArrayList<String>();
imports.add("java.util.Date");
return imports;
}
/**
* 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
* that map or list is returning.
* @param type
* @return
*/
public String getReturnClassType(String type) {
String classShortName = "";
if(type.startsWith("List[")){
classShortName = type.substring(5, type.length()-1);
classShortName = getObjectType(classShortName, true);
}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{
classShortName = getObjectType(type, true);
}
return classShortName;
}
/**
* 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
*/
public String getReturnValueType(String type) {
if(type.equalsIgnoreCase("void")|| type.equalsIgnoreCase("ok")){
return "void";
}
String classShortName = "";
if(type.startsWith("List[")){
classShortName = type.substring(5, type.length()-1);
classShortName = "List<"+getObjectType(classShortName, true)+">";
}else if (type.startsWith("Map[")) {
classShortName = type.substring(4, type.length()-1);
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);
}
return classShortName;
}
}

View File

@ -0,0 +1,80 @@
package com.wordnik.swagger.codegen.config.java;
import com.wordnik.swagger.codegen.DriverCodeGenerator;
import com.wordnik.swagger.codegen.config.ApiConfiguration;
import com.wordnik.swagger.codegen.config.LanguageConfiguration;
import com.wordnik.swagger.codegen.config.common.CamelCaseNamingPolicyProvider;
import com.wordnik.swagger.exception.CodeGenerationException;
import java.util.ArrayList;
import java.util.List;
/**
* User: ramesh
* Date: 6/16/11
* Time: 1:31 PM
*/
public class JavaLibCodeGen extends DriverCodeGenerator {
public static void main(String[] args) {
if(args.length < 1){
throw new CodeGenerationException("Invalid number of arguments passed: No command line argument was passed to the program for output path");
}
String outputPath = args[0];
JavaLibCodeGen codeGenerator = new JavaLibCodeGen(outputPath);
codeGenerator.generateCode();
}
public JavaLibCodeGen(String 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<String> defaultModelImports = new ArrayList<String>();
defaultModelImports.add("com.wordnik.swagger.common.WordListType");
defaultModelImports.add("com.wordnik.swagger.common.StringValue");
defaultModelImports.add("com.wordnik.swagger.common.Size");
defaultModelImports.add("com.wordnik.swagger.common.WordnikObject");
List<String> defaultServiceImports = new ArrayList<String>();
defaultServiceImports.add("com.wordnik.swagger.model.Long");
defaultServiceImports.add("com.wordnik.swagger.common.*");
defaultServiceImports.add("com.wordnik.swagger.common.ext.*");
apiConfiguration.setDefaultModelImports(defaultModelImports);
apiConfiguration.setDefaultServiceImports(defaultServiceImports);
apiConfiguration.setModelPackageName("com.wordnik.swagger.model");
apiConfiguration.setApiPackageName("com.wordnik.swagger.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/java/templates");
javaConfiguration.setExceptionPackageName("com.wordnik.swagger.exception");
javaConfiguration.setAnnotationPackageName("com.wordnik.swagger.annotations");
return javaConfiguration;
}
}

View File

@ -0,0 +1,53 @@
package com.wordnik.swagger.codegen.resource;
import com.wordnik.swagger.codegen.config.NamingPolicyProvider;
import org.codehaus.jackson.annotate.JsonProperty;
/**
* User: deepakmichael
* Date: 19/07/11
* Time: 1:21 AM
*/
public class ApiModelDefn {
@JsonProperty("id")
private String id;
@JsonProperty("properties")
private ApiPropertyListWrapper properties;
@JsonProperty("description")
private String description;
@JsonProperty("id")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@JsonProperty("properties")
public ApiPropertyListWrapper getProperties() {
return properties;
}
public void setProperties(ApiPropertyListWrapper properties) {
this.properties = properties;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Model toModel(String modelName, NamingPolicyProvider nameGenerator) {
Model model = new Model();
model.setName(modelName);
model.setDescription(this.getDescription());
model.setFields( this.getProperties().toFieldList( nameGenerator ) );
return model;
}
}

View File

@ -0,0 +1,27 @@
package com.wordnik.swagger.codegen.resource;
import org.codehaus.jackson.annotate.JsonAnyGetter;
import org.codehaus.jackson.annotate.JsonAnySetter;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class ApiModelListWrapper implements Serializable
{
private Map<String, ApiModelDefn> modelList = new HashMap<String, ApiModelDefn>();
@JsonAnyGetter
public Map<String, ApiModelDefn> getModelList() {
return this.modelList;
}
@JsonAnySetter
public void setModelList(String modelName, ApiModelDefn modelDefn) {
this.modelList.put(modelName, modelDefn);
}
}

View File

@ -0,0 +1,176 @@
package com.wordnik.swagger.codegen.resource;
import org.codehaus.jackson.annotate.JsonAnyGetter;
import org.codehaus.jackson.annotate.JsonAnySetter;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.annotate.JsonPropertyOrder;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@JsonPropertyOrder({
"id",
"default",
"items",
"description",
"name",
"enum",
"properties",
"required",
"notes",
"access",
"type"
})
public class ApiPropertyDefn implements Serializable
{
@JsonProperty("id")
private String id;
@JsonProperty("default")
private String defaultValue;
@JsonProperty("items")
private ApiPropertyDefn items;
@JsonProperty("description")
private String description;
@JsonProperty("name")
private String name;
@JsonProperty("enum")
private List<Object> possibleValues = new ArrayList<Object>();
@JsonProperty("properties")
private ApiPropertyListWrapper properties;
@JsonProperty("required")
private boolean required;
@JsonProperty("notes")
private String notes;
@JsonProperty("access")
private String access;
@JsonProperty("type")
private String type;
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
@JsonProperty("id")
public String getId() {
return id;
}
@JsonProperty("id")
public void setId(String id) {
this.id = id;
}
@JsonProperty("default")
public String getDefaultValue() {
return defaultValue;
}
@JsonProperty("default")
public void setDefault(String defaultvalue) {
this.defaultValue = defaultValue;
}
@JsonProperty("items")
public ApiPropertyDefn getItems() {
return items;
}
@JsonProperty("items")
public void setItems(ApiPropertyDefn items) {
this.items = items;
}
@JsonProperty("description")
public String getDescription() {
return description;
}
@JsonProperty("description")
public void setDescription(String description) {
this.description = description;
}
@JsonProperty("name")
public String getName() {
return name;
}
@JsonProperty("name")
public void setName(String name) {
this.name = name;
}
@JsonProperty("enum")
public List<Object> getPossibleValues() {
return possibleValues;
}
@JsonProperty("enum")
public void setEnum(List<Object> possibleValues) {
this.possibleValues = possibleValues;
}
@JsonProperty("properties")
public ApiPropertyListWrapper getProperties() {
return properties;
}
@JsonProperty("properties")
public void setProperties(ApiPropertyListWrapper properties) {
this.properties = properties;
}
@JsonProperty("required")
public boolean isRequired() {
return required;
}
@JsonProperty("required")
public void setRequired(boolean required) {
this.required = required;
}
@JsonProperty("notes")
public String getNotes() {
return notes;
}
@JsonProperty("notes")
public void setNotes(String notes) {
this.notes = notes;
}
@JsonProperty("access")
public String getAccess() {
return access;
}
@JsonProperty("access")
public void setAccess(String access) {
this.access = access;
}
@JsonProperty("type")
public String getType() {
return type;
}
@JsonProperty("type")
public void setType(String type) {
this.type = type;
}
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperties(String name, Object value) {
this.additionalProperties.put(name, value);
}
}

View File

@ -0,0 +1,67 @@
package com.wordnik.swagger.codegen.resource;
import com.wordnik.swagger.codegen.config.NamingPolicyProvider;
import org.codehaus.jackson.annotate.JsonAnyGetter;
import org.codehaus.jackson.annotate.JsonAnySetter;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class ApiPropertyListWrapper implements Serializable
{
private Map<String, ApiPropertyDefn> propertyList = new HashMap<String, ApiPropertyDefn>();
@JsonAnyGetter
public Map<String, ApiPropertyDefn> getPropertyList() {
return this.propertyList;
}
@JsonAnySetter
public void setPropertyList(String name, ApiPropertyDefn value) {
this.propertyList.put(name, value);
}
public List<ModelField> toFieldList(NamingPolicyProvider nameGenerator) {
List<ModelField> fields = new ArrayList<ModelField>();
ModelField field;
String propertyName;
ApiPropertyDefn propertyDefn;
for(Map.Entry<String, ApiPropertyDefn> propertyDefnEntry : this.getPropertyList().entrySet()) {
propertyName = propertyDefnEntry.getKey();
propertyDefn = propertyDefnEntry.getValue();
field = new ModelField();
field.setName(propertyName);
//TODO - need to handle this via the nameGenerator which will do this in case the propertyName is a key word in the language
if(propertyName.equals("enum") || propertyName.equals("default")){
field.setName(propertyName+"Value");
}
field.setDescription(propertyDefn.getDescription());
//field.setAllowableValues(propertyDefn.getPossibleValues()); //TODO
//field.setDataType(propertyDefn.getType()); //TODO - verify if this is needed for a model field - paramType is set
field.setParamType(propertyDefn.getType());
if(propertyDefn.getType().equals("array")){
String arrayItemType = propertyDefn.getItems().getType();
if(propertyDefn.getItems().getAdditionalProperties().get("$ref") != null) {
arrayItemType = (String) propertyDefn.getItems().getAdditionalProperties().get("$ref");
}
field.setParamType("List[" + nameGenerator.applyClassNamingPolicy(arrayItemType) + "]");
}
field.setDefaultValue(propertyDefn.getDefaultValue());
field.setInternalDescription(propertyDefn.getNotes());
field.setParamAccess(propertyDefn.getAccess());
field.setRequired(propertyDefn.isRequired());
//field.setWrapperName(propertyDefn);
fields.add(field);
}
return fields;
}
}

View File

@ -0,0 +1,122 @@
package com.wordnik.swagger.codegen.resource;
import com.wordnik.swagger.codegen.ResourceMethod;
import com.wordnik.swagger.codegen.config.DataTypeMappingProvider;
import com.wordnik.swagger.codegen.config.NamingPolicyProvider;
import java.util.ArrayList;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: ramesh
* Date: 3/30/11
* Time: 7:01 PM
* To change this template use File | Settings | File Templates.
*/
public class Endpoint {
private String path;
private String description;
private List<String> pathParameters;
private List<EndpointOperation> operations;
private List<ResourceMethod> methods;
private List<ErrorResponse> errorResponses;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<String> getPathParameters() {
return pathParameters;
}
public void setPathParameters(List<String> pathParameters) {
this.pathParameters = pathParameters;
}
public List<EndpointOperation> getOperations() {
return operations;
}
public void setOperations(List<EndpointOperation> operations) {
this.operations = operations;
setOperationResponses();
}
public List<ErrorResponse> getErrorResponses() {
return errorResponses;
}
public void setErrorResponses(List<ErrorResponse> errorResponses) {
this.errorResponses = errorResponses;
setOperationResponses();
}
private void setOperationResponses() {
if(this.errorResponses != null && this.operations != null && this.operations.size() > 0 ){
for(EndpointOperation operation: this.operations){
if(operation.getResponse() != null & operation.getResponse().size() > 0){
for(Response response : operation.getResponse()){
response.setErrorResponses(this.errorResponses);
}
}
}
}
}
public List<ResourceMethod> generateMethods(Resource resource, DataTypeMappingProvider dataTypeMapper, NamingPolicyProvider nameGenerator) {
if(methods == null){
methods = new ArrayList<ResourceMethod>();
if(getOperations() != null) {
for(EndpointOperation operation: getOperations()) {
if(!operation.isDeprecated() && areModelsAvailable(operation.getParameters(), resource, dataTypeMapper)) {
methods.add(operation.generateMethod(this, resource, dataTypeMapper, nameGenerator));
}
}
}
}
return methods;
}
private boolean areModelsAvailable(List<ModelField> 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(dataTypeMapper.isPrimitiveType(modelField.getDataType())){
isParamSetAvailable = true;
break;
}
if(model.getName().equalsIgnoreCase(modelField.getDataType())){
isParamSetAvailable = true;
break;
}
}
if(!isParamSetAvailable){
return false;
}
}
}
return isParamSetAvailable;
}
}

View File

@ -0,0 +1,333 @@
package com.wordnik.swagger.codegen.resource;
import com.wordnik.swagger.codegen.MethodArgument;
import com.wordnik.swagger.codegen.ResourceMethod;
import com.wordnik.swagger.codegen.config.DataTypeMappingProvider;
import com.wordnik.swagger.codegen.config.NamingPolicyProvider;
import java.util.ArrayList;
import java.util.List;
/**
* User: ramesh
* Date: 3/31/11
* Time: 7:54 AM
*/
public class EndpointOperation {
public static String PARAM_TYPE_QUERY = "query";
public static String PARAM_TYPE_PATH = "path";
public static String PARAM_TYPE_BODY = "body";
public static String PARAM_TYPE_HEADER = "header";
private static String AUTH_TOKEN_PARAM_NAME = "auth_token";
private static String API_KEY_PARAM_NAME = "api_key";
private static String FORMAT_PARAM_NAME = "format";
private static String AUTH_TOKEN_ARGUMENT_NAME = "authToken";
private String httpMethod;
private String summary = "";
private String notes = "";
private boolean open;
@Deprecated
private List<Response> response;
private String responseClass;
private List<ModelField> parameters;
private boolean deprecated;
private ResourceMethod method;
private List<String> tags;
@Deprecated
private String suggestedName;
private String nickname;
public String getHttpMethod() {
return httpMethod;
}
public void setHttpMethod(String httpMethod) {
this.httpMethod = httpMethod;
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
public boolean isOpen() {
return open;
}
public void setOpen(boolean open) {
this.open = open;
}
public List<Response> getResponse() {
return response;
}
public void setResponse(List<Response> response) {
this.response = response;
}
public String getResponseClass() {
return responseClass;
}
public void setResponseClass(String responseClass) {
this.responseClass = responseClass;
this.setResponse(new ArrayList<Response>());
Response response = new Response();
response.setValueType(this.responseClass);
this.getResponse().add(response);
}
public List<ModelField> getParameters() {
return parameters;
}
public void setParameters(List<ModelField> parameters) {
this.parameters = parameters;
}
public boolean isDeprecated() {
return deprecated;
}
public void setDeprecated(boolean deprecated) {
this.deprecated = deprecated;
}
public String getSuggestedName() {
return suggestedName;
}
public void setSuggestedName(String suggestedName) {
this.suggestedName = suggestedName;
}
public void setNickname(String nickname) {
this.nickname = nickname;
this.suggestedName = nickname;
}
public String getNickname() {
return nickname;
}
public List<String> getTags() {
return tags;
}
public void setTags(List<String> tags) {
this.tags = tags;
}
public ResourceMethod generateMethod(Endpoint endPoint, Resource resource, DataTypeMappingProvider dataTypeMapper, NamingPolicyProvider nameGenerator) {
if(method == null){
method = new ResourceMethod();
//add method description
method.setDescription(this.getSummary() + "\n " + 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.getSuggestedName()));
//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>();
method.setArguments(arguments);
method.setQueryParameters(queryParams);
method.setPathParameters(pathParams);
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(MethodArgument.ARGUMENT_STRING);
anArgument.setDescription(modelField.getDescription());
arguments.add(anArgument);
}else if(modelField.getParamType().equalsIgnoreCase(PARAM_TYPE_HEADER) &&
modelField.getName().equals(API_KEY_PARAM_NAME)){
//do nothing for API key parameter as all calls will automatically add API KEY to the http headers
}else if (modelField.getParamType().equalsIgnoreCase(PARAM_TYPE_PATH) &&
!modelField.getName().equalsIgnoreCase(FORMAT_PARAM_NAME)) {
anArgument.setName(modelField.getName());
anArgument.setDataType(MethodArgument.ARGUMENT_STRING);
anArgument.setDescription(modelField.getDescription());
arguments.add(anArgument);
pathParams.add(anArgument);
}else if (modelField.getParamType().equalsIgnoreCase(PARAM_TYPE_QUERY)) {
anArgument.setName(modelField.getName());
anArgument.setDataType(MethodArgument.ARGUMENT_STRING);
anArgument.setDescription(modelField.getDescription());
queryParams.add(anArgument);
arguments.add(anArgument);
}else if (modelField.getParamType().equalsIgnoreCase(PARAM_TYPE_BODY)) {
if(modelField.getName() == null) {
modelField.setName("postObject");
}
anArgument.setName(modelField.getName());
anArgument.setDataType(dataTypeMapper.getReturnValueType(modelField.getDataType()));
anArgument.setDescription(modelField.getDescription());
arguments.add(anArgument);
method.setPostObject(true);
}
if(modelField.isAllowMultiple() && dataTypeMapper.isPrimitiveType(modelField.getDataType())){
anArgument.setDataType(dataTypeMapper.getListReturnTypeSignature(
dataTypeMapper.getReturnValueType(modelField.getDataType())));
}
anArgument.setInputModelClassArgument(inputobjectName, nameGenerator);
}
}
}
//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() > 4){
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("postObject") && !argument.getName().equals("authToken")){
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);
}
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(arg.getDataType() + " " + arg.getName());
argumentNames.add(arg.getName());
}
}
method.setArgumentDefinitions(argumentDefinitions);
method.setArgumentNames(argumentNames);
}
//get method type
method.setMethodType(this.getHttpMethod());
//get return value
List<Response> response = this.getResponse();
method.setReturnValue(dataTypeMapper.getReturnValueType(response.get(0).getValueType()));
method.setReturnClassName(dataTypeMapper.getReturnClassType(response.get(0).getValueType()));
//get description string for exception
method.setExceptionDescription(calculateExceptionMessage());
}
return method;
}
/**
* Each operation can have one or many error responses Concatenate all the error responses and create on string
* @return
*/
private String calculateExceptionMessage() {
StringBuilder errorMessage = new StringBuilder();
if(this.getResponse() != null) {
for(Response response: this.getResponse()) {
if(response.getErrorResponses() != null) {
for(ErrorResponse errorResponse : response.getErrorResponses()){
errorMessage.append(errorResponse.getCode() + " - " + errorResponse.getReason() +" ");
}
}
}
}
return errorMessage.toString();
}
}

View File

@ -0,0 +1,33 @@
package com.wordnik.swagger.codegen.resource;
/**
* Created by IntelliJ IDEA.
* User: ramesh
* Date: 3/31/11
* Time: 8:24 AM
* To change this template use File | Settings | File Templates.
*/
public class ErrorResponse {
private int code;
private String reason;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
}

View File

@ -0,0 +1,49 @@
package com.wordnik.swagger.codegen.resource;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: ramesh
* Date: 3/31/11
* Time: 8:31 AM
* To change this template use File | Settings | File Templates.
*/
public class Model {
public static String INPUT_OBJECT_SUFFIX = "Input";
private String name;
private String description;
private List<ModelField> fields;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<ModelField> getFields() {
return fields;
}
public void setFields(List<ModelField> fields) {
this.fields = fields;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getGenratedClassName() {
return name.substring(0,1).toUpperCase() + name.substring(1);
}
}

View File

@ -0,0 +1,214 @@
package com.wordnik.swagger.codegen.resource;
import com.wordnik.swagger.codegen.FieldDefinition;
import com.wordnik.swagger.codegen.config.DataTypeMappingProvider;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
/**
* User: ramesh
* Date: 3/31/11
* Time: 7:57 AM
*/
public class ModelField {
private String name;
private String wrapperName;
private String description = "";
private String defaultValue;
private boolean required = false;
private boolean allowMultiple = false;
private List<String> allowableValues = null;
private String paramType;
private String dataType;
private String internalDescription;
private String paramAccess;
private FieldDefinition fieldDefinition;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getWrapperName() {
return wrapperName;
}
public void setWrapperName(String wrapperName) {
this.wrapperName = wrapperName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
public boolean isRequired() {
return required;
}
public void setRequired(boolean required) {
this.required = required;
}
public List<String> getAllowableValues() {
return allowableValues;
}
public boolean isAllowMultiple() {
return allowMultiple;
}
public void setAllowMultiple(boolean allowMultiple) {
this.allowMultiple = allowMultiple;
}
public void setAllowableValues(List<String> allowableValues) {
this.allowableValues = allowableValues;
}
public String getAllowedValuesString() {
String result = "";
if (this.allowableValues != null) {
for(String allowedValue: this.allowableValues){
result += (allowedValue +",");
}
}
if(result.length() == 0)
return null;
else
return result.substring(0, result.length() - 1);
}
public void setAllowedValues(String csvAlowedValue) {
List<String> allowedValues = new ArrayList<String>();
if (csvAlowedValue != null) {
StringTokenizer tokenizer = new StringTokenizer( csvAlowedValue, "," );
while(tokenizer.hasMoreTokens()){
tokenizer.nextToken(",");
}
}
this.setAllowableValues(allowedValues);
}
public String getParamType() {
return paramType;
}
public void setParamType(String paramType) {
this.paramType = paramType;
}
public String getInternalDescription() {
return internalDescription;
}
public void setInternalDescription(String internalDescription) {
this.internalDescription = internalDescription;
}
public String getParamAccess() {
return paramAccess;
}
public void setParamAccess(String paramAccess) {
this.paramAccess = paramAccess;
}
public String getDataType() {
return dataType;
}
public void setDataType(String dataType) {
this.dataType = dataType;
}
public FieldDefinition getFieldDefinition(){
return fieldDefinition;
}
public FieldDefinition getFieldDefinition(DataTypeMappingProvider dataTypeMapper) {
if(fieldDefinition == null) {
fieldDefinition = new FieldDefinition();
String type = paramType.trim();
if(type.contains("date")||type.contains("Date") ){
fieldDefinition.getImportDefinitions().add("java.util.Date");
}
if(type.startsWith("List[")){
fieldDefinition.getImportDefinitions().addAll(dataTypeMapper.getListImportPackages());
String entryType = type.substring(5, type.length()-1);
entryType = dataTypeMapper.getObjectType(entryType, true);
String returnType = dataTypeMapper.getListReturnTypeSignature(entryType);
fieldDefinition.setReturnType(returnType);
fieldDefinition.setInitialization(" = " + dataTypeMapper.generateListInitialization(entryType));
if(this.getWrapperName() != null){
fieldDefinition.setName(this.getWrapperName());
}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 = "";
String entryType = type.substring(4, type.length()-1);
keyClass = entryType.substring(0, entryType.indexOf(",") );
entryClass = entryType.substring(entryType.indexOf(",") + 1, entryType.length());
//entryType = dataTypeMapper.getObjectType(entryType, true);
entryType = dataTypeMapper.getObjectType(keyClass, true) + "," + dataTypeMapper.getObjectType(entryClass, true);
String returnType = dataTypeMapper.getMapReturnTypeSignature(entryType);
fieldDefinition.setReturnType(returnType);
fieldDefinition.setInitialization("= " + dataTypeMapper.generateMapInitialization(entryType));
if(this.getWrapperName() != null){
fieldDefinition.setName(this.getWrapperName());
}else{
fieldDefinition.setName(this.getName());
}
}else{
fieldDefinition.setReturnType(dataTypeMapper.getObjectType(type, false));
fieldDefinition.setName(this.getName());
}
}
return fieldDefinition;
}
}

View File

@ -0,0 +1,124 @@
package com.wordnik.swagger.codegen.resource;
import com.wordnik.swagger.codegen.ResourceMethod;
import com.wordnik.swagger.codegen.config.DataTypeMappingProvider;
import com.wordnik.swagger.codegen.config.NamingPolicyProvider;
import org.codehaus.jackson.annotate.JsonCreator;
import org.codehaus.jackson.annotate.JsonProperty;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* User: ramesh
* Date: 3/30/11
* Time: 7:01 PM
*/
public class Resource {
private String apiVersion;
//TODO rename the JSON property too after the sandbox var has been renamed
@JsonProperty("swaggerVersion")
private String swaggerVersion;
@JsonProperty("apis")
private List<Endpoint> endPoints = new ArrayList<Endpoint>();
@JsonProperty("models")
private ApiModelListWrapper modelListWrapper;
private List<Model> models = new ArrayList<Model>();
private String generatedClassName;
private List<ResourceMethod> methods;
@JsonCreator
public Resource() {
}
public String getApiVersion() {
return apiVersion;
}
public void setApiVersion(String apiVersion) {
this.apiVersion = apiVersion;
}
//TODO rename the JSON property too after the sandbox var has been renamed
@JsonProperty("swaggerVersion")
public String getSwaggerVersion() {
return swaggerVersion;
}
@JsonProperty("swaggerVersion")
public void setSwaggerVersion(String swaggerVersion) {
this.swaggerVersion = swaggerVersion;
}
@JsonProperty("apis")
public List<Endpoint> getEndPoints() {
return endPoints;
}
@JsonProperty("apis")
public void setEndPoints(List<Endpoint> endPoints) {
this.endPoints = endPoints;
}
@JsonProperty("models")
public ApiModelListWrapper getModelListWrapper() {
return modelListWrapper;
}
@JsonProperty("models")
public void setModelListWrapper(ApiModelListWrapper modelListWrapper) {
this.modelListWrapper = modelListWrapper;
}
public List<Model> getModels() {
return models;
}
/*public void setModels(List<Model> models) {
this.models = models;
}*/
public String generateClassName(NamingPolicyProvider nameGenerator) {
if (generatedClassName == null) {
String endPointPath = endPoints.get(0).getPath();
generatedClassName = nameGenerator.getServiceName(endPointPath);
}
return generatedClassName;
}
public List<ResourceMethod> generateMethods(Resource resource, DataTypeMappingProvider dataTypeMapper, NamingPolicyProvider nameGenerator) {
if(methods == null){
methods = new ArrayList<ResourceMethod>();
if(getEndPoints() != null) {
for(Endpoint endpoint: getEndPoints()){
methods.addAll(endpoint.generateMethods(resource, dataTypeMapper, nameGenerator));
}
}
}
return methods;
}
public void generateModelsFromWrapper(NamingPolicyProvider nameGenerator) {
String modelName;
ApiModelDefn modelDefn;
if (modelListWrapper != null) {
for (Map.Entry<String, ApiModelDefn> entry : modelListWrapper.getModelList().entrySet()) {
modelName = entry.getKey();
modelDefn = entry.getValue();
models.add (modelDefn.toModel(modelName, nameGenerator) );
}
}
}
}

View File

@ -0,0 +1,44 @@
package com.wordnik.swagger.codegen.resource;
import java.util.List;
/**
* User: ramesh
* Date: 3/31/11
* Time: 7:55 AM
*/
public class Response {
private String valueType;
private String condition;
private List<ErrorResponse> errorResponses;
public String getValueType() {
return valueType;
}
public void setValueType(String valueType) {
this.valueType = valueType;
}
public String getCondition() {
return condition;
}
public void setCondition(String condition) {
this.condition = condition;
}
public List<ErrorResponse> getErrorResponses() {
return errorResponses;
}
public void setErrorResponses(List<ErrorResponse> errorResponses) {
this.errorResponses = errorResponses;
}
}

View File

@ -0,0 +1,25 @@
package com.wordnik.swagger.exception;
/**
* Exception raised while generating code for java driver.
* User: ramesh
* Date: 3/31/11
* Time: 9:29 AM
*/
public class CodeGenerationException extends RuntimeException {
private String message;
public CodeGenerationException(String message){
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}