Swagr code-gen: Reading baseurl, apikey and apiList resource from config and creating resource list from response of apiList resource

This commit is contained in:
Deepak Michael 2011-07-21 09:36:09 +05:30
parent 7adc4e32fd
commit 4e7fdd9e5c
4 changed files with 146 additions and 42 deletions

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<apiConfig>
<apiUrl>
http://swagr.api.wordnik.com/v4/
</apiUrl>
<apiKey>
myKey
</apiKey>
<apiListResource>
/list
</apiListResource>
</apiConfig>

View File

@ -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<Resource> resources = this.readResourceDocumentation(
"http://swagr.api.wordnik.com/v4/", "word.json", isNewApi);//word.json,words.json,wordList.json,wordLists.json,
List<Resource> 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<Resource> readResourceDocumentation(String baseUrl, String resourceList, Boolean newApi) {
private List<Resource> readResourceDocumentation(String baseUrl) {
List<Resource> resourceDocs = new ArrayList<Resource>();
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<String> resourceURLs = new ArrayList<String>();
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<Model> models = new ArrayList<Model>();
String modelName;
ApiModelDefn modelDefn;
if (apiResource.getModels() != null) {
for (Map.Entry<String, ApiModelDefn> 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<Model> models = new ArrayList<Model>();
String modelName;
ApiModelDefn modelDefn;
if (apiResource.getModels() != null) {
for (Map.Entry<String, ApiModelDefn> 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;
}

View File

@ -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;
}
}

View File

@ -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<String, Object> additionalProperties = new HashMap<String, Object>();
@JsonCreator
public ApiResource(@JsonProperty("models") ApiModelListWrapper models, @JsonProperty("apis") List<Endpoint> endPoints)
{
this.models = models;
this.endPoints = endPoints;
}
@JsonProperty("apiVersion")
public String getApiVersion() {
return apiVersion;