Swagger Codegen: 'structure' folder created that contains initial seeded framework codea and files like build.xml for the project to be created. 'lang' folder in api-server-lib that contains code custom to the generated Api

This commit is contained in:
Deepak Michael
2011-07-31 01:43:57 +05:30
parent ddb8eff5b8
commit 568ab979f5
31 changed files with 534 additions and 44 deletions

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.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.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.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.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.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.common;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Logger;
import javax.ws.rs.core.MultivaluedMap;
import com.wordnik.exception.APIException;
import com.wordnik.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.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.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.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.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;
}
}