Swagger Codegen: Extract out deserializing code into new class - SwaggerApi; renamed swagr to swagger where used

This commit is contained in:
Deepak Michael 2011-07-27 22:28:24 +05:30
parent b61d3b2914
commit 851e916bf6
3 changed files with 197 additions and 156 deletions

View File

@ -3,6 +3,7 @@ package com.wordnik.codegen;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.wordnik.codegen.api.SwaggerApi;
import com.wordnik.codegen.config.CodeGenConfig;
import com.wordnik.codegen.config.GenerationEnvironmentConfig;
import com.wordnik.codegen.resource.*;
@ -13,10 +14,6 @@ import org.antlr.stringtemplate.StringTemplateGroup;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.DeserializationConfig.Feature;
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;
@ -28,22 +25,16 @@ import java.util.List;
*/
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 final String ENUM_OBJECT_TEMPLATE = "EnumObject";
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 final String PACKAGE_NAME = "packageName";
private CodeGenConfig config = null;
private GenerationEnvironmentConfig envConfig = null;
private String baseUrl;
private String apiKey;
private String apiListResource;
private SwaggerApi apiMarshaller;
public CodeGenConfig getConfig() {
return config;
@ -65,9 +56,9 @@ public class DriverCodeGenerator {
* Generate classes needed for the model and API invocation
*/
public void generateCode() {
readApiConfig();
apiMarshaller = new SwaggerApi(this.config);
//read resources and get their documentation
List<Resource> resources = this.readResourceDocumentation(baseUrl);
List<Resource> resources = apiMarshaller.readResourceDocumentation();
StringTemplateGroup aTemplateGroup = new StringTemplateGroup("templates",envConfig.getTemplateLocation());
if(resources.size() > 0) {
generateVersionHelper(resources.get(0).getApiVersion(), aTemplateGroup);
@ -78,141 +69,6 @@ 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) {
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);
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);
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 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
* @return
* @throws IOException
*/
private Resource deserializeResource(String response, ObjectMapper mapper) throws IOException {
Resource resource = mapper.readValue(response, Resource.class);
resource.generateModelsFromWrapper(this.config);
return resource;
}
/**
* 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.

View File

@ -0,0 +1,183 @@
package com.wordnik.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.codegen.config.CodeGenConfig;
import com.wordnik.codegen.resource.Endpoint;
import com.wordnik.codegen.resource.Resource;
import com.wordnik.exception.CodeGenerationException;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* User: deepakmichael
* Date: 27/07/11
* Time: 9:32 PM
*/
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;
private String apiKey;
private String apiListResource;
private CodeGenConfig codeGenConfig;
public SwaggerApi(CodeGenConfig driverCodeGenerator) {
codeGenConfig = driverCodeGenerator;
readApiConfig();
}
public 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
*/
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 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(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(codeGenConfig);
return resource;
}
}

View File

@ -18,8 +18,9 @@ public class Resource {
private String apiVersion;
//TODO rename the JSON property too after the sandbox var has been renamed
@JsonProperty("swagrVersion")
private String swagrVersion;
private String swaggerVersion;
@JsonProperty("apis")
private List<Endpoint> endPoints = new ArrayList<Endpoint>();
@ -35,7 +36,7 @@ public class Resource {
private List<ResourceMethod> methods;
@JsonCreator
public Resource() {//@JsonProperty("models") ApiModelListWrapper modelListWrapper, @JsonProperty("apis") List<Endpoint> endPoints)
public Resource() {
}
@ -47,14 +48,15 @@ public class Resource {
this.apiVersion = apiVersion;
}
//TODO rename the JSON property too after the sandbox var has been renamed
@JsonProperty("swagrVersion")
public String getSwagrVersion() {
return swagrVersion;
public String getSwaggerVersion() {
return swaggerVersion;
}
@JsonProperty("swagrVersion")
public void setSwagrVersion(String swagrVersion) {
this.swagrVersion = swagrVersion;
@JsonProperty("swaggerVersion")
public void setSwaggerVersion(String swaggerVersion) {
this.swaggerVersion = swaggerVersion;
}
@JsonProperty("apis")