diff --git a/build.xml b/build.xml
index 39d67768494..b88687f74f1 100644
--- a/build.xml
+++ b/build.xml
@@ -104,7 +104,7 @@
Must specify the parameter for apiConfiguration
- eg. -DapiConfiguration==../api-server-lib/java/config/apiConfiguration.json
+ eg. -DapiConfiguration=../api-server-lib/java/config/apiConfiguration.json
apiConfiguration to be used : ${apiConfiguration}
@@ -120,6 +120,26 @@
+
+
+
+ Must specify the parameter for apiConfiguration
+ eg. -DapiConfiguration=../api-server-lib/as3/config/apiConfiguration.json
+
+
+ apiConfiguration to be used : ${apiConfiguration}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/conf/as3/sample/as3_code_gen_conf.json b/conf/as3/sample/as3_code_gen_conf.json
new file mode 100644
index 00000000000..7d95d614b7c
--- /dev/null
+++ b/conf/as3/sample/as3_code_gen_conf.json
@@ -0,0 +1,30 @@
+{
+ "apiUrl":"http://swagr.api.wordnik.com/v4/",
+
+ "apiKey":"special-key",
+
+ "defaultServiceBaseClass":"SwaggerApi",
+
+ "defaultModelBaseClass":"Object",
+
+ "serviceBaseClasses":{},
+
+ "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"],
+
+ "modelPackageName":"com.wordnik.swagger.model",
+
+ "apiPackageName":"com.wordnik.swagger.api",
+
+ "ignoreMethods":["WordAPI.getWordFrequency","WordAPI.getAudio","WordAPI.getWordStats","WordAPI.getFlickrImages"],
+
+ "ignoreModels":["wordStats","photo","sizes"],
+
+ "outputDirectory":"../api-server-temp/as3ApiSDK/src/main/as3/com/wordnik/swagger/",
+
+ "libraryHome":"../api-server-temp/as3ApiSDK"
+}
\ No newline at end of file
diff --git a/conf/as3/structure/lib/ASAXB-0.1.1.swc b/conf/as3/structure/lib/ASAXB-0.1.1.swc
new file mode 100644
index 00000000000..c9359026784
Binary files /dev/null and b/conf/as3/structure/lib/ASAXB-0.1.1.swc differ
diff --git a/conf/as3/structure/src/main/as3/com/wordnik/swagger/common/ApiInvoker.as b/conf/as3/structure/src/main/as3/com/wordnik/swagger/common/ApiInvoker.as
new file mode 100644
index 00000000000..79c6e68a9c0
--- /dev/null
+++ b/conf/as3/structure/src/main/as3/com/wordnik/swagger/common/ApiInvoker.as
@@ -0,0 +1,223 @@
+package com.wordnik.swagger.common
+{
+ import asaxb.xml.bind.ASAXBContext;
+ import asaxb.xml.bind.Unmarshaller;
+
+ import com.wordnik.swagger.event.ApiClientEvent;
+ import com.wordnik.swagger.event.Response;
+ import com.wordnik.swagger.common.ApiUserCredentials;
+
+ import flash.events.EventDispatcher;
+ import flash.utils.Dictionary;
+ import flash.utils.describeType;
+ import flash.xml.XMLDocument;
+ import flash.xml.XMLNode;
+
+ import mx.messaging.ChannelSet;
+ import mx.messaging.channels.HTTPChannel;
+ import mx.messaging.messages.HTTPRequestMessage;
+ import mx.rpc.AsyncToken;
+ import mx.rpc.events.FaultEvent;
+ import mx.rpc.events.ResultEvent;
+ import mx.rpc.http.HTTPService;
+ import mx.rpc.xml.SimpleXMLEncoder;
+ import mx.utils.ObjectUtil;
+
+
+ public class ApiInvoker extends EventDispatcher
+ {
+
+ private var _apiUsageCredentials:ApiUserCredentials;
+ internal var _apiProxyServerUrl:String = "http://apihost.wordnik.com/";
+ private var _baseUrl: String = "http://beta.wordnik.com/api/";
+ internal var _useProxyServer: Boolean = true;
+ private var _proxyHostName:String = "api.wordnik.com";
+ private var _apiPath: String = "/v4";
+
+ public var _apiEventNotifier:EventDispatcher;
+
+ private static const DELETE_DATA_DUMMY:String = "dummyDataRequiredForDeleteOverride";
+ private static const X_HTTP_OVERRIDE_KEY:String = "X-HTTP-Method-Override";
+ private static const CONTENT_TYPE_HEADER_KEY:String = "Content-Type";
+
+ public function ApiInvoker(apiUsageCredentials: ApiUserCredentials, eventNotifier: EventDispatcher, useProxy: Boolean = true) {
+ _apiUsageCredentials = apiUsageCredentials;
+ _useProxyServer = useProxy;
+ if(_apiUsageCredentials.hostName != null){
+ _proxyHostName = _apiUsageCredentials.hostName;
+ }
+ _apiPath = _apiUsageCredentials.apiPath;
+ _apiProxyServerUrl = _apiUsageCredentials.apiProxyServerUrl;
+ _apiEventNotifier = eventNotifier;
+ }
+
+ public function invokeAPI(authToken: String , resourceURL: String, method: String, queryParams: Dictionary, postObject: Object): AsyncToken {
+ //make the communication
+ if(_useProxyServer) {
+ resourceURL = resourceURL = _apiProxyServerUrl + resourceURL;
+ }
+ else{
+ resourceURL = resourceURL = "http://"+ _proxyHostName + _apiPath + resourceURL;
+ }
+
+ var counter: int = 0;
+ var symbol: String = "&";
+ var paramValue: Object;
+ for (var paramName:String in queryParams) {
+ paramValue = queryParams[paramName];
+ //var key:String = paramName;
+ // do stuff
+ symbol = "&";
+ if(counter == 0){
+ symbol = "?";
+ }
+ resourceURL = resourceURL + symbol + paramName + "=" + paramValue.toString();
+ counter++;
+
+ }
+ //create a httpservice and invoke the rest url waiting for response
+ var requestHeader:Object = new Object();
+ resourceURL = ApiUrlHelper.appendTokenInfo(resourceURL, requestHeader, _apiUsageCredentials);
+ var bodyData:String = marshal( postObject);//restRequest.postData;
+
+ return doRestCall(resourceURL, onApiRequestResult, onApiRequestFault, method, bodyData, requestHeader, "application/xml");
+
+
+ }
+
+ private function doRestCall( url : String, resultFunction : Function, faultFunction : Function = null,
+ restMethod : String = "GET",
+ bodyData : Object = null, headers: Object = null, contentType:String = "application/xml" ) : AsyncToken
+ {
+ var httpService : HTTPService = new HTTPService( );
+
+ if(headers == null){
+ headers = new Object();
+ }
+ httpService.method = restMethod;
+
+ if ( restMethod.toUpperCase() != HTTPRequestMessage.GET_METHOD )
+ {
+ //httpService.method = HTTPRequestMessage.POST_METHOD; - not required as we're using the proxy
+ if( bodyData == null )
+ {
+ bodyData = new Object();
+ }
+
+ if(restMethod == HTTPRequestMessage.DELETE_METHOD){
+ headers[X_HTTP_OVERRIDE_KEY]= HTTPRequestMessage.DELETE_METHOD;
+ bodyData = DELETE_DATA_DUMMY;
+ }
+ else{
+ headers[CONTENT_TYPE_HEADER_KEY]= contentType;
+ }
+ }
+ else
+ {
+ //if the request type is GET and content type is xml then the Flex HTTPService converts it to a POST ... yeah
+ contentType = null;
+ }
+
+ httpService.url = url;
+ httpService.contentType = contentType;
+ httpService.resultFormat = "e4x";
+ httpService.headers = headers;
+ httpService.addEventListener( ResultEvent.RESULT, resultFunction );
+ if( faultFunction != null )
+ {
+ httpService.addEventListener( FaultEvent.FAULT, faultFunction );
+ }
+ if(_useProxyServer){
+ httpService.useProxy = true;
+
+ var channelSet: ChannelSet = new ChannelSet();
+ var httpChannel: HTTPChannel = new HTTPChannel();
+ httpChannel.uri = ApiUrlHelper.getProxyUrl(_proxyHostName);
+ channelSet.addChannel(httpChannel);
+ httpService.channelSet = channelSet;
+ }
+ return httpService.send( bodyData );
+ }
+
+ private function onApiRequestResult(event:ResultEvent):void
+ {
+ var completionListener: Function = event.token.completionListener;
+ var result: Object = event.result;
+ var resultType: Class = event.token.returnType;
+ var resultObject:Object;
+ if(resultType != null) {
+ var context:ASAXBContext = ASAXBContext.newInstance(resultType);
+ var unmarshaller:Unmarshaller = context.createUnmarshaller();
+ var resultXML: XML = new XML(event.result);
+ resultObject = unmarshaller.unmarshal(resultXML);
+
+ }
+ var response : Response = new Response(true, resultObject);
+ response.requestId = event.token.requestId;
+ var successEventType: String = event.token.completionEventType != null ? event.token.completionEventType : ApiClientEvent.SUCCESS_EVENT;
+
+ if (_apiEventNotifier != null) { //dispatch event via assigned dispatcher
+ var successEvent: ApiClientEvent = new ApiClientEvent(successEventType);
+ successEvent.response = response;
+ _apiEventNotifier.dispatchEvent(successEvent);
+ }
+ }
+
+ private function onApiRequestFault(event:FaultEvent):void
+ {
+ var completionListener: Function = event.token.completionListener;
+ if(completionListener != null){
+ completionListener.call( null, new Response( false, null, event.fault.faultString) );
+ }
+
+ var failureEventType: String = event.token.completionEventType != null ? event.token.completionEventType : ApiClientEvent.FAILURE_EVENT;
+
+ if (_apiEventNotifier != null) { //dispatch event via assigned dispatcher
+ var failureEvent: ApiClientEvent = new ApiClientEvent(failureEventType);
+ failureEvent.response = new Response( false, null, event.fault.faultString);
+ _apiEventNotifier.dispatchEvent(failureEvent);
+ }
+ }
+
+
+ public function marshal(source:Object):XML
+ {
+ var writer:XMLWriter=new XMLWriter();
+ var objDescriptor:XML=describeType(source);
+ var property:XML;
+ var propertyType:String;
+ var propertyValue:Object;
+
+ var qualifiedClassName:String=objDescriptor.@name;
+ qualifiedClassName=qualifiedClassName.replace("::",".");
+ writer.xml.setName(qualifiedClassName);
+
+ for each(property in objDescriptor.elements("variable")){
+ propertyValue=source[property.@name];
+ if (propertyValue!=null){
+ if (ObjectUtil.isSimple(propertyValue)){
+ writer.addProperty(property.@name, propertyValue.toString());
+ }
+ else {
+ writer.addProperty(property.@name, marshal(propertyValue).toXMLString());
+ }
+ }
+ }
+ for each(property in objDescriptor.elements("accessor")){
+ if (property.@access=="readonly"){
+ continue;
+ }
+ propertyValue=source[property.@name];
+ if (source[property.@name]!=null){
+ if (ObjectUtil.isSimple(propertyValue)){
+ writer.addProperty(property.@name, propertyValue.toString());
+ }
+ else {
+ writer.addProperty(property.@name, marshal(propertyValue).toXMLString());
+ }
+ }
+ }
+ return writer.xml;
+ }
+ }
+}
\ No newline at end of file
diff --git a/conf/as3/structure/src/main/as3/com/wordnik/swagger/common/ApiUrlHelper.as b/conf/as3/structure/src/main/as3/com/wordnik/swagger/common/ApiUrlHelper.as
new file mode 100644
index 00000000000..844f0deb16d
--- /dev/null
+++ b/conf/as3/structure/src/main/as3/com/wordnik/swagger/common/ApiUrlHelper.as
@@ -0,0 +1,42 @@
+package com.wordnik.swagger.common {
+import com.wordnik.swagger.common.ApiUserCredentials;
+
+/**
+ * @private
+ * Internal class for the Rest client
+ */
+internal class ApiUrlHelper {
+
+ private static const API_URL_KEY:String = "api_key";
+ private static const AUTH_TOKEN_URL_KEY:String = "auth_token";
+
+ private static const HOST_PROXY_PATH:String = "/v4/messagebroker/restproxy";
+ 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
+ if(restUrl.indexOf("?") == -1){
+ restUrl += ( "?" + API_URL_KEY + "=" + credentials.apiToken );
+ }
+ else{
+ restUrl += ( "&" + API_URL_KEY + "=" + credentials.apiToken );
+ }
+ requestHeader.api_key = credentials.apiToken;
+
+ if(credentials.authToken != null && credentials.authToken != ""){
+ restUrl += ( "&" + AUTH_TOKEN_URL_KEY + "=" + credentials.authToken );
+ requestHeader.auth_token = credentials.authToken;
+ }
+
+ return restUrl;
+ }
+
+ internal static function getProxyUrl(hostName: String): String{
+ if (hostName.charAt(hostName.length - 1) == "/") //remove trailing slash
+ {
+ hostName = hostName.substring(0, hostName.length - 1);
+ }
+ return HTTP_URL_PREFIX + hostName + HOST_PROXY_PATH;
+ }
+}
+}
diff --git a/conf/as3/structure/src/main/as3/com/wordnik/swagger/common/ApiUserCredentials.as b/conf/as3/structure/src/main/as3/com/wordnik/swagger/common/ApiUserCredentials.as
new file mode 100644
index 00000000000..412e3c31441
--- /dev/null
+++ b/conf/as3/structure/src/main/as3/com/wordnik/swagger/common/ApiUserCredentials.as
@@ -0,0 +1,55 @@
+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
+ */
+public class ApiUserCredentials {
+ /**
+ * All requests must be signed with your Wordnik API key
+ */
+ public var apiToken:String;
+ /**
+ * A valid auth_token which is necessary for certain operations - currently, user accounts and list-related CRUD operations
+ */
+ public var authToken:String;
+ /**
+ * The userId which is required for certain operations - currently, get user lists
+ */
+ public var userId:Number;
+ /**
+ * The host name for the Wordnik Rest API eg. api.wordnik.com
+ */
+ public var hostName:String;
+
+ /**
+ * The base path to the api resources - used along with the hostname
+ * eg. /v4
+ */
+ public var apiPath: String;
+
+ /**
+ * If a proxy server has been set up for the services specify the URL here. This value is used when the Api is invoked with
+ * the value useProxy as true
+ */
+ public var apiProxyServerUrl: String;
+
+ /**
+ * 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 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,
+ apiPath: String = "", apiProxyServerUrl: String="") {
+ this.hostName = hostName;
+ this.apiToken = apiToken;
+ this.authToken = authToken;
+ this.userId = userId;
+ this.apiPath = apiPath;
+ this.apiProxyServerUrl = apiProxyServerUrl;
+ }
+
+}
+}
\ No newline at end of file
diff --git a/conf/as3/structure/src/main/as3/com/wordnik/swagger/common/SwaggerApi.as b/conf/as3/structure/src/main/as3/com/wordnik/swagger/common/SwaggerApi.as
new file mode 100644
index 00000000000..7c512587d1a
--- /dev/null
+++ b/conf/as3/structure/src/main/as3/com/wordnik/swagger/common/SwaggerApi.as
@@ -0,0 +1,82 @@
+package com.wordnik.swagger.common
+{
+ import com.wordnik.swagger.common.ApiUserCredentials;
+
+ import flash.events.EventDispatcher;
+ import flash.events.IEventDispatcher;
+
+ import mx.utils.UIDUtil;
+
+ public class SwaggerApi extends EventDispatcher
+ {
+
+ protected var _apiUsageCredentials:ApiUserCredentials;
+ 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
+ * @param apiCredentials Wrapper object for tokens and hostName required towards authentication
+ * @param eventDispatcher Optional event dispatcher that when provided is used by the SDK to dispatch any Response
+ */
+ public function SwaggerApi(apiCredentials: ApiUserCredentials, eventDispatcher: EventDispatcher = null) {
+ super();
+ _apiUsageCredentials = apiCredentials;
+ _apiEventNotifier = eventDispatcher;
+ }
+
+ public function useProxyServer(value:Boolean, proxyServerUrl: String = null):void {
+ _useProxyServer = value;
+ }
+
+ protected function getApiInvoker():ApiInvoker {
+ if(_apiInvoker == null){
+ if(_apiEventNotifier == null){
+ _apiEventNotifier = this;
+ }
+ _apiInvoker = new ApiInvoker(_apiUsageCredentials, _apiEventNotifier, _useProxyServer);
+ }
+ return _apiInvoker;
+ }
+
+ protected function getUniqueId():String {
+ return UIDUtil.createUID();
+ }
+
+ /**
+ * Method for returning the path value
+ * For a string value an empty value is returned if the value is null
+ * @param value
+ * @return
+ */
+ protected static function toPathValue(value: Object): String {
+ if(value is Array){
+ return arrayToPathValue(value as Array);
+ }
+ return value == null ? "" : value.toString();
+ }
+
+ /**
+ * Method for returning a path value
+ * For a list of objects a comma separated string is returned
+ * @param objects
+ * @return
+ */
+ protected static function arrayToPathValue(objects: Array): String {
+ var out: String = "";
+
+ return objects.join(",");
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/conf/as3/structure/src/main/as3/com/wordnik/swagger/common/XMLWriter.as b/conf/as3/structure/src/main/as3/com/wordnik/swagger/common/XMLWriter.as
new file mode 100644
index 00000000000..067f49e6301
--- /dev/null
+++ b/conf/as3/structure/src/main/as3/com/wordnik/swagger/common/XMLWriter.as
@@ -0,0 +1,28 @@
+package com.wordnik.swagger.common
+{
+ public class XMLWriter
+ {
+ public var xml:XML;
+
+ public function XMLWriter()
+ {
+ xml=;
+ }
+
+ public function reset():void {
+ xml=new XML();
+ }
+
+ public function addProperty(propertyName:String, propertyValue:String):XML {
+ var xmlProperty:XML=
+ xmlProperty.setName(propertyName);
+ xmlProperty.appendChild(propertyValue);
+ xml.appendChild(xmlProperty);
+ return xmlProperty;
+ }
+
+ public function addAttribute(propertyName:String, attribute:String, attributeValue:String):void {
+ xml.elements(propertyName)[0].@[attribute]=attributeValue;
+ }
+ }
+}
\ No newline at end of file
diff --git a/conf/as3/structure/src/main/as3/com/wordnik/swagger/event/ApiClientEvent.as b/conf/as3/structure/src/main/as3/com/wordnik/swagger/event/ApiClientEvent.as
new file mode 100644
index 00000000000..5484669a3f2
--- /dev/null
+++ b/conf/as3/structure/src/main/as3/com/wordnik/swagger/event/ApiClientEvent.as
@@ -0,0 +1,36 @@
+package com.wordnik.swagger.event {
+import com.wordnik.swagger.event.Response;
+
+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
+ * the ApiClientEvent to indicate success or failure of the invocation using the Response
+ */
+public class ApiClientEvent extends Event{
+
+ /**
+ * Event type to indicate a unsuccessful invocation
+ */
+ public static const FAILURE_EVENT:String = "unsuccesfulInvocation";
+
+ /**
+ * Event type to indicate a successful invocation
+ */
+ public static const SUCCESS_EVENT:String = "successfulInvocation";
+
+ /**
+ * The Response object which contains response info
+ */
+ public var response: Response;
+ /**
+ * Any additional info
+ */
+ public var message:String;
+
+ public function ApiClientEvent(type:String,bubbles:Boolean = false,cancelable:Boolean = false) {
+ super(type, bubbles, cancelable);
+ }
+}
+}
\ No newline at end of file
diff --git a/conf/as3/structure/src/main/as3/com/wordnik/swagger/event/Response.as b/conf/as3/structure/src/main/as3/com/wordnik/swagger/event/Response.as
new file mode 100644
index 00000000000..f09aae7e90a
--- /dev/null
+++ b/conf/as3/structure/src/main/as3/com/wordnik/swagger/event/Response.as
@@ -0,0 +1,52 @@
+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.
+ */
+public class Response {
+
+ /**
+ * Indicates whether the invoked operation failed or succeeded
+ */
+ public var isSuccess:Boolean;
+
+ /**
+ * The payload of the succesful operation eg. a Word in a WordRequest
+ */
+ public var payload:Object;
+
+ /**
+ * Error message in case of failure
+ */
+ public var errorMessage:String;
+
+ /**
+ * A request Id that was passed in by the user as a param when invoking the operation
+ */
+ public var requestId:String;
+ private static const API_ERROR_MSG:String = "Api error response: ";
+
+ public function Response(isSuccessful: Boolean, payload: Object = null, errorMessage: String = null, requestId: String = null) {
+ this.isSuccess = isSuccessful;
+ this.payload = payload;
+ this.errorMessage = getFriendlyMessage(errorMessage);
+ }
+
+ private static function getFriendlyMessage(errorMessage: String): String{
+ var result: String = errorMessage;
+ if(errorMessage == null)
+ return null;
+ var errorCode: String;
+ var errorCodeArray: Array = errorMessage.match(/(?<=HTTP\/1.1 )[0-9][0-9][0-9]/);
+ if(errorCodeArray != null && errorCodeArray.length == 1){
+ errorCode = String(errorCodeArray[0]);
+ }
+ var msgArray: Array = errorMessage.match(/(?<=HTTP\/1.1 [0-9][0-9][0-9] )[^]*/);
+ if(msgArray != null && msgArray.length == 1){
+ result = API_ERROR_MSG + String(msgArray[0]);
+ }
+ return result;
+ }
+}
+}
\ No newline at end of file
diff --git a/conf/as3/structure/src/main/as3/com/wordnik/swagger/exception/ApiError.as b/conf/as3/structure/src/main/as3/com/wordnik/swagger/exception/ApiError.as
new file mode 100644
index 00000000000..13d09415829
--- /dev/null
+++ b/conf/as3/structure/src/main/as3/com/wordnik/swagger/exception/ApiError.as
@@ -0,0 +1,10 @@
+package com.wordnik.swagger.exception
+{
+ public class ApiError extends Error
+ {
+ public function ApiError(id:*=0, message:*="")
+ {
+ super(message,id);
+ }
+ }
+}
\ No newline at end of file
diff --git a/conf/as3/structure/src/main/as3/com/wordnik/swagger/exception/ApiErrorCodes.as b/conf/as3/structure/src/main/as3/com/wordnik/swagger/exception/ApiErrorCodes.as
new file mode 100644
index 00000000000..abe12178361
--- /dev/null
+++ b/conf/as3/structure/src/main/as3/com/wordnik/swagger/exception/ApiErrorCodes.as
@@ -0,0 +1,34 @@
+package com.wordnik.swagger.exception
+{
+ public class ApiErrorCodes
+ {
+ /**
+ * System exception.
+ */
+ public static const SYSTEM_EXCEPTION: Number = 0;
+
+ /**
+ * With Arguments as current key.
+ */
+ public static const API_KEY_NOT_VALID: Number = 1000;
+ /**
+ * With arguments as current token value
+ */
+ public static const AUTH_TOKEN_NOT_VALID: Number = 1001;
+ /**
+ * With arguments as input JSON and output class anme
+ */
+ public static const ERROR_CONVERTING_JSON_TO_JAVA: Number = 1002;
+ /**
+ * With arguments as JAVA class name
+ */
+ public static const ERROR_CONVERTING_JAVA_TO_JSON: Number = 1003;
+
+ public static const ERROR_FROM_WEBSERVICE_CALL: Number = 1004;
+ /**
+ * With arguments as current API server name
+ */
+ public static const API_SERVER_NOT_VALID: Number = 1005;
+
+ }
+}
\ No newline at end of file
diff --git a/conf/as3/structure/src/main/as3/com/wordnik/swagger/model/DefinitionWrapper.as b/conf/as3/structure/src/main/as3/com/wordnik/swagger/model/DefinitionWrapper.as
new file mode 100644
index 00000000000..82e48aa1d64
--- /dev/null
+++ b/conf/as3/structure/src/main/as3/com/wordnik/swagger/model/DefinitionWrapper.as
@@ -0,0 +1,13 @@
+package com.wordnik.swagger.model
+{
+ public class DefinitionWrapper
+ {
+ /**
+ *
+ *
+ *
+ */
+ [XmlElements(name="definition", type="com.wordnik.swagger.model.Definition")]
+ public var definition: Array = new Array();
+ }
+}
\ No newline at end of file
diff --git a/conf/as3/templates/EnumObject.st b/conf/as3/templates/EnumObject.st
new file mode 100644
index 00000000000..9cbc2c661c5
--- /dev/null
+++ b/conf/as3/templates/EnumObject.st
@@ -0,0 +1,30 @@
+package $packageName$;
+
+$imports:{ import |
+import $import$;
+}$
+
+/**
+ * $enum.description$
+ * NOTE: This class is auto generated by the drive code generator program so please do not edit the class manually.
+ * @author deepak
+ *
+ */
+public enum $className$ {
+
+ $values: { value | $value.name$($value.value$)};separator=", "$;
+
+ final $enumValueType$ value;
+
+ $className$($enumValueType$ value) {
+ this.value = value;
+ }
+
+ public $enumValueType$ getValue() {
+ return value;
+ }
+
+ @Override public String toString() {
+ return String.valueOf(this.getValue());
+ }
+};
\ No newline at end of file
diff --git a/conf/as3/templates/ModelObject.st b/conf/as3/templates/ModelObject.st
new file mode 100644
index 00000000000..e8e00f07c22
--- /dev/null
+++ b/conf/as3/templates/ModelObject.st
@@ -0,0 +1,29 @@
+package $packageName$ {
+
+$imports:{ import |
+import $import$;
+}$
+
+ /**
+ * $model.description$
+ * NOTE: This class is auto generated by the drive code generator program so please do not edit the class manually.
+ * @author deepak
+ *
+ */
+ public class $className$ extends $extends$ {
+
+ $fields:{ field |
+
+ /**
+ * $field.description$
+ * $if(field.required)$@Required$endif$
+ * $if(field.allowableValues)$[AllowableValues(value="$field.allowedValuesString$"]$endif$
+ */
+$if(!field.fieldDefinition.collectionItemType)$
+ [XmlElement(name="$field.fieldDefinition.name$")]$endif$
+$if(field.fieldDefinition.collectionItemType)$
+ [XmlElements(name="$field.fieldDefinition.name$", type="$field.fieldDefinition.collectionItemType$")]$endif$
+ public var $field.fieldDefinition.name$: $field.fieldDefinition.returnType$ $field.fieldDefinition.initialization$;$\r$}$
+
+ }
+}
\ No newline at end of file
diff --git a/conf/as3/templates/ResourceObject.st b/conf/as3/templates/ResourceObject.st
new file mode 100644
index 00000000000..20ae8ce82a2
--- /dev/null
+++ b/conf/as3/templates/ResourceObject.st
@@ -0,0 +1,111 @@
+package $packageName$ {
+
+
+import $exceptionPackageName$.ApiErrorCodes;
+import $exceptionPackageName$.ApiError;
+import $modelPackageName$.*;
+
+
+$imports:{ import |
+import $import$;
+}$
+
+ /**
+ * NOTE: This class is auto generated by the drive code generator program so please do not edit the class manually.
+ * @author deepak
+ *
+ */
+ public class $resource$ extends $extends$ {
+
+ /**
+ * Constructor for the $resource$ api client
+ * @param apiCredentials Wrapper object for tokens and hostName required towards authentication
+ * @param eventDispatcher Optional event dispatcher that when provided is used by the SDK to dispatch any Response
+ */
+ public function $resource$(apiCredentials: ApiUserCredentials, eventDispatcher: EventDispatcher = null) {
+ super(apiCredentials, eventDispatcher);
+ }
+
+
+$methods:{ method |
+ /**
+ * $method.description$
+$method.arguments:{ argument |
+ * @param $argument.name$ $argument.description$
+ $if(argument.allowedValues)$
+ * Allowed values are - $argument.allowedValues$
+ $endif$}$
+ *
+$if(!method.responseVoid)$
+ * @return $method.returnValue$ {@link $method.returnClassName$} $endif$
+ */
+$if(method.hasArguments)$
+ [MethodArgumentNames(value="$method.argumentNames; separator=", "$")]$endif$
+ public function $method.name$($method.argumentDefinitions; separator=", "$): String {
+
+$if(method.authToken)$
+ if(authToken == null || authToken.length == 0) {
+ throw new ApiError(ApiErrorCodes.AUTH_TOKEN_NOT_VALID);
+ }$endif$
+ var requestId: String = getUniqueId();
+ //parse inputs
+ var resourcePath: String = "$method.resourcePath$";
+ resourcePath = resourcePath.replace("{format}","xml");
+ var method: String = "$method.methodType$";
+ var queryParams:Dictionary = new Dictionary();
+$if(!method.inputModel)$
+$method.queryParameters:{ argument |
+ if( $argument.name$ != null) {
+ queryParams["$argument.name$"] = toPathValue($argument.name$);
+ }
+}$
+$method.pathParameters:{ argument |
+ if( $argument.name$ != null) {
+ resourcePath = resourcePath.replace("{$argument.name$}", $argument.name$);
+ }
+}$
+$endif$
+$if(method.inputModel)$
+$method.queryParameters:{ argument |
+ if( $argument.inputModelClassArgument$ != null && $argument.methodNameFromModelClass$ != null) {
+ queryParams["$argument.name$"] = $argument.methodNameFromModelClass$;
+ }
+}$
+$method.pathParameters:{ argument |
+ if( $argument.inputModelClassArgument$ != null && $argument.methodNameFromModelClass$ != null) {
+ resourcePath = resourcePath.replace("{$argument.name$}", $argument.methodNameFromModelClass$);
+ }
+}$
+$endif$
+ //make the API Call
+$if(method.postObject)$
+$if(method.authToken)$
+ var token:AsyncToken = getApiInvoker().invokeAPI(authToken, resourcePath, method, queryParams, postData);
+$endif$
+$if(!method.authToken)$
+ var token:AsyncToken = getApiInvoker().invokeAPI(null, resourcePath, method, queryParams, postData);
+$endif$
+$endif$
+
+$if(!method.postObject)$
+$if(method.authToken)$
+ var token:AsyncToken = getApiInvoker().invokeAPI(authToken, resourcePath, method, queryParams, null);
+$endif$
+$if(!method.authToken)$
+ var token:AsyncToken = getApiInvoker().invokeAPI(null, resourcePath, method, queryParams, null);
+$endif$
+$endif$
+
+ token.requestId = requestId;
+ token.completionEventType = "$method.name$";
+
+ //create output objects if the response has more than one object
+$if(!method.responseVoid)$
+ token.returnType = $method.returnClassName$;
+
+$endif$
+ return requestId;
+ }
+}$
+ }
+}
diff --git a/conf/as3/templates/VersionChecker.st b/conf/as3/templates/VersionChecker.st
new file mode 100644
index 00000000000..76fc590418a
--- /dev/null
+++ b/conf/as3/templates/VersionChecker.st
@@ -0,0 +1,20 @@
+package $packageName$ {
+
+/**
+ * Maintains the compatible server version against which the drive is written
+ * @author deepak
+ *
+ */
+ public class VersionChecker {
+
+ private var compatibleVersion: String = "$apiVersion$";
+
+ /**
+ * Gets the version against which the driver code was written
+ */
+ public function getCompatibleVersion(): String {
+ return compatibleVersion;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/wordnik/swagger/codegen/FieldDefinition.java b/src/main/java/com/wordnik/swagger/codegen/FieldDefinition.java
index 615e24fe5cf..c357d0b6feb 100644
--- a/src/main/java/com/wordnik/swagger/codegen/FieldDefinition.java
+++ b/src/main/java/com/wordnik/swagger/codegen/FieldDefinition.java
@@ -28,6 +28,8 @@ public class FieldDefinition {
private String initialization;
private List importDefinitions = new ArrayList();
+
+ private String collectionItemType;
public String getReturnType() {
return returnType;
@@ -61,5 +63,11 @@ public class FieldDefinition {
return name.substring(0,1).toUpperCase() + name.substring(1);
}
+ public void setCollectionItemType(String collectionItemType) {
+ this.collectionItemType = collectionItemType;
+ }
+ public String getCollectionItemType() {
+ return collectionItemType;
+ }
}
diff --git a/src/main/java/com/wordnik/swagger/codegen/LibraryCodeGenerator.java b/src/main/java/com/wordnik/swagger/codegen/LibraryCodeGenerator.java
index 622966190ae..540b081d001 100644
--- a/src/main/java/com/wordnik/swagger/codegen/LibraryCodeGenerator.java
+++ b/src/main/java/com/wordnik/swagger/codegen/LibraryCodeGenerator.java
@@ -106,7 +106,13 @@ public class LibraryCodeGenerator {
}
generateModelClasses(resources, aTemplateGroup);
generateModelClassesForInput(resources, aTemplateGroup);
- generateEnumForAllowedValues(resources, aTemplateGroup);
+ if(languageConfig.isGenerateHelperEnums()){
+ generateEnumForAllowedValues(resources, aTemplateGroup);
+ }
+
+ if(languageConfig.isGenerateOutputWrappers()) {
+ generateOutputWrappers(resources, aTemplateGroup);
+ }
generateAPIClasses(resources, aTemplateGroup);
}
@@ -139,7 +145,7 @@ public class LibraryCodeGenerator {
List imports = new ArrayList();
imports.addAll(this.config.getDefaultModelImports());
for(ModelField param : model.getFields()){
- for(String importDef : param.getFieldDefinition(this.getDataTypeMappingProvider()).getImportDefinitions()){
+ for(String importDef : param.getFieldDefinition(this.getDataTypeMappingProvider(), config, nameGenerator).getImportDefinitions()){
if(!imports.contains(importDef)){
imports.add(importDef);
}
@@ -182,7 +188,7 @@ public class LibraryCodeGenerator {
List imports = new ArrayList();
imports.addAll(this.config.getDefaultModelImports());
for(ModelField param : model.getFields()){
- for(String importDef : param.getFieldDefinition(this.getDataTypeMappingProvider()).getImportDefinitions()){
+ for(String importDef : param.getFieldDefinition(this.getDataTypeMappingProvider(), config, nameGenerator).getImportDefinitions()){
if(!imports.contains(importDef)){
imports.add(importDef);
}
@@ -265,6 +271,57 @@ public class LibraryCodeGenerator {
}
}
+ private void generateOutputWrappers(List resources, StringTemplateGroup templateGroup) {
+ List generatedClasses = new ArrayList();
+ StringTemplate template;
+
+ for(Resource resource: resources) {
+ if(resource.getEndPoints() != null) {
+ for(Endpoint endpoint : resource.getEndPoints()){
+ if(endpoint.getOperations() != null) {
+ for(EndpointOperation operation : endpoint.getOperations()){
+ ResourceMethod method = operation.generateMethod(endpoint, resource, dataTypeMappingProvider, nameGenerator);
+ if(codeGenRulesProvider.isModelIgnored( nameGenerator.applyMethodNamingPolicy( method.getReturnClassName() ))){
+ continue;
+ }
+ if(method.getOutputWrapperModel() != null) {
+ Model model = method.getOutputWrapperModel();
+ method.setReturnClassName(model.getName());
+ if(model != null){
+ if(!generatedClasses.contains(model.getName())) {
+ List imports = new ArrayList();
+ imports.addAll(this.config.getDefaultModelImports());
+ for(ModelField param : model.getFields()){
+ for(String importDef : param.getFieldDefinition(this.getDataTypeMappingProvider(), config, nameGenerator).getImportDefinitions()){
+ if(!imports.contains(importDef)){
+ imports.add(importDef);
+ }
+ }
+ }
+ template = templateGroup.getInstanceOf(MODEL_OBJECT_TEMPLATE);
+
+ template.setAttribute("fields", model.getFields());
+ template.setAttribute("imports", imports);
+ template.setAttribute("extends", config.getDefaultModelBaseClass());
+ template.setAttribute("annotationPackageName", languageConfig.getAnnotationPackageName());
+ 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");
+ generatedClasses.add(model.getName());
+ }
+ }
+ }
+
+ }
+ }
+ }
+ }
+ }
+
+
+ }
+
/**
* Generates one API class for each resource and each end point in the resource is translated as method.
* @param resources
@@ -328,7 +385,7 @@ public class LibraryCodeGenerator {
imports.addAll(this.config.getDefaultModelImports());
imports.addAll(this.getDataTypeMappingProvider().getListIncludes());
for(ModelField param : model.getFields()){
- for(String importDef : param.getFieldDefinition(this.getDataTypeMappingProvider()).getImportDefinitions()){
+ for(String importDef : param.getFieldDefinition(this.getDataTypeMappingProvider(), config, nameGenerator).getImportDefinitions()){
if(!imports.contains(importDef)){
imports.add(importDef);
}
diff --git a/src/main/java/com/wordnik/swagger/codegen/ResourceMethod.java b/src/main/java/com/wordnik/swagger/codegen/ResourceMethod.java
index 151479de00f..f8b551f998f 100644
--- a/src/main/java/com/wordnik/swagger/codegen/ResourceMethod.java
+++ b/src/main/java/com/wordnik/swagger/codegen/ResourceMethod.java
@@ -53,7 +53,8 @@ public class ResourceMethod {
private boolean postObject;
private Model inputModel;
-
+
+ private Model outputWrapperModel;
public String getTitle() {
return title;
@@ -200,4 +201,12 @@ public class ResourceMethod {
}
return false;
}
+
+ public void setOutputWrapperModel(Model outputWrapperModel) {
+ this.outputWrapperModel = outputWrapperModel;
+ }
+
+ public Model getOutputWrapperModel() {
+ return outputWrapperModel;
+ }
}
diff --git a/src/main/java/com/wordnik/swagger/codegen/config/DataTypeMappingProvider.java b/src/main/java/com/wordnik/swagger/codegen/config/DataTypeMappingProvider.java
index 947e5397128..db7ddc3d3f7 100644
--- a/src/main/java/com/wordnik/swagger/codegen/config/DataTypeMappingProvider.java
+++ b/src/main/java/com/wordnik/swagger/codegen/config/DataTypeMappingProvider.java
@@ -187,4 +187,14 @@ public interface DataTypeMappingProvider {
* @return
*/
public String getGenericType(String type);
+
+ /**
+ * Returns the syntax for defintion of an object of type and name
+ *
+ * @param argumentType
+ * @param argumentName
+ * @return
+ */
+ public String getArgumentDefinition(String argumentType, String argumentName);
+
}
diff --git a/src/main/java/com/wordnik/swagger/codegen/config/LanguageConfiguration.java b/src/main/java/com/wordnik/swagger/codegen/config/LanguageConfiguration.java
index 57bdf721088..a70dbbb16d0 100644
--- a/src/main/java/com/wordnik/swagger/codegen/config/LanguageConfiguration.java
+++ b/src/main/java/com/wordnik/swagger/codegen/config/LanguageConfiguration.java
@@ -41,6 +41,10 @@ public class LanguageConfiguration {
private String annotationPackageName;
+ private boolean generateHelperEnums = true;
+
+ private boolean generateOutputWrappers = false;
+
public String getClassFileExtension() {
return classFileExtension;
}
@@ -109,4 +113,20 @@ public class LanguageConfiguration {
public void setLibraryHome(String libraryHome) {
this.libraryHome = libraryHome;
}
+
+ public void setGenerateHelperEnums(boolean generateHelperEnums) {
+ this.generateHelperEnums = generateHelperEnums;
+ }
+
+ public boolean isGenerateHelperEnums() {
+ return generateHelperEnums;
+ }
+
+ public void setGenerateOutputWrappers(boolean generateOutputWrappers) {
+ this.generateOutputWrappers = generateOutputWrappers;
+ }
+
+ public boolean isGenerateOutputWrappers() {
+ return generateOutputWrappers;
+ }
}
diff --git a/src/main/java/com/wordnik/swagger/codegen/config/NamingPolicyProvider.java b/src/main/java/com/wordnik/swagger/codegen/config/NamingPolicyProvider.java
index b85b0042256..185dfac8d1d 100644
--- a/src/main/java/com/wordnik/swagger/codegen/config/NamingPolicyProvider.java
+++ b/src/main/java/com/wordnik/swagger/codegen/config/NamingPolicyProvider.java
@@ -97,6 +97,18 @@ public interface NamingPolicyProvider {
*/
public String getInputObjectName(String serviceName, String resourcePath);
+ /**
+ * Generate the name of the wrapper class used as a wrapper for a list of items returned by a service
+ *
+ * Example: get definitions API returns a list of definition objects as the result. This will be wrapped by an
+ * object. The object's name will be determined by invoking this service.
+ * eg. DefinitionList for a wrapper of 'definition's
+ *
+ * @param wrapperItemName
+ * @return
+ */
+ public String getOutputWrapperName(String wrapperItemName);
+
/**
* Generates a name for an enum for the param or field name.
*
diff --git a/src/main/java/com/wordnik/swagger/codegen/config/as3/As3DataTypeMappingProvider.java b/src/main/java/com/wordnik/swagger/codegen/config/as3/As3DataTypeMappingProvider.java
new file mode 100644
index 00000000000..045749d6833
--- /dev/null
+++ b/src/main/java/com/wordnik/swagger/codegen/config/as3/As3DataTypeMappingProvider.java
@@ -0,0 +1,185 @@
+package com.wordnik.swagger.codegen.config.as3;
+
+import com.wordnik.swagger.codegen.config.DataTypeMappingProvider;
+import com.wordnik.swagger.codegen.config.NamingPolicyProvider;
+import com.wordnik.swagger.codegen.config.common.CamelCaseNamingPolicyProvider;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * User: ramesh
+ * Date: 5/31/11
+ * Time: 7:03 AM
+ */
+public class As3DataTypeMappingProvider implements DataTypeMappingProvider {
+
+ public static Map primitiveValueMap = new HashMap();
+ static{
+ primitiveValueMap.put("string", "String");
+ primitiveValueMap.put("String", "String");
+ primitiveValueMap.put("int", "Number");
+ primitiveValueMap.put("integer", "int");
+ primitiveValueMap.put("Integer", "int");
+ primitiveValueMap.put("boolean", "Boolean");
+ primitiveValueMap.put("Boolean", "Boolean");
+ primitiveValueMap.put("long", "Number");
+ primitiveValueMap.put("Long", "Number");
+ primitiveValueMap.put("double", "Number");
+ primitiveValueMap.put("Double", "Number");
+ primitiveValueMap.put("float", "Number");
+ primitiveValueMap.put("Float", "Number");
+ primitiveValueMap.put("Date", "Date");
+ primitiveValueMap.put("date", "Date");
+ }
+
+ public static Map primitiveObjectMap = new HashMap();
+ static{
+ primitiveObjectMap.put("string", "String");
+ primitiveObjectMap.put("String", "String");
+ primitiveObjectMap.put("int", "int");
+ primitiveObjectMap.put("integer", "int");
+ primitiveObjectMap.put("Integer", "int");
+ primitiveObjectMap.put("boolean", "Boolean");
+ primitiveObjectMap.put("Boolean", "Boolean");
+ primitiveObjectMap.put("long", "Number");
+ primitiveObjectMap.put("Long", "Number");
+ primitiveObjectMap.put("double", "Number");
+ primitiveObjectMap.put("Double", "Number");
+ primitiveObjectMap.put("float", "Number");
+ primitiveObjectMap.put("Float", "Number");
+ primitiveObjectMap.put("Date", "Date");
+ primitiveObjectMap.put("date", "Date");
+ }
+
+ private NamingPolicyProvider nameGenerator = new CamelCaseNamingPolicyProvider();
+
+ public boolean isPrimitiveType(String type) {
+ if(type.equalsIgnoreCase("String") || type.equalsIgnoreCase("int") || type.equalsIgnoreCase("integer") || type.equalsIgnoreCase("double") ||
+ type.equalsIgnoreCase("boolean") || type.equalsIgnoreCase("float")|| type.equalsIgnoreCase("long") || type.equalsIgnoreCase("Number") ){
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * If the data type is primitive and it is expecting object structure then return primitive objects
+ * else return primitive types
+ * @param type
+ * @param primitiveObject -- indicates if the object is primitive or not
+ * @return
+ */
+ public String getObjectType(String type, boolean primitiveObject) {
+ if(isPrimitiveType(type)){
+ if(primitiveObject){
+ return primitiveObjectMap.get(type);
+ }else{
+ return primitiveValueMap.get(type);
+ }
+ }else{
+ return nameGenerator.applyClassNamingPolicy(type);
+ }
+ }
+
+ public String getListReturnTypeSignature(String typeClass) {
+ return "Array";
+ }
+
+ public String getReturnTypeForVoidMethods() {
+ return "void";
+ }
+
+ public String getMapReturnTypeSignature(String typeClass) {
+ return "Object";
+ }
+
+ public String getSetReturnTypeSignature(String typeClass) {
+ return "Array";
+ }
+
+ public String generateListInitialization(String typeClass) {
+ return " new Array()";
+ }
+
+ public String generateMapInitialization(String typeClass) {
+ return " new Object()";
+ }
+
+ public String generateSetInitialization(String typeClass) {
+ return " new Array()";
+ }
+
+ public List getListIncludes() {
+ List imports = new ArrayList();
+ return imports;
+ }
+
+ public List getMapIncludes() {
+ List imports = new ArrayList();
+ imports.add("flash.utils.Dictionary");
+ return imports;
+ }
+
+ public List getSetIncludes() {
+ List imports = new ArrayList();
+ return imports; }
+
+
+ public List getDateIncludes() {
+ List imports = new ArrayList();
+ return imports;
+ }
+
+ /**
+ * Gets the short name of the class the class.
+ * Input can be MAP, LIST or regular string. In case of map or list the class name will be class name
+ * that map or list is returning.
+ * @param type
+ * @return
+ */
+ public String getClassType(String type, boolean primitiveObject) {
+ String classShortName = "";
+ if(type.startsWith("List[")){
+ classShortName = type.substring(5, type.length()-1);
+ classShortName = getObjectType(classShortName, true);
+ }else if (type.startsWith("Map[")) {
+ classShortName = type.substring(4, type.length()-1);
+ classShortName = getObjectType(classShortName, true);
+ }else if (type.startsWith("Set[")) {
+ classShortName = type.substring(4, type.length()-1);
+ classShortName = getObjectType(classShortName, true);
+ }else if (type.equals("ok")) {
+ classShortName = "void";
+ }else{
+ classShortName = getObjectType(type, true);
+ }
+ return classShortName;
+ }
+
+ public String getArgumentDefinition(String argumentType, String argumentName) {
+ return argumentName + ": " + argumentType;
+ }
+
+ /**
+ * Gets the class of the expected return value for a type string. Examples of type Strings are int, User, List[User]
+ * If the type string is a collection type like a map or list the string value returned would be the class
+ * that map or list is returning.
+ *
+ * @param type
+ * @return
+ */
+ public String getGenericType(String type) {
+ if(type.equalsIgnoreCase("void")|| type.equalsIgnoreCase("ok")){
+ return "void";
+ }
+ String classShortName = "";
+ if(type.startsWith("List[") || type.startsWith("Map[") || type.startsWith("Set[")){
+ classShortName = "Array";
+ }else{
+ classShortName = getObjectType(type, true);
+ }
+ return classShortName;
+ }
+}
diff --git a/src/main/java/com/wordnik/swagger/codegen/config/as3/As3LibCodeGen.java b/src/main/java/com/wordnik/swagger/codegen/config/as3/As3LibCodeGen.java
new file mode 100644
index 00000000000..473bb03ff21
--- /dev/null
+++ b/src/main/java/com/wordnik/swagger/codegen/config/as3/As3LibCodeGen.java
@@ -0,0 +1,85 @@
+package com.wordnik.swagger.codegen.config.as3;
+
+import com.wordnik.swagger.codegen.LibraryCodeGenerator;
+import com.wordnik.swagger.codegen.config.LanguageConfiguration;
+import com.wordnik.swagger.codegen.config.common.CamelCaseNamingPolicyProvider;
+import com.wordnik.swagger.codegen.exception.CodeGenerationException;
+import com.wordnik.swagger.codegen.util.FileUtil;
+
+import java.io.File;
+
+/**
+ * User: deepakmichael
+ * Date: 17/08/11
+ * Time: 5:02 PM
+ */
+public class As3LibCodeGen extends LibraryCodeGenerator{
+ public static void main(String[] args) {
+ if(args.length < 1){
+ throw new CodeGenerationException("Invalid number of arguments passed: No command line argument was passed to the program for config json");
+ }
+ if(args.length == 1) {
+ String configPath = args[0];
+ As3LibCodeGen codeGenerator = new As3LibCodeGen(configPath);
+ codeGenerator.generateCode();
+ }
+ if(args.length == 4) {
+ String apiServerURL = args[0];
+ if(!apiServerURL.endsWith("/")){
+ apiServerURL = apiServerURL + "/";
+ }
+ String apiKey = args[1];
+ String packageName = args[2];
+ String libraryHome = args[3];
+ if(libraryHome.endsWith("/")){
+ libraryHome = libraryHome.substring(0, libraryHome.length()-1);
+ }
+ String modelPackageName = packageName+".model";
+ String apiPackageName = packageName+".api";
+ String classOutputDir = libraryHome + "/src/main/as3/" + packageName.replace(".","/");
+ As3LibCodeGen codeGenerator = new As3LibCodeGen(apiServerURL, apiKey, modelPackageName,
+ apiPackageName, classOutputDir, libraryHome);
+ codeGenerator.generateCode();
+ }
+
+ }
+
+ public As3LibCodeGen(String apiServerURL, String apiKey, String modelPackageName, String apiPackageName,
+ String classOutputDir, String libraryHome){
+ super(apiServerURL, apiKey, modelPackageName, apiPackageName, classOutputDir, libraryHome);
+ this.setDataTypeMappingProvider(new As3DataTypeMappingProvider());
+ this.setNameGenerator(new As3NamingPolicyProvider());
+ }
+
+ public As3LibCodeGen(String configPath){
+ super(configPath);
+ this.setDataTypeMappingProvider(new As3DataTypeMappingProvider());
+ this.setNameGenerator(new As3NamingPolicyProvider());
+ }
+
+ @Override
+ protected LanguageConfiguration initializeLangConfig(LanguageConfiguration as3Configuration) {
+ as3Configuration.setClassFileExtension(".as");
+ as3Configuration.setTemplateLocation("conf/as3/templates");
+ as3Configuration.setStructureLocation("conf/as3/structure");
+ as3Configuration.setExceptionPackageName("com.wordnik.swagger.exception");
+ as3Configuration.setAnnotationPackageName("com.wordnik.swagger.annotations");
+
+ //create ouput directories
+ FileUtil.createOutputDirectories(as3Configuration.getModelClassLocation(), as3Configuration.getClassFileExtension());
+ FileUtil.createOutputDirectories(as3Configuration.getResourceClassLocation(), as3Configuration.getClassFileExtension());
+/*
+ FileUtil.clearFolder(as3Configuration.getLibraryHome() + "/src/main/java/com/wordnik/swagger/runtime");
+ FileUtil.createOutputDirectories(as3Configuration.getLibraryHome() + "/src/main/java/com/wordnik/swagger/runtime", "as");
+*/
+ 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.setGenerateHelperEnums(false);
+ as3Configuration.setGenerateOutputWrappers(true);
+ return as3Configuration;
+ }
+
+}
diff --git a/src/main/java/com/wordnik/swagger/codegen/config/as3/As3NamingPolicyProvider.java b/src/main/java/com/wordnik/swagger/codegen/config/as3/As3NamingPolicyProvider.java
new file mode 100644
index 00000000000..165940e7867
--- /dev/null
+++ b/src/main/java/com/wordnik/swagger/codegen/config/as3/As3NamingPolicyProvider.java
@@ -0,0 +1,25 @@
+package com.wordnik.swagger.codegen.config.as3;
+
+import com.wordnik.swagger.codegen.config.common.CamelCaseNamingPolicyProvider;
+
+/**
+ * User: deepakmichael
+ * Date: 16/08/11
+ * Time: 11:01 AM
+ */
+public class As3NamingPolicyProvider extends CamelCaseNamingPolicyProvider {
+
+ /**
+ * Gets the signature of the method that gets value for give attribute name.
+ *
+ * Example: If class name is user and attibute name is email the out in java language will be
+ * user.getEmail()
+ *
+ * @param className
+ * @param attributeName
+ * @return
+ */
+ public String createGetterMethodName(String className, String attributeName) {
+ return className+"."+ attributeName;
+ }
+}
diff --git a/src/main/java/com/wordnik/swagger/codegen/config/common/CamelCaseNamingPolicyProvider.java b/src/main/java/com/wordnik/swagger/codegen/config/common/CamelCaseNamingPolicyProvider.java
index 42204c545a3..a4663f412c6 100644
--- a/src/main/java/com/wordnik/swagger/codegen/config/common/CamelCaseNamingPolicyProvider.java
+++ b/src/main/java/com/wordnik/swagger/codegen/config/common/CamelCaseNamingPolicyProvider.java
@@ -141,6 +141,20 @@ public class CamelCaseNamingPolicyProvider implements NamingPolicyProvider {
return inputobjectName;
}
+ /**
+ * Generate the name of the wrapper class used as a wrapper for a list of items returned by a service
+ *
+ * Example: get definitions API returns a list of definition objects as the result. This will be wrapped by an
+ * object. The object's name will be determined by invoking this service.
+ * eg. DefinitionList for a wrapper of 'definition's
+ *
+ * @param wrapperItemName
+ * @return
+ */
+ public String getOutputWrapperName(String wrapperItemName) {
+ return applyClassNamingPolicy(wrapperItemName) + "Wrapper";
+ }
+
/**
* Generates a name for an enum for the param or field name.
*
diff --git a/src/main/java/com/wordnik/swagger/codegen/config/java/JavaDataTypeMappingProvider.java b/src/main/java/com/wordnik/swagger/codegen/config/java/JavaDataTypeMappingProvider.java
index f34ae08d5d0..bd0eafd351e 100644
--- a/src/main/java/com/wordnik/swagger/codegen/config/java/JavaDataTypeMappingProvider.java
+++ b/src/main/java/com/wordnik/swagger/codegen/config/java/JavaDataTypeMappingProvider.java
@@ -158,7 +158,18 @@ public class JavaDataTypeMappingProvider implements DataTypeMappingProvider {
return classShortName;
}
- /**
+ /**
+ * Returns the syntax for defintion of an object of type and name
+ *
+ * @param argumentType
+ * @param argumentName
+ * @return
+ */
+ public String getArgumentDefinition(String argumentType, String argumentName) {
+ return argumentType + " " + argumentName;
+ }
+
+ /**
* Gets the class of the expected return value for a type string. Examples of type Strings are int, User, List[User]
* If the type string is a collection type like a map or list the string value returned would be the class
* that map or list is returning.
diff --git a/src/main/java/com/wordnik/swagger/codegen/resource/EndpointOperation.java b/src/main/java/com/wordnik/swagger/codegen/resource/EndpointOperation.java
index 761fd112faa..a83fb3ae8e2 100644
--- a/src/main/java/com/wordnik/swagger/codegen/resource/EndpointOperation.java
+++ b/src/main/java/com/wordnik/swagger/codegen/resource/EndpointOperation.java
@@ -291,7 +291,7 @@ public class EndpointOperation {
if (method.getArguments() != null && method.getArguments().size() > 0) {
for(MethodArgument arg: method.getArguments()) {
if(!arg.getName().equalsIgnoreCase(FORMAT_PARAM_NAME)){
- argumentDefinitions.add(arg.getDataType() + " " + arg.getName());
+ argumentDefinitions.add( dataTypeMapper.getArgumentDefinition(arg.getDataType(), arg.getName()) );
argumentNames.add(arg.getName());
}
}
@@ -306,7 +306,21 @@ public class EndpointOperation {
method.setReturnValue(dataTypeMapper.getClassType(responseClass, false));
method.setReturnClassName(dataTypeMapper.getGenericType(responseClass));
-
+ //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));
+ List fields = new ArrayList();
+ 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());
+ }
+
//get description string for exception
method.setExceptionDescription(calculateExceptionMessage());
}
diff --git a/src/main/java/com/wordnik/swagger/codegen/resource/ModelField.java b/src/main/java/com/wordnik/swagger/codegen/resource/ModelField.java
index a23d1ef29aa..3b9107eb5b7 100644
--- a/src/main/java/com/wordnik/swagger/codegen/resource/ModelField.java
+++ b/src/main/java/com/wordnik/swagger/codegen/resource/ModelField.java
@@ -17,7 +17,9 @@
package com.wordnik.swagger.codegen.resource;
import com.wordnik.swagger.codegen.FieldDefinition;
+import com.wordnik.swagger.codegen.config.ApiConfiguration;
import com.wordnik.swagger.codegen.config.DataTypeMappingProvider;
+import com.wordnik.swagger.codegen.config.NamingPolicyProvider;
import java.util.ArrayList;
import java.util.List;
@@ -170,7 +172,7 @@ public class ModelField {
return fieldDefinition;
}
- public FieldDefinition getFieldDefinition(DataTypeMappingProvider dataTypeMapper) {
+ public FieldDefinition getFieldDefinition(DataTypeMappingProvider dataTypeMapper, ApiConfiguration config, NamingPolicyProvider nameGenerator) {
if(fieldDefinition == null) {
fieldDefinition = new FieldDefinition();
String type = paramType.trim();
@@ -180,6 +182,11 @@ public class ModelField {
if(type.startsWith("List[")){
fieldDefinition.getImportDefinitions().addAll(dataTypeMapper.getListIncludes());
String entryType = type.substring(5, type.length()-1);
+ if (dataTypeMapper.isPrimitiveType(entryType)) {
+ fieldDefinition.setCollectionItemType(entryType);
+ } else {
+ fieldDefinition.setCollectionItemType(config.getModelPackageName() + "." + nameGenerator.applyClassNamingPolicy(entryType));
+ }
entryType = dataTypeMapper.getClassType(entryType, true);
String returnType = dataTypeMapper.getListReturnTypeSignature(entryType);
fieldDefinition.setReturnType(returnType);