diff --git a/code-gen/conf/apiConfig.xml b/code-gen/conf/apiConfig.xml new file mode 100644 index 00000000000..19799c7c961 --- /dev/null +++ b/code-gen/conf/apiConfig.xml @@ -0,0 +1,13 @@ + + + + http://swagr.api.wordnik.com/v4/ + + + myKey + + + /list + + + \ No newline at end of file diff --git a/code-gen/src/main/java/com/wordnik/codegen/DriverCodeGenerator.java b/code-gen/src/main/java/com/wordnik/codegen/DriverCodeGenerator.java index 2d1c237fdfe..81b50f4974e 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/DriverCodeGenerator.java +++ b/code-gen/src/main/java/com/wordnik/codegen/DriverCodeGenerator.java @@ -12,10 +12,11 @@ import org.antlr.stringtemplate.StringTemplateGroup; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.DeserializationConfig.Feature; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -30,9 +31,16 @@ public class DriverCodeGenerator { private static String HEADER_NAME_API_VERSION = "Wordnik-Api-Version"; private static String VERSION_OBJECT_TEMPLATE = "VersionChecker"; private static String MODEL_OBJECT_TEMPLATE = "ModelObject"; - private static String API_OBJECT_TEMPLATE = "ResourceObject"; + private static String API_OBJECT_TEMPLATE = "ResourceObject"; + public 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 CodeGenConfig config = null; + private CodeGenConfig config = null; + private String baseUrl; + private String apiKey; + private String apiListResource; public CodeGenConfig getConfig() { return config; @@ -46,11 +54,9 @@ public class DriverCodeGenerator { * Generate classes needed for the model and API invocation */ public void generateCode() { + readApiConfig(); //read resources and get their documentation - //TODO - temporary change until new API server is up - Boolean isNewApi = true; - List resources = this.readResourceDocumentation( - "http://swagr.api.wordnik.com/v4/", "word.json", isNewApi);//word.json,words.json,wordList.json,wordLists.json, + List resources = this.readResourceDocumentation(baseUrl); StringTemplateGroup aTemplateGroup = new StringTemplateGroup("templates",config.getTemplateLocation()); if(resources.size() > 0) { generateVersionHelper(resources.get(0).getVersion(), aTemplateGroup); @@ -61,13 +67,44 @@ public class DriverCodeGenerator { generateAPIClasses(resources, aTemplateGroup); } + private void readApiConfig() { + try { + FileInputStream fileInputStream = new FileInputStream(API_CONFIG_LOCATION); + XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(fileInputStream); + int eventType = xmlStreamReader.getEventType(); + while(xmlStreamReader.hasNext()) { + eventType = xmlStreamReader.next(); + if(eventType == XMLStreamConstants.START_ELEMENT && + xmlStreamReader.getLocalName().equals(API_URL_CONFIG)){ + baseUrl = xmlStreamReader.getElementText().trim(); + } + if(eventType == XMLStreamConstants.START_ELEMENT && + xmlStreamReader.getLocalName().equals(API_KEY)){ + apiKey = xmlStreamReader.getElementText().trim(); + } + if(eventType == XMLStreamConstants.START_ELEMENT && + xmlStreamReader.getLocalName().equals(API_LISTING_URL)){ + apiListResource = xmlStreamReader.getElementText().trim(); + } + } + xmlStreamReader.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (XMLStreamException e) { + e.printStackTrace(); + } + } + /** * 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 */ - private List readResourceDocumentation(String baseUrl, String resourceList, Boolean newApi) { + private List readResourceDocumentation(String baseUrl) { List resourceDocs = new ArrayList(); + Client apiClient = Client.create(); + + String resourceList = retrieveResourceList(apiClient); //valid for input if (baseUrl == null || resourceList == null || @@ -81,23 +118,30 @@ public class DriverCodeGenerator { String[] resources = resourceList.split(","); List resourceURLs = new ArrayList(); for (String resource : resources) { - resourceURLs.add(baseUrl + resource); + 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 - Client apiClient = Client.create(); for (String resourceURL : resourceURLs) { WebResource aResource = apiClient.resource(resourceURL); - ClientResponse clientResponse = aResource.get(ClientResponse.class); + 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); String response = clientResponse.getEntity(String.class); try { ObjectMapper mapper = new ObjectMapper(); mapper.getDeserializationConfig().set(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); - Resource aResourceDoc = deserializeResource(response, mapper, newApi); + Resource aResourceDoc = deserializeResource(response, mapper); aResourceDoc.setVersion(version); resourceDocs.add(aResourceDoc); } catch (IOException ioe) { + ioe.printStackTrace(); throw new CodeGenerationException("Error in coverting resource json documentation to java object"); } } @@ -105,42 +149,72 @@ public class DriverCodeGenerator { } + 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 the apiConfig.xml eg. /listingResourceNameHere"); + } + 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(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 - * @param newApi * @return * @throws IOException */ - private Resource deserializeResource(String response, ObjectMapper mapper, Boolean newApi) throws IOException { + private Resource deserializeResource(String response, ObjectMapper mapper) throws IOException { Resource resource; - if(!newApi) { - resource = (Resource) mapper.readValue(response, Resource.class); - } - else{ - ApiResource apiResource = mapper.readValue(response, ApiResource.class); - //convert apiResource to resource - resource = new Resource(); - Model model; - List models = new ArrayList(); - String modelName; - ApiModelDefn modelDefn; - if (apiResource.getModels() != null) { - for (Map.Entry entry : apiResource.getModels().getModelList().entrySet()) { - modelName = entry.getKey(); - modelDefn = entry.getValue(); - model = new Model(); - model.setName(modelName); - model.setDescription(modelDefn.getDescription()); - model.setFields( modelDefn.getProperties().toFieldList( this.config ) ); - models.add( model ); - } - } - resource.setModels( models ); - resource.setEndPoints( apiResource.getEndPoints() ); - } + ApiResource apiResource = mapper.readValue(response, ApiResource.class); + resource = new Resource(); + Model model; + List models = new ArrayList(); + String modelName; + ApiModelDefn modelDefn; + if (apiResource.getModels() != null) { + for (Map.Entry entry : apiResource.getModels().getModelList().entrySet()) { + modelName = entry.getKey(); + modelDefn = entry.getValue(); + model = modelDefn.toModel(modelName, this.config); + models.add( model ); + } + } + resource.setModels( models ); + resource.setEndPoints( apiResource.getEndPoints() ); return resource; } diff --git a/code-gen/src/main/java/com/wordnik/codegen/resource/ApiModelDefn.java b/code-gen/src/main/java/com/wordnik/codegen/resource/ApiModelDefn.java index f2d3be7af39..f2834fb7a0a 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/resource/ApiModelDefn.java +++ b/code-gen/src/main/java/com/wordnik/codegen/resource/ApiModelDefn.java @@ -1,5 +1,6 @@ package com.wordnik.codegen.resource; +import com.wordnik.codegen.config.CodeGenConfig; import org.codehaus.jackson.annotate.JsonProperty; /** @@ -41,4 +42,12 @@ public class ApiModelDefn { public void setDescription(String description) { this.description = description; } + + public Model toModel(String modelName, CodeGenConfig config) { + Model model = new Model(); + model.setName(modelName); + model.setDescription(this.getDescription()); + model.setFields( this.getProperties().toFieldList( config ) ); + return model; + } } diff --git a/code-gen/src/main/java/com/wordnik/codegen/resource/ApiResource.java b/code-gen/src/main/java/com/wordnik/codegen/resource/ApiResource.java index aae5a8b70ea..c3c3c7c9ab0 100644 --- a/code-gen/src/main/java/com/wordnik/codegen/resource/ApiResource.java +++ b/code-gen/src/main/java/com/wordnik/codegen/resource/ApiResource.java @@ -1,5 +1,6 @@ package com.wordnik.codegen.resource; +import org.codehaus.jackson.annotate.JsonCreator; import org.codehaus.jackson.annotate.JsonProperty; import org.codehaus.jackson.annotate.JsonPropertyOrder; import org.codehaus.jackson.map.annotate.JsonSerialize; @@ -36,6 +37,13 @@ public class ApiResource implements Serializable private Object id; private Map additionalProperties = new HashMap(); + @JsonCreator + public ApiResource(@JsonProperty("models") ApiModelListWrapper models, @JsonProperty("apis") List endPoints) + { + this.models = models; + this.endPoints = endPoints; + } + @JsonProperty("apiVersion") public String getApiVersion() { return apiVersion;