diff --git a/code-gen/build.xml b/code-gen/build.xml index 89b262f552d..848c2102015 100644 --- a/code-gen/build.xml +++ b/code-gen/build.xml @@ -13,16 +13,24 @@ + - + - Must specify the parameter: outputPath eg. -DoutputPath=../java/src/main/java/com/wordnik/ + 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) + + outputPath for Api = ${outputPath} + + apiServerRootDir = ${apiServerRootDir} + @@ -34,10 +42,9 @@ - - - + + diff --git a/code-gen/conf/apiConfig.xml b/code-gen/conf/apiConfig.xml deleted file mode 100644 index 19799c7c961..00000000000 --- a/code-gen/conf/apiConfig.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - http://swagr.api.wordnik.com/v4/ - - - myKey - - - /list - - - \ No newline at end of file diff --git a/code-gen/conf/java/structure/build.xml b/code-gen/conf/java/structure/build.xml new file mode 100644 index 00000000000..30c58cdc45a --- /dev/null +++ b/code-gen/conf/java/structure/build.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code-gen/conf/java/structure/ivy.xml b/code-gen/conf/java/structure/ivy.xml new file mode 100644 index 00000000000..ec44869bb26 --- /dev/null +++ b/code-gen/conf/java/structure/ivy.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/src/lang/java/com/wordnik/annotations/AllowableValues.java b/code-gen/conf/java/structure/src/main/java/com/wordnik/annotations/AllowableValues.java similarity index 100% rename from java/src/lang/java/com/wordnik/annotations/AllowableValues.java rename to code-gen/conf/java/structure/src/main/java/com/wordnik/annotations/AllowableValues.java diff --git a/java/src/lang/java/com/wordnik/annotations/MethodArgumentNames.java b/code-gen/conf/java/structure/src/main/java/com/wordnik/annotations/MethodArgumentNames.java similarity index 100% rename from java/src/lang/java/com/wordnik/annotations/MethodArgumentNames.java rename to code-gen/conf/java/structure/src/main/java/com/wordnik/annotations/MethodArgumentNames.java diff --git a/java/src/lang/java/com/wordnik/annotations/Required.java b/code-gen/conf/java/structure/src/main/java/com/wordnik/annotations/Required.java similarity index 100% rename from java/src/lang/java/com/wordnik/annotations/Required.java rename to code-gen/conf/java/structure/src/main/java/com/wordnik/annotations/Required.java diff --git a/java/src/lang/java/com/wordnik/common/StringValue.java b/code-gen/conf/java/structure/src/main/java/com/wordnik/common/StringValue.java similarity index 100% rename from java/src/lang/java/com/wordnik/common/StringValue.java rename to code-gen/conf/java/structure/src/main/java/com/wordnik/common/StringValue.java diff --git a/java/src/lang/java/com/wordnik/common/WordnikAPI.java b/code-gen/conf/java/structure/src/main/java/com/wordnik/common/WordnikAPI.java similarity index 100% rename from java/src/lang/java/com/wordnik/common/WordnikAPI.java rename to code-gen/conf/java/structure/src/main/java/com/wordnik/common/WordnikAPI.java diff --git a/java/src/lang/java/com/wordnik/exception/APIException.java b/code-gen/conf/java/structure/src/main/java/com/wordnik/exception/APIException.java similarity index 100% rename from java/src/lang/java/com/wordnik/exception/APIException.java rename to code-gen/conf/java/structure/src/main/java/com/wordnik/exception/APIException.java diff --git a/java/src/lang/java/com/wordnik/exception/APIExceptionCodes.java b/code-gen/conf/java/structure/src/main/java/com/wordnik/exception/APIExceptionCodes.java similarity index 100% rename from java/src/lang/java/com/wordnik/exception/APIExceptionCodes.java rename to code-gen/conf/java/structure/src/main/java/com/wordnik/exception/APIExceptionCodes.java diff --git a/java/src/lang/java/com/wordnik/exception/CodeGenerationException.java b/code-gen/conf/java/structure/src/main/java/com/wordnik/exception/CodeGenerationException.java similarity index 100% rename from java/src/lang/java/com/wordnik/exception/CodeGenerationException.java rename to code-gen/conf/java/structure/src/main/java/com/wordnik/exception/CodeGenerationException.java diff --git a/code-gen/conf/templates/java/EnumObject.st b/code-gen/conf/java/templates/EnumObject.st similarity index 100% rename from code-gen/conf/templates/java/EnumObject.st rename to code-gen/conf/java/templates/EnumObject.st diff --git a/code-gen/conf/templates/java/ModelObject.st b/code-gen/conf/java/templates/ModelObject.st similarity index 100% rename from code-gen/conf/templates/java/ModelObject.st rename to code-gen/conf/java/templates/ModelObject.st diff --git a/code-gen/conf/templates/java/ResourceObject.st b/code-gen/conf/java/templates/ResourceObject.st similarity index 100% rename from code-gen/conf/templates/java/ResourceObject.st rename to code-gen/conf/java/templates/ResourceObject.st diff --git a/code-gen/conf/templates/java/VersionChecker.st b/code-gen/conf/java/templates/VersionChecker.st similarity index 100% rename from code-gen/conf/templates/java/VersionChecker.st rename to code-gen/conf/java/templates/VersionChecker.st diff --git a/code-gen/src/main/java/com/wordnik/codegen/api/SwaggerApi.java b/code-gen/src/main/java/com/wordnik/codegen/api/SwaggerApi.java index 8590dbbf2cf..e5a88267bee 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/api/SwaggerApi.java +++ b/code-gen/src/main/java/com/wordnik/codegen/api/SwaggerApi.java @@ -23,11 +23,6 @@ import java.util.List; */ public class SwaggerApi { - private static final String API_CONFIG_LOCATION = "conf/apiConfig.xml"; - private static final String API_URL_CONFIG = "apiUrl"; - private static final String API_KEY = "apiKey"; - private static final String API_LISTING_URL = "apiListResource"; - private static String HEADER_NAME_API_VERSION = "Wordnik-Api-Version"; private String baseUrl; @@ -117,7 +112,7 @@ public class SwaggerApi { Resource resourceApi; String apiResourceUrl = null; if(apiListResource == null){ - throw new CodeGenerationException("apiListingUrl needs to be defined in the apiConfig.xml eg. /listingResourceNameHere"); + throw new CodeGenerationException("apiListingUrl needs to be defined in api configuration object"); } if(!apiListResource.endsWith(".json")){ apiResourceUrl = trimResourceName( apiListResource.concat(".json") ); diff --git a/code-gen/src/main/java/com/wordnik/codegen/config/CodeGenConfig.java b/code-gen/src/main/java/com/wordnik/codegen/config/CodeGenConfig.java deleted file mode 100644 index 7db1cf3557c..00000000000 --- a/code-gen/src/main/java/com/wordnik/codegen/config/CodeGenConfig.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.wordnik.codegen.config; - -/** - * Sets the configurations required for the code generation - * - * User: ramesh - * Date: 5/25/11 - * Time: 8:39 AM - */ -public abstract class CodeGenConfig { - - private RulesProvider codeGenRulesProvider; - - private DataTypeMappingProvider dataTypeMapper; - - private NamingPolicyProvider nameGenerator; - - -} diff --git a/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaLibCodeGen.java b/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaLibCodeGen.java index 37e2a81c1ce..9cb1ee8182d 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaLibCodeGen.java +++ b/code-gen/src/main/java/com/wordnik/codegen/config/java/JavaLibCodeGen.java @@ -71,7 +71,7 @@ public class JavaLibCodeGen extends DriverCodeGenerator { LanguageConfiguration javaConfiguration = new LanguageConfiguration(); javaConfiguration.setClassFileExtension(".java"); javaConfiguration.setOutputDirectory(outputPath); - javaConfiguration.setTemplateLocation("conf/templates/java"); + javaConfiguration.setTemplateLocation("conf/java/templates"); javaConfiguration.setExceptionPackageName("com.wordnik.exception"); javaConfiguration.setAnnotationPackageName("com.wordnik.annotations"); return javaConfiguration; diff --git a/java/src/lang/com/wordnik/annotations/AllowableValues.java b/java/src/lang/com/wordnik/annotations/AllowableValues.java new file mode 100644 index 00000000000..35f185295b2 --- /dev/null +++ b/java/src/lang/com/wordnik/annotations/AllowableValues.java @@ -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 ""; +} diff --git a/java/src/lang/com/wordnik/annotations/MethodArgumentNames.java b/java/src/lang/com/wordnik/annotations/MethodArgumentNames.java new file mode 100644 index 00000000000..6022ecea410 --- /dev/null +++ b/java/src/lang/com/wordnik/annotations/MethodArgumentNames.java @@ -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 ""; +} diff --git a/java/src/lang/com/wordnik/annotations/Required.java b/java/src/lang/com/wordnik/annotations/Required.java new file mode 100644 index 00000000000..16538c8053a --- /dev/null +++ b/java/src/lang/com/wordnik/annotations/Required.java @@ -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 { + +} diff --git a/java/src/lang/java/com/wordnik/common/Size.java b/java/src/lang/com/wordnik/common/Size.java similarity index 100% rename from java/src/lang/java/com/wordnik/common/Size.java rename to java/src/lang/com/wordnik/common/Size.java diff --git a/java/src/lang/com/wordnik/common/StringValue.java b/java/src/lang/com/wordnik/common/StringValue.java new file mode 100644 index 00000000000..66d61e73c17 --- /dev/null +++ b/java/src/lang/com/wordnik/common/StringValue.java @@ -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; + } +} diff --git a/java/src/lang/java/com/wordnik/common/WordListType.java b/java/src/lang/com/wordnik/common/WordListType.java similarity index 100% rename from java/src/lang/java/com/wordnik/common/WordListType.java rename to java/src/lang/com/wordnik/common/WordListType.java diff --git a/java/src/lang/com/wordnik/common/WordnikAPI.java b/java/src/lang/com/wordnik/common/WordnikAPI.java new file mode 100644 index 00000000000..6527b340e0b --- /dev/null +++ b/java/src/lang/com/wordnik/common/WordnikAPI.java @@ -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 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); + } + } +} diff --git a/java/src/lang/java/com/wordnik/common/WordnikObject.java b/java/src/lang/com/wordnik/common/WordnikObject.java similarity index 100% rename from java/src/lang/java/com/wordnik/common/WordnikObject.java rename to java/src/lang/com/wordnik/common/WordnikObject.java diff --git a/java/src/lang/java/com/wordnik/common/ext/AbstractWordAPI.java b/java/src/lang/com/wordnik/common/ext/AbstractWordAPI.java similarity index 100% rename from java/src/lang/java/com/wordnik/common/ext/AbstractWordAPI.java rename to java/src/lang/com/wordnik/common/ext/AbstractWordAPI.java diff --git a/java/src/lang/com/wordnik/exception/APIException.java b/java/src/lang/com/wordnik/exception/APIException.java new file mode 100644 index 00000000000..42c27118e55 --- /dev/null +++ b/java/src/lang/com/wordnik/exception/APIException.java @@ -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; + } +} diff --git a/java/src/lang/com/wordnik/exception/APIExceptionCodes.java b/java/src/lang/com/wordnik/exception/APIExceptionCodes.java new file mode 100644 index 00000000000..013f364519a --- /dev/null +++ b/java/src/lang/com/wordnik/exception/APIExceptionCodes.java @@ -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; + +} diff --git a/java/src/lang/com/wordnik/exception/CodeGenerationException.java b/java/src/lang/com/wordnik/exception/CodeGenerationException.java new file mode 100644 index 00000000000..7b55cb2852a --- /dev/null +++ b/java/src/lang/com/wordnik/exception/CodeGenerationException.java @@ -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; + } +} +