Swagger: AS3 sdk - Refactoring towards better names and cleanup

This commit is contained in:
Deepak Michael 2011-08-29 11:16:38 +05:30
parent d1fff11394
commit 2f311849d8
20 changed files with 219 additions and 72 deletions

View File

@ -11,10 +11,7 @@
"defaultModelImports":[],
"defaultServiceImports":["mx.rpc.AsyncToken","mx.utils.UIDUtil",
"flash.utils.Dictionary","flash.events.EventDispatcher",
"com.wordnik.swagger.common.ApiUserCredentials","com.wordnik.swagger.event.Response",
"com.wordnik.swagger.common.SwaggerApi"],
"defaultServiceImports":[],
"modelPackageName":"com.wordnik.swagger.model",

View File

@ -99,6 +99,10 @@
<include-libraries file="${basedir}/${libpath}/" />
<source-path path-element="${sourcepath}" />
<keep-as3-metadata name="XmlRootNode"/>
<keep-as3-metadata name="XmlElement"/>
<keep-as3-metadata name="XmlElements"/>
<!-- include our Class packages into the build (com folder) -->
<include-sources dir="${sourcepath}" includes="*" />

View File

@ -0,0 +1,28 @@
# Window and document title for the documentation
title=Sample app AS3 SDK API Documentation
#Path to the source folder where the .as files are located
sourcepath = ./src/main/as3
# Class-folders you want to search for classes to be included in the docs, seperated by spaces (for example ../com/ ../net/ )
# to include every .as and .mxml file within your project, just state ../
domainextensions = ./src/main/as3
# The Location of deployment library on your Computer (PC/Mac) for compiled SWC file
liboutputfolder = bin
liboutputfile = as3-sample-sdk.swc
libpath = lib
# The Location of the output folder for your generated documents
docsoutputfolder = asdoc
# Home directory for flex sdk 3, change this to build for Mac or PC using # as comment
# SDK_HOME = C:/Program Files/Adobe/Flash Builder 4/sdks/3.5.0
# SDK_HOME = /Applications/Adobe Flash Builder 4/sdks/3.5.0
# SDK_HOME = /usr/local/flex_sdk_4.1.0/
# FLEX_HOME = /usr/local/flex_sdk_4.1.0/
# The location of your asdoc.exe, change this to build for Mac or PC using # as comment
#asdoc.exe = C:/Program Files/Adobe/Flash Builder 4/sdks/3.5.0/bin/asdoc.exe
#asdoc.exe = /Applications/Adobe Flash Builder 4/sdks/3.5.0/bin/asdoc

View File

@ -0,0 +1,131 @@
<!-- Flex Library Project ASDocs -->
<project name="AS3SDKCompile" default="compile" basedir=".">
<!-- import our build properties file -->
<property file="./build.properties"/>
<property environment="env"/>
<property name="FLEX_HOME" value="${env.SDK_HOME}"/>
<!-- Flex Ant Tasks used to perform compc and mxml compiling more info at http://labs.adobe.com/wiki/index.php/Flex_Ant_Tasks -->
<taskdef resource="flexTasks.tasks" classpath="${env.SDK_HOME}/ant/lib/flexTasks.jar"/>
<target name="setup" description="perform an setup operations"/>
<!-- Execute the ASDoc Compile wich runs 3 seperate tasks in a series -->
<target name="compile" description="series of tasks to create docs and swc">
<!--<antcall target="cleanDir" description="clean the docs directory"/>-->
<!--<antcall target="asDocs" description="full build of asdocs"/>-->
<antcall target="buildSWC" description="build the SWC file"/>
</target>
<target name="deploy" description="perform an deployment operations"/>
<target name="install" description="perform an installation operations"/>
<!--
DELETE the existing output folder and files and then re-generate the output folder
-->
<target name="clean" description="DELETE the existing output folder and files and then re-generate the output folder">
<delete dir="${basedir}/${docsoutputfolder}" failonerror="true" includeemptydirs="true"/>
<delete file="${basedir}/${liboutputfolder}/${liboutputfile}"/>
<delete dir="${basedir}/dist" failonerror="true" includeemptydirs="true"/>
<mkdir dir="${basedir}/${docsoutputfolder}"/>
</target>
<!--
Run the ASDoc executable and generate the ASDocs to the new output folder
-->
<target name="docs" description="Run the ASDoc executable and generate the ASDocs to the new output folder">
<exec executable="${env.SDK_HOME}/bin/asdoc" failonerror="true">
<arg line="-doc-sources ${sourcepath}"/>
<arg line="-source-path ${sourcepath}"/>
<arg line="-footer 'Copyright Wordnik'"/>
<arg line="-package com.wordnik.swagger.api 'Contains the apis which are used by clients to make calls to the services deployed'"/>
<arg line="-package com.wordnik.swagger.model 'Contains common classes which encapsulate data elements required'"/>
<arg line="-package com.wordnik.swagger.common 'Contains classes which are used by the api classes to invoke the deployed api like SwaggerApi - a base class, ApiUserCredentials, etc.''"/>
<arg line="-package com.wordnik.swagger.event 'Results of calls made to Wordnik are returned via dispatched events. This package contains such event classes. Right now thats just ApiClientEvent and Response.'"/>
<arg line="-package com.wordnik.swagger.exception 'Contains classes that encapsulate the errors generated'"/>
<arg value="-window-title"/>
<arg value="${title}"/>
<arg value="-main-title"/>
<arg value="${title}"/>
<arg value="-output"/>
<arg value="${basedir}/${docsoutputfolder}"/>
<arg value="-external-library-path"/>
<arg value="${basedir}/${libpath}"/>
</exec>
<echo>docs created</echo>
</target>
<!--
Compile the SWC file library including lib folder and the path to our classes, we use compc for library,
check the docs for Flex Ant Tasks, http://labs.adobe.com/wiki/index.php/Flex_Ant_Tasks.
-->
<target name="buildSWC" description="Compile the SWC file for the Librayr Project">
<compc output="${basedir}/${liboutputfolder}/${liboutputfile}">
<!--
Include the path to any external SWC files used in the sdk, you may have to place name of SWC (ASAXB-0.1.1.swc) at end of path.
So file path would be file="${basedir}/${libpath}/ASAXB-0.1.1.swc"
-->
<include-libraries file="${basedir}/${libpath}/" />
<source-path path-element="${sourcepath}" />
<keep-as3-metadata name="XmlRootNode"/>
<keep-as3-metadata name="XmlElement"/>
<keep-as3-metadata name="XmlElements"/>
<!-- include our Class packages into the build (com folder) -->
<include-sources dir="${sourcepath}" includes="*" />
</compc>
<echo>SWC created</echo>
</target>
<target name="dist" depends="clean, buildSWC, docs">
<mkdir dir="${basedir}/dist/lib"/>
<mkdir dir="${basedir}/dist/docs"/>
<mkdir dir="${basedir}/dist/sample"/>
<copy file="${basedir}/${liboutputfolder}/${liboutputfile}" todir="${basedir}/dist/lib/">
</copy>
<copy todir="${basedir}/dist/docs/">
<fileset dir="${basedir}/asdoc"/>
</copy>
<zip destfile="sample-as3-sdk.zip" basedir="${basedir}/dist" />
</target>
</project>

View File

@ -29,11 +29,11 @@ package com.wordnik.swagger.common
{
private var _apiUsageCredentials:ApiUserCredentials;
internal var _apiProxyServerUrl:String = "http://apihost.wordnik.com/";
private var _baseUrl: String = "http://beta.wordnik.com/api/";
internal var _apiProxyServerUrl:String = "";
private var _baseUrl: String = "";
internal var _useProxyServer: Boolean = true;
private var _proxyHostName:String = "api.wordnik.com";
private var _apiPath: String = "/v4";
private var _proxyHostName:String = "";
private var _apiPath: String = "";
public var _apiEventNotifier:EventDispatcher;
public var _apiLibraryReferences:LibraryReferences;

View File

@ -14,7 +14,7 @@ internal class ApiUrlHelper {
private static const HTTP_URL_PREFIX:String = "http://";
internal static function appendTokenInfo(restUrl:String, requestHeader: Object, credentials: ApiUserCredentials): String {
//wordnik credentials presence validated on client initialization and not here
//checks for the presence api credentials on client initialization and not repeated here
if(restUrl.indexOf("?") == -1){
restUrl += ( "?" + API_URL_KEY + "=" + credentials.apiToken );
}

View File

@ -1,24 +1,24 @@
package com.wordnik.swagger.common {
/**
* Wordnik Api account credentials. The info is used to authenticate with the Wordnik API and perform
* account-specific user actions
* Api account credentials.
*
*/
public class ApiUserCredentials {
/**
* All requests must be signed with your Wordnik API key
* An apitoken that is passed along with the requests
*/
public var apiToken:String;
/**
* A valid auth_token which is necessary for certain operations - currently, user accounts and list-related CRUD operations
* A valid auth_token which could be necessary for certain operations
*/
public var authToken:String;
/**
* The userId which is required for certain operations - currently, get user lists
* The userId which could be required for certain operations
*/
public var userId:Number;
/**
* The host name for the Wordnik Rest API eg. api.wordnik.com
* The host name for the Rest API eg. api.companyName.com
*/
public var hostName:String;
@ -36,9 +36,9 @@ public class ApiUserCredentials {
/**
* Constructor of ApiUserCredentials
* @param apiToken All requests must be signed with your Wordnik API key
* @param authToken A valid auth_token which is necessary for certain operations - currently, user accounts and list-related CRUD operations
* @param hostName The host name for the Wordnik Rest API eg. api.wordnik.com
* @param apiToken An apitoken that is passed along with the requests
* @param authToken A valid auth_token which could necessary for certain operations
* @param hostName The host name for the Rest API eg. api.companyName.com
* @param userId The userId which is required for certain operations - currently, get user lists
*/
public function ApiUserCredentials(apiToken: String, authToken: String = null, hostName: String = null, userId: Number = -1,

View File

@ -14,15 +14,8 @@ package com.wordnik.swagger.common
protected var _apiEventNotifier:EventDispatcher;
protected var _apiInvoker: ApiInvoker;
protected var apiProxyServerUrl:String = "http://apihost.wordnik.com/";
protected var _baseUrl: String = "http://beta.wordnik.com/api/";
protected var _useProxyServer: Boolean = true;
protected var proxyHostName:String = "api.wordnik.com";
protected static const DELETE_DATA_DUMMY:String = "dummyDataRequiredForDeleteOverride";
protected static const X_HTTP_OVERRIDE_KEY:String = "X-HTTP-Method-Override";
protected static const CONTENT_TYPE_HEADER_KEY:String = "Content-Type";
/**
* Constructor for the api client

View File

@ -5,7 +5,7 @@ import flash.events.Event;
/**
* Event dispatched by the SDK to communicate success events and failure events.
* If a custom dispatcher has been assigned by the consumer on the WordnikClient then the dispatcher dispatches
* If a custom dispatcher has been assigned by the consumer on the generated client then the dispatcher dispatches
* the ApiClientEvent to indicate success or failure of the invocation using the Response
*/
public class ApiClientEvent extends Event{

View File

@ -1,8 +1,8 @@
package com.wordnik.swagger.event {
/**
* Response contains info on the result of a Wordnik API invocation.
* A completion listener will expect this WNResult object as a parameter.
* Response contains info on the result of an API invocation.
* A completion listener will expect this Response object.
*/
public class Response {

View File

@ -1,13 +0,0 @@
package com.wordnik.swagger.model
{
public class DefinitionWrapper
{
/**
*
*
*
*/
[XmlElements(name="definition", type="com.wordnik.swagger.model.Definition")]
public var definition: Array = new Array();
}
}

View File

@ -4,7 +4,14 @@ package $packageName$ {
import $exceptionPackageName$.ApiErrorCodes;
import $exceptionPackageName$.ApiError;
import $modelPackageName$.*;
import com.wordnik.swagger.common.ApiUserCredentials;
import com.wordnik.swagger.event.Response;
import com.wordnik.swagger.common.SwaggerApi;
import mx.rpc.AsyncToken;
import mx.utils.UIDUtil;
import flash.utils.Dictionary;
import flash.events.EventDispatcher;
$imports:{ import |
import $import$;
@ -17,6 +24,9 @@ import $import$;
*/
public class $resource$ extends $extends$ {
$methods:{ method |
public var event_$method.name$: String = "$method.name$";$\r$}$
/**
* Constructor for the $resource$ api client
* @param apiCredentials Wrapper object for tokens and hostName required towards authentication

View File

@ -22,7 +22,6 @@ import com.wordnik.swagger.codegen.config.common.CamelCaseNamingPolicyProvider;
import com.wordnik.swagger.codegen.config.java.JavaDataTypeMappingProvider;
import com.wordnik.swagger.codegen.exception.CodeGenerationException;
import com.wordnik.swagger.codegen.resource.*;
import com.wordnik.swagger.codegen.util.FileUtil;
import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.codehaus.jackson.map.DeserializationConfig;
@ -107,7 +106,7 @@ public class LibraryCodeGenerator {
}
generateModelClasses(resources, aTemplateGroup);
generateModelClassesForInput(resources, aTemplateGroup);
if(languageConfig.isHelperEnumRequired()){
if(languageConfig.isModelEnumRequired()){
generateEnumForAllowedValues(resources, aTemplateGroup);
}
@ -138,9 +137,6 @@ public class LibraryCodeGenerator {
private void generateModelClasses(List<Resource> resources, StringTemplateGroup templateGroup) {
List<String> generatedClassNames = new ArrayList();
//remove old generated files
FileUtil.clearFolder(languageConfig.getModelClassLocation());
for(Resource resource: resources) {
for(Model model : resource.getModels()){
if(!generatedClassNames.contains(model.getName()) && !this.getCodeGenRulesProvider().isModelIgnored(model.getName())){
@ -291,8 +287,8 @@ public class LibraryCodeGenerator {
if(codeGenRulesProvider.isModelIgnored( nameGenerator.applyMethodNamingPolicy( method.getReturnClassName() ))){
continue;
}
if(method.getOutputWrapperModel() != null) {
Model model = method.getOutputWrapperModel();
if(method.getListWrapperModel() != null) {
Model model = method.getListWrapperModel();
method.setReturnClassName(model.getName());
if(model != null){
if(!generatedClasses.contains(model.getName())) {
@ -314,7 +310,7 @@ public class LibraryCodeGenerator {
template.setAttribute("className", model.getGenratedClassName());
template.setAttribute(PACKAGE_NAME, config.getModelPackageName());
File aFile = new File(languageConfig.getModelClassLocation()+model.getGenratedClassName()+languageConfig.getClassFileExtension());
writeFile(aFile, template.toString(), "Output wrapper model class");
writeFile(aFile, template.toString(), "List wrapper model class");
generatedClasses.add(model.getName());
}
}
@ -334,9 +330,6 @@ public class LibraryCodeGenerator {
*/
private void generateAPIClasses(List<Resource> resources, StringTemplateGroup templateGroup) {
//delete previously generated files
FileUtil.clearFolder(languageConfig.getResourceClassLocation());
for(Resource resource : resources) {
try{
List<ResourceMethod> methods = new ArrayList<ResourceMethod>();

View File

@ -54,7 +54,7 @@ public class ResourceMethod {
private Model inputModel;
private Model outputWrapperModel;
private Model listWrapperModel;
public String getTitle() {
return title;
@ -202,11 +202,11 @@ public class ResourceMethod {
return false;
}
public void setOutputWrapperModel(Model outputWrapperModel) {
this.outputWrapperModel = outputWrapperModel;
public void setListWrapperModel(Model listWrapperModel) {
this.listWrapperModel = listWrapperModel;
}
public Model getOutputWrapperModel() {
return outputWrapperModel;
public Model getListWrapperModel() {
return listWrapperModel;
}
}

View File

@ -41,7 +41,7 @@ public class LanguageConfiguration {
private String annotationPackageName;
private boolean isHelperEnumRequired = true;
private boolean isModelEnumRequired = true;
private boolean isOutputWrapperRequired = false;
@ -114,12 +114,12 @@ public class LanguageConfiguration {
this.libraryHome = libraryHome;
}
public void setHelperEnumRequired(boolean helperEnumRequired) {
this.isHelperEnumRequired = helperEnumRequired;
public void setModelEnumRequired(boolean modelEnumRequired) {
this.isModelEnumRequired = modelEnumRequired;
}
public boolean isHelperEnumRequired() {
return isHelperEnumRequired;
public boolean isModelEnumRequired() {
return isModelEnumRequired;
}
public void setOutputWrapperRequired(boolean outputWrapperRequired) {

View File

@ -107,7 +107,7 @@ public interface NamingPolicyProvider {
* @param wrapperItemName
* @return
*/
public String getOutputWrapperName(String wrapperItemName);
public String getListWrapperName(String wrapperItemName);
/**
* Generates a name for an enum for the param or field name.

View File

@ -76,12 +76,15 @@ public class As3LibCodeGen extends LibraryCodeGenerator{
//create ouput directories
FileUtil.createOutputDirectories(as3Configuration.getModelClassLocation(), as3Configuration.getClassFileExtension());
FileUtil.createOutputDirectories(as3Configuration.getResourceClassLocation(), as3Configuration.getClassFileExtension());
//delete previously generated files
FileUtil.clearFolder(as3Configuration.getModelClassLocation());
FileUtil.clearFolder(as3Configuration.getResourceClassLocation());
FileUtil.clearFolder(as3Configuration.getLibraryHome() + "/src/main/as3/com/wordnik/swagger/common");
FileUtil.clearFolder(as3Configuration.getLibraryHome() + "/src/main/as3/com/wordnik/swagger/exception");
FileUtil.clearFolder(as3Configuration.getLibraryHome() + "/src/main/as3/com/wordnik/swagger/event");
FileUtil.copyDirectory(new File(as3Configuration.getStructureLocation()), new File(as3Configuration.getLibraryHome()));
as3Configuration.setHelperEnumRequired(false);
as3Configuration.setModelEnumRequired(false);
as3Configuration.setOutputWrapperRequired(true);
return as3Configuration;
}

View File

@ -151,8 +151,8 @@ public class CamelCaseNamingPolicyProvider implements NamingPolicyProvider {
* @param wrapperItemName
* @return
*/
public String getOutputWrapperName(String wrapperItemName) {
return applyClassNamingPolicy(wrapperItemName) + "Wrapper";
public String getListWrapperName(String wrapperItemName) {
return applyClassNamingPolicy(wrapperItemName) + "List";
}
/**

View File

@ -85,6 +85,8 @@ public class JavaLibCodeGen extends LibraryCodeGenerator {
//create ouput directories
FileUtil.createOutputDirectories(javaConfiguration.getModelClassLocation(), javaConfiguration.getClassFileExtension());
FileUtil.createOutputDirectories(javaConfiguration.getResourceClassLocation(), javaConfiguration.getClassFileExtension());
FileUtil.clearFolder(javaConfiguration.getModelClassLocation());
FileUtil.clearFolder(javaConfiguration.getResourceClassLocation());
FileUtil.clearFolder(javaConfiguration.getLibraryHome() + "/src/main/java/com/wordnik/swagger/runtime");
FileUtil.createOutputDirectories(javaConfiguration.getLibraryHome() + "/src/main/java/com/wordnik/swagger/runtime", "java");
FileUtil.copyDirectory(new File("src/main/java/com/wordnik/swagger/runtime"), new File(javaConfiguration.getLibraryHome()+"/src/main/java/com/wordnik/swagger/runtime"));

View File

@ -309,16 +309,15 @@ public class EndpointOperation {
//if this is a list return type
if(method.getReturnClassName().equals(dataTypeMapper.getListReturnTypeSignature(responseClass))){
String returnValueTypeName = method.getReturnValue();
Model outputWrapperModel = new Model();
outputWrapperModel.setName(nameGenerator.getOutputWrapperName(returnValueTypeName));
Model listWrapperModel = new Model();
listWrapperModel.setName(nameGenerator.getListWrapperName(returnValueTypeName));
List<ModelField> fields = new ArrayList<ModelField>();
ModelField aModelField = new ModelField();
aModelField.setName(nameGenerator.applyMethodNamingPolicy(returnValueTypeName));
aModelField.setParamType(responseClass);
fields.add(aModelField);
outputWrapperModel.setFields(fields);
method.setOutputWrapperModel(outputWrapperModel);
//method.setReturnClassName(outputWrapperModel.getName());
listWrapperModel.setFields(fields);
method.setListWrapperModel(listWrapperModel);
}
//get description string for exception