diff --git a/bin/flash-petstore.sh b/bin/flash-petstore.sh new file mode 100755 index 00000000000..c85f6eedbd7 --- /dev/null +++ b/bin/flash-petstore.sh @@ -0,0 +1,6 @@ +#!/bin/bash +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +export CLASSPATH="$DIR/../target/lib/*:$DIR/../target/*" +export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties" +scala $WORDNIK_OPTS $JAVA_CONFIG_OPTIONS -cp $CLASSPATH "$@" FlashPetstoreCodegen http://petstore.swagger.wordnik.com/api/resources.json special-key diff --git a/bin/php-petstore.sh b/bin/php-petstore.sh new file mode 100755 index 00000000000..e6a1190bb18 --- /dev/null +++ b/bin/php-petstore.sh @@ -0,0 +1,6 @@ +#!/bin/bash +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +export CLASSPATH="$DIR/../target/lib/*:$DIR/../target/*" +export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties" +scala $WORDNIK_OPTS $JAVA_CONFIG_OPTIONS -cp $CLASSPATH "$@" PHPPetstoreCodegen http://petstore.swagger.wordnik.com/api/resources.json special-key diff --git a/samples/petstore/flash/bin/AirExecutorApp-app.xml b/samples/petstore/flash/bin/AirExecutorApp-app.xml new file mode 100644 index 00000000000..1dbaf98e644 --- /dev/null +++ b/samples/petstore/flash/bin/AirExecutorApp-app.xml @@ -0,0 +1,146 @@ + + + + + + + AirExecutorApp + + + AirExecutorApp + + + AirExecutorApp + + + v1 + + + + + + + + + + + + + + + AirExecutorApp.swf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/petstore/flash/build.properties b/samples/petstore/flash/build.properties new file mode 100644 index 00000000000..8e77d88c961 --- /dev/null +++ b/samples/petstore/flash/build.properties @@ -0,0 +1,29 @@ +# 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/flex + +# 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/flex + +# 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 + +# The location of the test sources +testsourcepath = ./src/test/flex + +# Home directory for flex sdk, change this to build for Mac or PC using # as comment +FLEX4_SDK_HOME = /usr/local/flex_sdk_4.1.0/ +#FLEX4_SDK_HOME = /Applications/Adobe Flash Builder 4/sdks/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 + diff --git a/samples/petstore/flash/build.xml b/samples/petstore/flash/build.xml new file mode 100644 index 00000000000..58c487d2364 --- /dev/null +++ b/samples/petstore/flash/build.xml @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + docs created + + + + + + + + + + + + + + + + + + + + + + + + SWC created + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/petstore/flash/lib/ASAXB-0.1.1.swc b/samples/petstore/flash/lib/ASAXB-0.1.1.swc new file mode 100644 index 00000000000..c9359026784 Binary files /dev/null and b/samples/petstore/flash/lib/ASAXB-0.1.1.swc differ diff --git a/samples/petstore/flash/lib/ext/as3corelib.swc b/samples/petstore/flash/lib/ext/as3corelib.swc new file mode 100644 index 00000000000..12dd6b3b0a6 Binary files /dev/null and b/samples/petstore/flash/lib/ext/as3corelib.swc differ diff --git a/samples/petstore/flash/lib/ext/flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc b/samples/petstore/flash/lib/ext/flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc new file mode 100644 index 00000000000..e41bc68abd9 Binary files /dev/null and b/samples/petstore/flash/lib/ext/flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc differ diff --git a/samples/petstore/flash/lib/ext/flexunit-aircilistener-4.1.0_RC2-28-3.5.0.12683.swc b/samples/petstore/flash/lib/ext/flexunit-aircilistener-4.1.0_RC2-28-3.5.0.12683.swc new file mode 100644 index 00000000000..8bbdf8b86a0 Binary files /dev/null and b/samples/petstore/flash/lib/ext/flexunit-aircilistener-4.1.0_RC2-28-3.5.0.12683.swc differ diff --git a/samples/petstore/flash/lib/ext/flexunit-cilistener-4.1.0_RC2-28-3.5.0.12683.swc b/samples/petstore/flash/lib/ext/flexunit-cilistener-4.1.0_RC2-28-3.5.0.12683.swc new file mode 100644 index 00000000000..b69064ac765 Binary files /dev/null and b/samples/petstore/flash/lib/ext/flexunit-cilistener-4.1.0_RC2-28-3.5.0.12683.swc differ diff --git a/samples/petstore/flash/lib/ext/flexunit-core-flex-4.0.0.2-sdk3.5.0.12683.swc b/samples/petstore/flash/lib/ext/flexunit-core-flex-4.0.0.2-sdk3.5.0.12683.swc new file mode 100644 index 00000000000..a90af750bb5 Binary files /dev/null and b/samples/petstore/flash/lib/ext/flexunit-core-flex-4.0.0.2-sdk3.5.0.12683.swc differ diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/client/api/PetApi.as b/samples/petstore/flash/src/main/flex/com/wordnik/client/api/PetApi.as new file mode 100644 index 00000000000..cc320ab96ff --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/client/api/PetApi.as @@ -0,0 +1,160 @@ +package com.wordnik.client.api { + +import com.wordnik.swagger.common.ApiInvoker; +import com.wordnik.swagger.exception.ApiErrorCodes; +import com.wordnik.swagger.exception.ApiError; +import com.wordnik.swagger.common.ApiUserCredentials; +import com.wordnik.swagger.event.Response; +import com.wordnik.swagger.common.SwaggerApi; +import com.wordnik.client.model.Pet; +import mx.rpc.AsyncToken; +import mx.utils.UIDUtil; +import flash.utils.Dictionary; +import flash.events.EventDispatcher; + +public class PetApi extends SwaggerApi { + /** + * Constructor for the PetApi 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 PetApi(apiCredentials: ApiUserCredentials, eventDispatcher: EventDispatcher = null) { + super(apiCredentials, eventDispatcher); + } + +public static const event_getPetById: String = "getPetById"; +public static const event_addPet: String = "addPet"; +public static const event_updatePet: String = "updatePet"; +public static const event_findPetsByStatus: String = "findPetsByStatus"; +public static const event_findPetsByTags: String = "findPetsByTags"; +/* + * Returns Pet */ + public function getPetById (petId: String): String { + // create path and map variables + var path: String = "/pet.{format}/{petId}".replace(/{format}/g,"xml").replace("{" + "petId" + "}", getApiInvoker().escapeString(petId)); + + // query params + var queryParams: Dictionary = new Dictionary(); + var headerParams: Dictionary = new Dictionary(); + + // verify required params are set + if(petId == null ) { + throw new ApiError(400, "missing required params"); + } + var token:AsyncToken = getApiInvoker().invokeAPI(path, "GET", queryParams, null, headerParams); + + var requestId: String = getUniqueId(); + + token.requestId = requestId; + token.completionEventType = "getPetById"; + + token.returnType = Pet; + return requestId; + + } + /* + * Returns void */ + public function addPet (body: Pet): String { + // create path and map variables + var path: String = "/pet.{format}".replace(/{format}/g,"xml"); + + // query params + var queryParams: Dictionary = new Dictionary(); + var headerParams: Dictionary = new Dictionary(); + + // verify required params are set + if(body == null ) { + throw new ApiError(400, "missing required params"); + } + var token:AsyncToken = getApiInvoker().invokeAPI(path, "POST", queryParams, body, headerParams); + + var requestId: String = getUniqueId(); + + token.requestId = requestId; + token.completionEventType = "addPet"; + + token.returnType = null ; + return requestId; + + } + /* + * Returns void */ + public function updatePet (body: Pet): String { + // create path and map variables + var path: String = "/pet.{format}".replace(/{format}/g,"xml"); + + // query params + var queryParams: Dictionary = new Dictionary(); + var headerParams: Dictionary = new Dictionary(); + + // verify required params are set + if(body == null ) { + throw new ApiError(400, "missing required params"); + } + var token:AsyncToken = getApiInvoker().invokeAPI(path, "PUT", queryParams, body, headerParams); + + var requestId: String = getUniqueId(); + + token.requestId = requestId; + token.completionEventType = "updatePet"; + + token.returnType = null ; + return requestId; + + } + /* + * Returns com.wordnik.client.model.PetList */ + public function findPetsByStatus (status: String= "available"): String { + // create path and map variables + var path: String = "/pet.{format}/findByStatus".replace(/{format}/g,"xml"); + + // query params + var queryParams: Dictionary = new Dictionary(); + var headerParams: Dictionary = new Dictionary(); + + // verify required params are set + if(status == null ) { + throw new ApiError(400, "missing required params"); + } + if("null" != String(status)) + queryParams["status"] = toPathValue(status); + var token:AsyncToken = getApiInvoker().invokeAPI(path, "GET", queryParams, null, headerParams); + + var requestId: String = getUniqueId(); + + token.requestId = requestId; + token.completionEventType = "findPetsByStatus"; + + token.returnType = com.wordnik.client.model.PetList; + return requestId; + + } + /* + * Returns com.wordnik.client.model.PetList */ + public function findPetsByTags (tags: String): String { + // create path and map variables + var path: String = "/pet.{format}/findByTags".replace(/{format}/g,"xml"); + + // query params + var queryParams: Dictionary = new Dictionary(); + var headerParams: Dictionary = new Dictionary(); + + // verify required params are set + if(tags == null ) { + throw new ApiError(400, "missing required params"); + } + if("null" != String(tags)) + queryParams["tags"] = toPathValue(tags); + var token:AsyncToken = getApiInvoker().invokeAPI(path, "GET", queryParams, null, headerParams); + + var requestId: String = getUniqueId(); + + token.requestId = requestId; + token.completionEventType = "findPetsByTags"; + + token.returnType = com.wordnik.client.model.PetList; + return requestId; + + } + } + } diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/client/api/StoreApi.as b/samples/petstore/flash/src/main/flex/com/wordnik/client/api/StoreApi.as new file mode 100644 index 00000000000..4ce2a47f0cc --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/client/api/StoreApi.as @@ -0,0 +1,104 @@ +package com.wordnik.client.api { + +import com.wordnik.swagger.common.ApiInvoker; +import com.wordnik.swagger.exception.ApiErrorCodes; +import com.wordnik.swagger.exception.ApiError; +import com.wordnik.swagger.common.ApiUserCredentials; +import com.wordnik.swagger.event.Response; +import com.wordnik.swagger.common.SwaggerApi; +import com.wordnik.client.model.Order; +import mx.rpc.AsyncToken; +import mx.utils.UIDUtil; +import flash.utils.Dictionary; +import flash.events.EventDispatcher; + +public class StoreApi extends SwaggerApi { + /** + * Constructor for the StoreApi 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 StoreApi(apiCredentials: ApiUserCredentials, eventDispatcher: EventDispatcher = null) { + super(apiCredentials, eventDispatcher); + } + +public static const event_getOrderById: String = "getOrderById"; +public static const event_deleteOrder: String = "deleteOrder"; +public static const event_placeOrder: String = "placeOrder"; +/* + * Returns Order */ + public function getOrderById (orderId: String): String { + // create path and map variables + var path: String = "/store.{format}/order/{orderId}".replace(/{format}/g,"xml").replace("{" + "orderId" + "}", getApiInvoker().escapeString(orderId)); + + // query params + var queryParams: Dictionary = new Dictionary(); + var headerParams: Dictionary = new Dictionary(); + + // verify required params are set + if(orderId == null ) { + throw new ApiError(400, "missing required params"); + } + var token:AsyncToken = getApiInvoker().invokeAPI(path, "GET", queryParams, null, headerParams); + + var requestId: String = getUniqueId(); + + token.requestId = requestId; + token.completionEventType = "getOrderById"; + + token.returnType = Order; + return requestId; + + } + /* + * Returns void */ + public function deleteOrder (orderId: String): String { + // create path and map variables + var path: String = "/store.{format}/order/{orderId}".replace(/{format}/g,"xml").replace("{" + "orderId" + "}", getApiInvoker().escapeString(orderId)); + + // query params + var queryParams: Dictionary = new Dictionary(); + var headerParams: Dictionary = new Dictionary(); + + // verify required params are set + if(orderId == null ) { + throw new ApiError(400, "missing required params"); + } + var token:AsyncToken = getApiInvoker().invokeAPI(path, "DELETE", queryParams, null, headerParams); + + var requestId: String = getUniqueId(); + + token.requestId = requestId; + token.completionEventType = "deleteOrder"; + + token.returnType = null ; + return requestId; + + } + /* + * Returns void */ + public function placeOrder (body: Order): String { + // create path and map variables + var path: String = "/store.{format}/order".replace(/{format}/g,"xml"); + + // query params + var queryParams: Dictionary = new Dictionary(); + var headerParams: Dictionary = new Dictionary(); + + // verify required params are set + if(body == null ) { + throw new ApiError(400, "missing required params"); + } + var token:AsyncToken = getApiInvoker().invokeAPI(path, "POST", queryParams, body, headerParams); + + var requestId: String = getUniqueId(); + + token.requestId = requestId; + token.completionEventType = "placeOrder"; + + token.returnType = null ; + return requestId; + + } + } + } diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/client/api/UserApi.as b/samples/petstore/flash/src/main/flex/com/wordnik/client/api/UserApi.as new file mode 100644 index 00000000000..1464eca03c8 --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/client/api/UserApi.as @@ -0,0 +1,234 @@ +package com.wordnik.client.api { + +import com.wordnik.swagger.common.ApiInvoker; +import com.wordnik.swagger.exception.ApiErrorCodes; +import com.wordnik.swagger.exception.ApiError; +import com.wordnik.swagger.common.ApiUserCredentials; +import com.wordnik.swagger.event.Response; +import com.wordnik.swagger.common.SwaggerApi; +import com.wordnik.client.model.User; +import mx.rpc.AsyncToken; +import mx.utils.UIDUtil; +import flash.utils.Dictionary; +import flash.events.EventDispatcher; + +public class UserApi extends SwaggerApi { + /** + * Constructor for the UserApi 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 UserApi(apiCredentials: ApiUserCredentials, eventDispatcher: EventDispatcher = null) { + super(apiCredentials, eventDispatcher); + } + +public static const event_createUsersWithArrayInput: String = "createUsersWithArrayInput"; +public static const event_createUser: String = "createUser"; +public static const event_createUsersWithListInput: String = "createUsersWithListInput"; +public static const event_updateUser: String = "updateUser"; +public static const event_deleteUser: String = "deleteUser"; +public static const event_getUserByName: String = "getUserByName"; +public static const event_loginUser: String = "loginUser"; +public static const event_logoutUser: String = "logoutUser"; +/* + * Returns void */ + public function createUsersWithArrayInput (body: Array): String { + // create path and map variables + var path: String = "/user.{format}/createWithArray".replace(/{format}/g,"xml"); + + // query params + var queryParams: Dictionary = new Dictionary(); + var headerParams: Dictionary = new Dictionary(); + + // verify required params are set + if(body == null ) { + throw new ApiError(400, "missing required params"); + } + var token:AsyncToken = getApiInvoker().invokeAPI(path, "POST", queryParams, body, headerParams); + + var requestId: String = getUniqueId(); + + token.requestId = requestId; + token.completionEventType = "createUsersWithArrayInput"; + + token.returnType = null ; + return requestId; + + } + /* + * Returns void */ + public function createUser (body: User): String { + // create path and map variables + var path: String = "/user.{format}".replace(/{format}/g,"xml"); + + // query params + var queryParams: Dictionary = new Dictionary(); + var headerParams: Dictionary = new Dictionary(); + + // verify required params are set + if(body == null ) { + throw new ApiError(400, "missing required params"); + } + var token:AsyncToken = getApiInvoker().invokeAPI(path, "POST", queryParams, body, headerParams); + + var requestId: String = getUniqueId(); + + token.requestId = requestId; + token.completionEventType = "createUser"; + + token.returnType = null ; + return requestId; + + } + /* + * Returns void */ + public function createUsersWithListInput (body: Array): String { + // create path and map variables + var path: String = "/user.{format}/createWithList".replace(/{format}/g,"xml"); + + // query params + var queryParams: Dictionary = new Dictionary(); + var headerParams: Dictionary = new Dictionary(); + + // verify required params are set + if(body == null ) { + throw new ApiError(400, "missing required params"); + } + var token:AsyncToken = getApiInvoker().invokeAPI(path, "POST", queryParams, body, headerParams); + + var requestId: String = getUniqueId(); + + token.requestId = requestId; + token.completionEventType = "createUsersWithListInput"; + + token.returnType = null ; + return requestId; + + } + /* + * Returns void */ + public function updateUser (username: String, body: User): String { + // create path and map variables + var path: String = "/user.{format}/{username}".replace(/{format}/g,"xml").replace("{" + "username" + "}", getApiInvoker().escapeString(username)); + + // query params + var queryParams: Dictionary = new Dictionary(); + var headerParams: Dictionary = new Dictionary(); + + // verify required params are set + if(username == null || body == null ) { + throw new ApiError(400, "missing required params"); + } + var token:AsyncToken = getApiInvoker().invokeAPI(path, "PUT", queryParams, body, headerParams); + + var requestId: String = getUniqueId(); + + token.requestId = requestId; + token.completionEventType = "updateUser"; + + token.returnType = null ; + return requestId; + + } + /* + * Returns void */ + public function deleteUser (username: String): String { + // create path and map variables + var path: String = "/user.{format}/{username}".replace(/{format}/g,"xml").replace("{" + "username" + "}", getApiInvoker().escapeString(username)); + + // query params + var queryParams: Dictionary = new Dictionary(); + var headerParams: Dictionary = new Dictionary(); + + // verify required params are set + if(username == null ) { + throw new ApiError(400, "missing required params"); + } + var token:AsyncToken = getApiInvoker().invokeAPI(path, "DELETE", queryParams, null, headerParams); + + var requestId: String = getUniqueId(); + + token.requestId = requestId; + token.completionEventType = "deleteUser"; + + token.returnType = null ; + return requestId; + + } + /* + * Returns User */ + public function getUserByName (username: String): String { + // create path and map variables + var path: String = "/user.{format}/{username}".replace(/{format}/g,"xml").replace("{" + "username" + "}", getApiInvoker().escapeString(username)); + + // query params + var queryParams: Dictionary = new Dictionary(); + var headerParams: Dictionary = new Dictionary(); + + // verify required params are set + if(username == null ) { + throw new ApiError(400, "missing required params"); + } + var token:AsyncToken = getApiInvoker().invokeAPI(path, "GET", queryParams, null, headerParams); + + var requestId: String = getUniqueId(); + + token.requestId = requestId; + token.completionEventType = "getUserByName"; + + token.returnType = User; + return requestId; + + } + /* + * Returns string */ + public function loginUser (username: String, password: String): String { + // create path and map variables + var path: String = "/user.{format}/login".replace(/{format}/g,"xml"); + + // query params + var queryParams: Dictionary = new Dictionary(); + var headerParams: Dictionary = new Dictionary(); + + // verify required params are set + if(username == null || password == null ) { + throw new ApiError(400, "missing required params"); + } + if("null" != String(username)) + queryParams["username"] = toPathValue(username); + if("null" != String(password)) + queryParams["password"] = toPathValue(password); + var token:AsyncToken = getApiInvoker().invokeAPI(path, "GET", queryParams, null, headerParams); + + var requestId: String = getUniqueId(); + + token.requestId = requestId; + token.completionEventType = "loginUser"; + + token.returnType = string; + return requestId; + + } + /* + * Returns void */ + public function logoutUser (): String { + // create path and map variables + var path: String = "/user.{format}/logout".replace(/{format}/g,"xml"); + + // query params + var queryParams: Dictionary = new Dictionary(); + var headerParams: Dictionary = new Dictionary(); + + var token:AsyncToken = getApiInvoker().invokeAPI(path, "GET", queryParams, null, headerParams); + + var requestId: String = getUniqueId(); + + token.requestId = requestId; + token.completionEventType = "logoutUser"; + + token.returnType = null ; + return requestId; + + } + } + } diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/client/model/Category.as b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/Category.as new file mode 100644 index 00000000000..1b17bd5b332 --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/Category.as @@ -0,0 +1,21 @@ +package com.wordnik.client.model { + +[XmlRootNode(name="Category")] + public class Category { + [XmlElement(name="id")] + public var id: Number = 0.0; + + [XmlElement(name="name")] + public var name: String = null; + + public function toString(): String { + var str: String = "Category: "; + str += " (id: " + id + ")"; + str += " (name: " + name + ")"; + return str; + } + + +} +} + diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/client/model/CategoryList.as b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/CategoryList.as new file mode 100644 index 00000000000..e921b660418 --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/CategoryList.as @@ -0,0 +1,16 @@ +package com.wordnik.client.model { + +import com.wordnik.swagger.common.ListWrapper; +public class CategoryList implements ListWrapper { + // This declaration below of __obj_class is to force flash compiler to include this class + private var _category_obj_class: com.wordnik.client.model.Category = null; + [XmlElements(name="category", type="com.wordnik.client.model.Category")] + public var category: Array = new Array(); + + public function getList(): Array{ + return category; + } + +} +} + diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/client/model/Order.as b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/Order.as new file mode 100644 index 00000000000..6124e260f8f --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/Order.as @@ -0,0 +1,34 @@ +package com.wordnik.client.model { + +[XmlRootNode(name="Order")] + public class Order { + [XmlElement(name="id")] + public var id: Number = 0.0; + + [XmlElement(name="petId")] + public var petId: Number = 0.0; + + /* Order Status */ + [XmlElement(name="status")] + public var status: String = null; + + [XmlElement(name="quantity")] + public var quantity: Number = 0.0; + + [XmlElement(name="shipDate")] + public var shipDate: Date = null; + + public function toString(): String { + var str: String = "Order: "; + str += " (id: " + id + ")"; + str += " (petId: " + petId + ")"; + str += " (status: " + status + ")"; + str += " (quantity: " + quantity + ")"; + str += " (shipDate: " + shipDate + ")"; + return str; + } + + +} +} + diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/client/model/OrderList.as b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/OrderList.as new file mode 100644 index 00000000000..6c894c2faac --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/OrderList.as @@ -0,0 +1,16 @@ +package com.wordnik.client.model { + +import com.wordnik.swagger.common.ListWrapper; +public class OrderList implements ListWrapper { + // This declaration below of __obj_class is to force flash compiler to include this class + private var _order_obj_class: com.wordnik.client.model.Order = null; + [XmlElements(name="order", type="com.wordnik.client.model.Order")] + public var order: Array = new Array(); + + public function getList(): Array{ + return order; + } + +} +} + diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/client/model/Pet.as b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/Pet.as new file mode 100644 index 00000000000..fb46b1f50b7 --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/Pet.as @@ -0,0 +1,46 @@ +package com.wordnik.client.model { + +import com.wordnik.client.model.Category; +import com.wordnik.client.model.Tag; +[XmlRootNode(name="Pet")] + public class Pet { + [XmlElement(name="id")] + public var id: Number = 0.0; + + // This declaration below of _tags_obj_class is to force flash compiler to include this class + private var _tags_obj_class: com.wordnik.client.model.Tag = null; + [XmlElementWrapper(name="tags")] + [XmlElements(name="tag", type="com.wordnik.client.model.Tag")] + public var tags: Array = new Array(); + + [XmlElement(name="category")] + public var category: Category = null; + + /* pet status in the store */ + [XmlElement(name="status")] + public var status: String = null; + + [XmlElement(name="name")] + public var name: String = null; + + // This declaration below of _photoUrls_obj_class is to force flash compiler to include this class + private var _photoUrls_obj_class: com.wordnik.client.model.String = null; + [XmlElementWrapper(name="photoUrls")] + [XmlElements(name="photoUrl", type="com.wordnik.client.model.String")] + public var photoUrls: Array = new Array(); + + public function toString(): String { + var str: String = "Pet: "; + str += " (id: " + id + ")"; + str += " (tags: " + tags + ")"; + str += " (category: " + category + ")"; + str += " (status: " + status + ")"; + str += " (name: " + name + ")"; + str += " (photoUrls: " + photoUrls + ")"; + return str; + } + + +} +} + diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/client/model/PetList.as b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/PetList.as new file mode 100644 index 00000000000..d960f59cc2f --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/PetList.as @@ -0,0 +1,18 @@ +package com.wordnik.client.model { + +import com.wordnik.swagger.common.ListWrapper; +import com.wordnik.client.model.Category; +import com.wordnik.client.model.Tag; +public class PetList implements ListWrapper { + // This declaration below of __obj_class is to force flash compiler to include this class + private var _pet_obj_class: com.wordnik.client.model.Pet = null; + [XmlElements(name="pet", type="com.wordnik.client.model.Pet")] + public var pet: Array = new Array(); + + public function getList(): Array{ + return pet; + } + +} +} + diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/client/model/Tag.as b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/Tag.as new file mode 100644 index 00000000000..e229eb0ba64 --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/Tag.as @@ -0,0 +1,21 @@ +package com.wordnik.client.model { + +[XmlRootNode(name="Tag")] + public class Tag { + [XmlElement(name="id")] + public var id: Number = 0.0; + + [XmlElement(name="name")] + public var name: String = null; + + public function toString(): String { + var str: String = "Tag: "; + str += " (id: " + id + ")"; + str += " (name: " + name + ")"; + return str; + } + + +} +} + diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/client/model/TagList.as b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/TagList.as new file mode 100644 index 00000000000..3224bffe312 --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/TagList.as @@ -0,0 +1,16 @@ +package com.wordnik.client.model { + +import com.wordnik.swagger.common.ListWrapper; +public class TagList implements ListWrapper { + // This declaration below of __obj_class is to force flash compiler to include this class + private var _tag_obj_class: com.wordnik.client.model.Tag = null; + [XmlElements(name="tag", type="com.wordnik.client.model.Tag")] + public var tag: Array = new Array(); + + public function getList(): Array{ + return tag; + } + +} +} + diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/client/model/User.as b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/User.as new file mode 100644 index 00000000000..852825212af --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/User.as @@ -0,0 +1,46 @@ +package com.wordnik.client.model { + +[XmlRootNode(name="User")] + public class User { + [XmlElement(name="id")] + public var id: Number = 0.0; + + [XmlElement(name="lastName")] + public var lastName: String = null; + + [XmlElement(name="username")] + public var username: String = null; + + [XmlElement(name="phone")] + public var phone: String = null; + + [XmlElement(name="email")] + public var email: String = null; + + /* User Status */ + [XmlElement(name="userStatus")] + public var userStatus: Number = 0.0; + + [XmlElement(name="firstName")] + public var firstName: String = null; + + [XmlElement(name="password")] + public var password: String = null; + + public function toString(): String { + var str: String = "User: "; + str += " (id: " + id + ")"; + str += " (lastName: " + lastName + ")"; + str += " (username: " + username + ")"; + str += " (phone: " + phone + ")"; + str += " (email: " + email + ")"; + str += " (userStatus: " + userStatus + ")"; + str += " (firstName: " + firstName + ")"; + str += " (password: " + password + ")"; + return str; + } + + +} +} + diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/client/model/UserList.as b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/UserList.as new file mode 100644 index 00000000000..561aa1d8de4 --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/client/model/UserList.as @@ -0,0 +1,16 @@ +package com.wordnik.client.model { + +import com.wordnik.swagger.common.ListWrapper; +public class UserList implements ListWrapper { + // This declaration below of __obj_class is to force flash compiler to include this class + private var _user_obj_class: com.wordnik.client.model.User = null; + [XmlElements(name="user", type="com.wordnik.client.model.User")] + public var user: Array = new Array(); + + public function getList(): Array{ + return user; + } + +} +} + diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/swagger/common/ApiInvoker.as b/samples/petstore/flash/src/main/flex/com/wordnik/swagger/common/ApiInvoker.as new file mode 100644 index 00000000000..662041443dc --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/swagger/common/ApiInvoker.as @@ -0,0 +1,289 @@ +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 = ""; + private var _baseUrl: String = ""; + internal var _useProxyServer: Boolean = true; + private var _proxyHostName:String = ""; + private var _apiPath: String = ""; + private var _proxyPath: String = ""; + + 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; + _proxyPath = _apiUsageCredentials.proxyPath; + _apiProxyServerUrl = _apiUsageCredentials.apiProxyServerUrl; + _apiEventNotifier = eventNotifier; + } + + public function invokeAPI(resourceURL: String, method: String, queryParams: Dictionary, postObject: Object, headerParams: Dictionary): AsyncToken { + //make the communication + if(_useProxyServer) { + resourceURL = _apiProxyServerUrl + resourceURL; + } + else{ + 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++; + + } +// trace(resourceURL); + //create a httpservice and invoke the rest url waiting for response + var requestHeader:Object = new Object(); + if(headerParams != null) { + for(var key: String in headerParams) { + requestHeader[key] = headerParams[key]; + } + } + + resourceURL = ApiUrlHelper.appendTokenInfo(resourceURL, requestHeader, _apiUsageCredentials); + + var bodyData:String = marshal(postObject).toString();//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 if(restMethod == HTTPRequestMessage.PUT_METHOD){ + headers[X_HTTP_OVERRIDE_KEY]= HTTPRequestMessage.PUT_METHOD; + } + 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, _proxyPath); + 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); + try{ + resultObject = unmarshaller.unmarshal(resultXML); + } + catch(error: TypeError){ + var errorResponse: Response = new Response(false, null, "Could not unmarshall response"); + if (_apiEventNotifier != null) { //dispatch event via assigned dispatcher + var failureEvent: ApiClientEvent = new ApiClientEvent(event.token.completionEventType); + failureEvent.response = errorResponse; + _apiEventNotifier.dispatchEvent(failureEvent); + } + } + + if(resultObject is ListWrapper){ + resultObject = ListWrapper(resultObject).getList(); + } + } + + 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):Object { +// trace("marshal got - " + source) + if(source is String) { + return source; + } else if(source is Array && source.length > 0) { + var writer:XMLWriter=new XMLWriter(); + var sourceArray: Array = source as Array; + var arrayEnclosure: String = getArrayEnclosure(sourceArray); + writer.xml.setName(arrayEnclosure); + + for (var i:int = 0; i < sourceArray.length; i++) { + var o: Object = sourceArray[i]; + writer.xml.appendChild(marshal(o)); + } + return writer.xml; + } else + return marshalObject(source); + } + + public function marshalObject(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("::","."); + var className: String = qualifiedClassName.substring(qualifiedClassName.lastIndexOf(".") + 1); + className = className.charAt().toLowerCase() + className.substring(1); + writer.xml.setName(className); + + 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; + } + + public function escapeString(str: String): String { + return str; + } + + private function getArrayEnclosure(arr: Array) : String { + if(arr != null && arr.length > 0) { + var className: String = flash.utils.getQualifiedClassName(arr[0]) + if(className.indexOf("::") > 0) + className = className.substr(className.indexOf("::") + 2, className.length) + + return className.substring(0, 1).toLowerCase() + className.substring(1, className.length) + "s"; + } else + return ""; + } + + +} +} \ No newline at end of file diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/swagger/common/ApiUrlHelper.as b/samples/petstore/flash/src/main/flex/com/wordnik/swagger/common/ApiUrlHelper.as new file mode 100644 index 00000000000..3b94f447a83 --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/swagger/common/ApiUrlHelper.as @@ -0,0 +1,41 @@ +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 HTTP_URL_PREFIX:String = "http://"; + + internal static function appendTokenInfo(restUrl:String, requestHeader: Object, credentials: ApiUserCredentials): String { + //checks for the presence api credentials on client initialization and not repeated 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, proxyPath: String): String{ + if (hostName.charAt(hostName.length - 1) == "/") //remove trailing slash + { + hostName = hostName.substring(0, hostName.length - 1); + } + return HTTP_URL_PREFIX + hostName + proxyPath; + } +} +} diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/swagger/common/ApiUserCredentials.as b/samples/petstore/flash/src/main/flex/com/wordnik/swagger/common/ApiUserCredentials.as new file mode 100644 index 00000000000..a7536c213e2 --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/swagger/common/ApiUserCredentials.as @@ -0,0 +1,63 @@ +package com.wordnik.swagger.common { + +/** + * Api account credentials. + * + */ +public class ApiUserCredentials { + /** + * An apitoken that is passed along with the requests + */ + public var apiToken:String; + /** + * A valid auth_token which could be necessary for certain operations + */ + public var authToken:String; + /** + * The userId which could be required for certain operations + */ + public var userId:Number; + /** + * The host name for the Rest API eg. api.companyName.com + */ + public var hostName:String; + + /** + * The base path to the api resources - used along with the hostname + * eg. /v4 + */ + public var apiPath: String; + + /** + * The base path to the blazeds proxy + * eg. /v4/messagebroker/restproxy + */ + public var proxyPath: 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 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(hostName: String, apiPath: String, apiToken: String, + authToken: String = null, userId: Number = -1, apiProxyServerUrl: String="", + proxyPath: String = null) { + this.hostName = hostName; + this.apiToken = apiToken; + this.authToken = authToken; + this.userId = userId; + this.apiPath = apiPath; + this.apiProxyServerUrl = apiProxyServerUrl; + this.proxyPath = proxyPath; + } + +} +} \ No newline at end of file diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/swagger/common/ListWrapper.as b/samples/petstore/flash/src/main/flex/com/wordnik/swagger/common/ListWrapper.as new file mode 100644 index 00000000000..1ea2ebead00 --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/swagger/common/ListWrapper.as @@ -0,0 +1,9 @@ +package com.wordnik.swagger.common +{ + public interface ListWrapper + { + + function getList(): Array; + + } +} \ No newline at end of file diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/swagger/common/SwaggerApi.as b/samples/petstore/flash/src/main/flex/com/wordnik/swagger/common/SwaggerApi.as new file mode 100644 index 00000000000..a78f3105cb1 --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/swagger/common/SwaggerApi.as @@ -0,0 +1,75 @@ +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 _useProxyServer: Boolean = false; + + + /** + * 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/samples/petstore/flash/src/main/flex/com/wordnik/swagger/common/XMLWriter.as b/samples/petstore/flash/src/main/flex/com/wordnik/swagger/common/XMLWriter.as new file mode 100644 index 00000000000..067f49e6301 --- /dev/null +++ b/samples/petstore/flash/src/main/flex/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/samples/petstore/flash/src/main/flex/com/wordnik/swagger/event/ApiClientEvent.as b/samples/petstore/flash/src/main/flex/com/wordnik/swagger/event/ApiClientEvent.as new file mode 100644 index 00000000000..313da09ea78 --- /dev/null +++ b/samples/petstore/flash/src/main/flex/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 generated client 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/samples/petstore/flash/src/main/flex/com/wordnik/swagger/event/Response.as b/samples/petstore/flash/src/main/flex/com/wordnik/swagger/event/Response.as new file mode 100644 index 00000000000..56cceb61959 --- /dev/null +++ b/samples/petstore/flash/src/main/flex/com/wordnik/swagger/event/Response.as @@ -0,0 +1,56 @@ +package com.wordnik.swagger.event { + +/** + * Response contains info on the result of an API invocation. + * A completion listener will expect this Response object. + */ +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; + } + + public function toString(): String { + return "Response (requestId:" + requestId + "; isSuccess:" + isSuccess + "; errorMessage:" + errorMessage + "; payload:" + payload + ")"; + } +} +} \ No newline at end of file diff --git a/samples/petstore/flash/src/main/flex/com/wordnik/swagger/exception/ApiError.as b/samples/petstore/flash/src/main/flex/com/wordnik/swagger/exception/ApiError.as new file mode 100644 index 00000000000..13d09415829 --- /dev/null +++ b/samples/petstore/flash/src/main/flex/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/samples/petstore/flash/src/main/flex/com/wordnik/swagger/exception/ApiErrorCodes.as b/samples/petstore/flash/src/main/flex/com/wordnik/swagger/exception/ApiErrorCodes.as new file mode 100644 index 00000000000..abe12178361 --- /dev/null +++ b/samples/petstore/flash/src/main/flex/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/src/main/resources/flash/ASAXB-0.1.1.swc b/src/main/resources/flash/ASAXB-0.1.1.swc new file mode 100644 index 00000000000..c9359026784 Binary files /dev/null and b/src/main/resources/flash/ASAXB-0.1.1.swc differ diff --git a/src/main/resources/flash/AirExecutorApp-app.xml b/src/main/resources/flash/AirExecutorApp-app.xml new file mode 100644 index 00000000000..1dbaf98e644 --- /dev/null +++ b/src/main/resources/flash/AirExecutorApp-app.xml @@ -0,0 +1,146 @@ + + + + + + + AirExecutorApp + + + AirExecutorApp + + + AirExecutorApp + + + v1 + + + + + + + + + + + + + + + AirExecutorApp.swf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/flash/ApiClientEvent.as b/src/main/resources/flash/ApiClientEvent.as new file mode 100644 index 00000000000..313da09ea78 --- /dev/null +++ b/src/main/resources/flash/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 generated client 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/src/main/resources/flash/ApiError.as b/src/main/resources/flash/ApiError.as new file mode 100644 index 00000000000..13d09415829 --- /dev/null +++ b/src/main/resources/flash/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/src/main/resources/flash/ApiErrorCodes.as b/src/main/resources/flash/ApiErrorCodes.as new file mode 100644 index 00000000000..abe12178361 --- /dev/null +++ b/src/main/resources/flash/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/src/main/resources/flash/ApiInvoker.as b/src/main/resources/flash/ApiInvoker.as new file mode 100644 index 00000000000..662041443dc --- /dev/null +++ b/src/main/resources/flash/ApiInvoker.as @@ -0,0 +1,289 @@ +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 = ""; + private var _baseUrl: String = ""; + internal var _useProxyServer: Boolean = true; + private var _proxyHostName:String = ""; + private var _apiPath: String = ""; + private var _proxyPath: String = ""; + + 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; + _proxyPath = _apiUsageCredentials.proxyPath; + _apiProxyServerUrl = _apiUsageCredentials.apiProxyServerUrl; + _apiEventNotifier = eventNotifier; + } + + public function invokeAPI(resourceURL: String, method: String, queryParams: Dictionary, postObject: Object, headerParams: Dictionary): AsyncToken { + //make the communication + if(_useProxyServer) { + resourceURL = _apiProxyServerUrl + resourceURL; + } + else{ + 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++; + + } +// trace(resourceURL); + //create a httpservice and invoke the rest url waiting for response + var requestHeader:Object = new Object(); + if(headerParams != null) { + for(var key: String in headerParams) { + requestHeader[key] = headerParams[key]; + } + } + + resourceURL = ApiUrlHelper.appendTokenInfo(resourceURL, requestHeader, _apiUsageCredentials); + + var bodyData:String = marshal(postObject).toString();//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 if(restMethod == HTTPRequestMessage.PUT_METHOD){ + headers[X_HTTP_OVERRIDE_KEY]= HTTPRequestMessage.PUT_METHOD; + } + 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, _proxyPath); + 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); + try{ + resultObject = unmarshaller.unmarshal(resultXML); + } + catch(error: TypeError){ + var errorResponse: Response = new Response(false, null, "Could not unmarshall response"); + if (_apiEventNotifier != null) { //dispatch event via assigned dispatcher + var failureEvent: ApiClientEvent = new ApiClientEvent(event.token.completionEventType); + failureEvent.response = errorResponse; + _apiEventNotifier.dispatchEvent(failureEvent); + } + } + + if(resultObject is ListWrapper){ + resultObject = ListWrapper(resultObject).getList(); + } + } + + 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):Object { +// trace("marshal got - " + source) + if(source is String) { + return source; + } else if(source is Array && source.length > 0) { + var writer:XMLWriter=new XMLWriter(); + var sourceArray: Array = source as Array; + var arrayEnclosure: String = getArrayEnclosure(sourceArray); + writer.xml.setName(arrayEnclosure); + + for (var i:int = 0; i < sourceArray.length; i++) { + var o: Object = sourceArray[i]; + writer.xml.appendChild(marshal(o)); + } + return writer.xml; + } else + return marshalObject(source); + } + + public function marshalObject(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("::","."); + var className: String = qualifiedClassName.substring(qualifiedClassName.lastIndexOf(".") + 1); + className = className.charAt().toLowerCase() + className.substring(1); + writer.xml.setName(className); + + 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; + } + + public function escapeString(str: String): String { + return str; + } + + private function getArrayEnclosure(arr: Array) : String { + if(arr != null && arr.length > 0) { + var className: String = flash.utils.getQualifiedClassName(arr[0]) + if(className.indexOf("::") > 0) + className = className.substr(className.indexOf("::") + 2, className.length) + + return className.substring(0, 1).toLowerCase() + className.substring(1, className.length) + "s"; + } else + return ""; + } + + +} +} \ No newline at end of file diff --git a/src/main/resources/flash/ApiUrlHelper.as b/src/main/resources/flash/ApiUrlHelper.as new file mode 100644 index 00000000000..3b94f447a83 --- /dev/null +++ b/src/main/resources/flash/ApiUrlHelper.as @@ -0,0 +1,41 @@ +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 HTTP_URL_PREFIX:String = "http://"; + + internal static function appendTokenInfo(restUrl:String, requestHeader: Object, credentials: ApiUserCredentials): String { + //checks for the presence api credentials on client initialization and not repeated 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, proxyPath: String): String{ + if (hostName.charAt(hostName.length - 1) == "/") //remove trailing slash + { + hostName = hostName.substring(0, hostName.length - 1); + } + return HTTP_URL_PREFIX + hostName + proxyPath; + } +} +} diff --git a/src/main/resources/flash/ApiUserCredentials.as b/src/main/resources/flash/ApiUserCredentials.as new file mode 100644 index 00000000000..a7536c213e2 --- /dev/null +++ b/src/main/resources/flash/ApiUserCredentials.as @@ -0,0 +1,63 @@ +package com.wordnik.swagger.common { + +/** + * Api account credentials. + * + */ +public class ApiUserCredentials { + /** + * An apitoken that is passed along with the requests + */ + public var apiToken:String; + /** + * A valid auth_token which could be necessary for certain operations + */ + public var authToken:String; + /** + * The userId which could be required for certain operations + */ + public var userId:Number; + /** + * The host name for the Rest API eg. api.companyName.com + */ + public var hostName:String; + + /** + * The base path to the api resources - used along with the hostname + * eg. /v4 + */ + public var apiPath: String; + + /** + * The base path to the blazeds proxy + * eg. /v4/messagebroker/restproxy + */ + public var proxyPath: 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 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(hostName: String, apiPath: String, apiToken: String, + authToken: String = null, userId: Number = -1, apiProxyServerUrl: String="", + proxyPath: String = null) { + this.hostName = hostName; + this.apiToken = apiToken; + this.authToken = authToken; + this.userId = userId; + this.apiPath = apiPath; + this.apiProxyServerUrl = apiProxyServerUrl; + this.proxyPath = proxyPath; + } + +} +} \ No newline at end of file diff --git a/src/main/resources/flash/ListWrapper.as b/src/main/resources/flash/ListWrapper.as new file mode 100644 index 00000000000..1ea2ebead00 --- /dev/null +++ b/src/main/resources/flash/ListWrapper.as @@ -0,0 +1,9 @@ +package com.wordnik.swagger.common +{ + public interface ListWrapper + { + + function getList(): Array; + + } +} \ No newline at end of file diff --git a/src/main/resources/flash/Response.as b/src/main/resources/flash/Response.as new file mode 100644 index 00000000000..56cceb61959 --- /dev/null +++ b/src/main/resources/flash/Response.as @@ -0,0 +1,56 @@ +package com.wordnik.swagger.event { + +/** + * Response contains info on the result of an API invocation. + * A completion listener will expect this Response object. + */ +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; + } + + public function toString(): String { + return "Response (requestId:" + requestId + "; isSuccess:" + isSuccess + "; errorMessage:" + errorMessage + "; payload:" + payload + ")"; + } +} +} \ No newline at end of file diff --git a/src/main/resources/flash/SwaggerApi.as b/src/main/resources/flash/SwaggerApi.as new file mode 100644 index 00000000000..a78f3105cb1 --- /dev/null +++ b/src/main/resources/flash/SwaggerApi.as @@ -0,0 +1,75 @@ +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 _useProxyServer: Boolean = false; + + + /** + * 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/src/main/resources/flash/XMLWriter.as b/src/main/resources/flash/XMLWriter.as new file mode 100644 index 00000000000..067f49e6301 --- /dev/null +++ b/src/main/resources/flash/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/src/main/resources/flash/api.mustache b/src/main/resources/flash/api.mustache new file mode 100644 index 00000000000..647ec763a24 --- /dev/null +++ b/src/main/resources/flash/api.mustache @@ -0,0 +1,73 @@ +package {{package}} { + +import com.wordnik.swagger.common.ApiInvoker; +import com.wordnik.swagger.exception.ApiErrorCodes; +import com.wordnik.swagger.exception.ApiError; +import com.wordnik.swagger.common.ApiUserCredentials; +import com.wordnik.swagger.event.Response; +import com.wordnik.swagger.common.SwaggerApi; +{{#imports}}import {{import}}; +{{/imports}} + +import mx.rpc.AsyncToken; +import mx.utils.UIDUtil; +import flash.utils.Dictionary; +import flash.events.EventDispatcher; + +{{#operations}} +public class {{classname}} extends SwaggerApi { + /** + * Constructor for the {{classname}} 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 {{classname}}(apiCredentials: ApiUserCredentials, eventDispatcher: EventDispatcher = null) { + super(apiCredentials, eventDispatcher); + } + +{{#operation}} + public static const event_{{nickname}}: String = "{{nickname}}"; +{{/operation}} + +{{#operation}} + + /* + * Returns {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}} + */ + public function {{nickname}} ({{#allParams}}{{paramName}}: {{{dataType}}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{#hasMore}}, {{/hasMore}}{{/allParams}}): String { + // create path and map variables + var path: String = "{{path}}".replace(/{format}/g,"xml"){{#pathParams}}.replace("{" + "{{paramName}}" + "}", getApiInvoker().escapeString({{{paramName}}})){{/pathParams}}; + + // query params + var queryParams: Dictionary = new Dictionary(); + var headerParams: Dictionary = new Dictionary(); + + {{#requiredParamCount}} + // verify required params are set + if({{/requiredParamCount}}{{#requiredParams}} {{paramName}} == null {{#hasMore}}|| {{/hasMore}}{{/requiredParams}}{{#requiredParamCount}}) { + throw new ApiError(400, "missing required params"); + } + {{/requiredParamCount}} + + {{#queryParams}}if("null" != String({{paramName}})) + queryParams["{{paramName}}"] = toPathValue({{paramName}}); + {{/queryParams}} + + {{#headerParams}}headerParams["{{paramName}}"] = toPathValue({{paramName}}); + {{/headerParams}} + + var token:AsyncToken = getApiInvoker().invokeAPI(path, "{{httpMethod}}", queryParams, {{#bodyParam}}{{bodyParam}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}}, headerParams); + + var requestId: String = getUniqueId(); + + token.requestId = requestId; + token.completionEventType = "{{nickname}}"; + + token.returnType = {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}null {{/returnType}}; + return requestId; + + } + {{/operation}} +} + {{/operations}} +} \ No newline at end of file diff --git a/src/main/resources/flash/as3corelib.swc b/src/main/resources/flash/as3corelib.swc new file mode 100644 index 00000000000..12dd6b3b0a6 Binary files /dev/null and b/src/main/resources/flash/as3corelib.swc differ diff --git a/src/main/resources/flash/build.properties b/src/main/resources/flash/build.properties new file mode 100644 index 00000000000..8e77d88c961 --- /dev/null +++ b/src/main/resources/flash/build.properties @@ -0,0 +1,29 @@ +# 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/flex + +# 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/flex + +# 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 + +# The location of the test sources +testsourcepath = ./src/test/flex + +# Home directory for flex sdk, change this to build for Mac or PC using # as comment +FLEX4_SDK_HOME = /usr/local/flex_sdk_4.1.0/ +#FLEX4_SDK_HOME = /Applications/Adobe Flash Builder 4/sdks/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 + diff --git a/src/main/resources/flash/build.xml b/src/main/resources/flash/build.xml new file mode 100644 index 00000000000..58c487d2364 --- /dev/null +++ b/src/main/resources/flash/build.xml @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + docs created + + + + + + + + + + + + + + + + + + + + + + + + SWC created + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/flash/facetValue.as b/src/main/resources/flash/facetValue.as new file mode 100644 index 00000000000..c6bfa1f27d1 --- /dev/null +++ b/src/main/resources/flash/facetValue.as @@ -0,0 +1,8 @@ +package com.wordnik.client.model { + + public class FacetValue { + public var value: String = null; + public var count: Number = 0; + } + +} \ No newline at end of file diff --git a/src/main/resources/flash/flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc b/src/main/resources/flash/flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc new file mode 100644 index 00000000000..e41bc68abd9 Binary files /dev/null and b/src/main/resources/flash/flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc differ diff --git a/src/main/resources/flash/flexunit-aircilistener-4.1.0_RC2-28-3.5.0.12683.swc b/src/main/resources/flash/flexunit-aircilistener-4.1.0_RC2-28-3.5.0.12683.swc new file mode 100644 index 00000000000..8bbdf8b86a0 Binary files /dev/null and b/src/main/resources/flash/flexunit-aircilistener-4.1.0_RC2-28-3.5.0.12683.swc differ diff --git a/src/main/resources/flash/flexunit-cilistener-4.1.0_RC2-28-3.5.0.12683.swc b/src/main/resources/flash/flexunit-cilistener-4.1.0_RC2-28-3.5.0.12683.swc new file mode 100644 index 00000000000..b69064ac765 Binary files /dev/null and b/src/main/resources/flash/flexunit-cilistener-4.1.0_RC2-28-3.5.0.12683.swc differ diff --git a/src/main/resources/flash/flexunit-core-flex-4.0.0.2-sdk3.5.0.12683.swc b/src/main/resources/flash/flexunit-core-flex-4.0.0.2-sdk3.5.0.12683.swc new file mode 100644 index 00000000000..a90af750bb5 Binary files /dev/null and b/src/main/resources/flash/flexunit-core-flex-4.0.0.2-sdk3.5.0.12683.swc differ diff --git a/src/main/resources/flash/model.mustache b/src/main/resources/flash/model.mustache new file mode 100644 index 00000000000..5720c96508b --- /dev/null +++ b/src/main/resources/flash/model.mustache @@ -0,0 +1,42 @@ +package {{package}} { + +{{#imports}}import {{import}}; +{{/imports}} + +{{#models}} +{{#model}} + [XmlRootNode(name="{{classname}}")] + public class {{classname}} { + {{#vars}} + + {{#notes}}/* {{notes}} */ + {{/notes}} + {{#description}}/* {{description}} */ + {{/description}} + + {{#isList}} + // This declaration below of _{{name}}_obj_class is to force flash compiler to include this class + private var _{{name}}_obj_class: {{baseType}} = null; + [XmlElementWrapper(name="{{name}}")] + [XmlElements(name="{{nameSingular}}", type="{{baseType}}")] + {{/isList}} + {{#isNotContainer}}[XmlElement(name="{{name}}")] + {{/isNotContainer}} + public var {{name}}: {{{datatype}}} = {{{defaultValue}}}; + + {{/vars}} + + public function toString(): String { + var str: String = "{{classname}}: "; + {{#vars}} + str += " ({{name}}: " + {{name}} + ")"; + {{/vars}} + return str; + } + + +} +{{/model}} + {{/models}} + +} diff --git a/src/main/resources/flash/modelList.mustache b/src/main/resources/flash/modelList.mustache new file mode 100644 index 00000000000..b0c3bd73f83 --- /dev/null +++ b/src/main/resources/flash/modelList.mustache @@ -0,0 +1,23 @@ +package {{package}} { + +import com.wordnik.swagger.common.ListWrapper; +{{#imports}}import {{import}}; +{{/imports}} + +{{#models}} +{{#model}} + public class {{classname}}List implements ListWrapper { + // This declaration below of _{{name}}_obj_class is to force flash compiler to include this class + private var _{{classVarName}}_obj_class: {{package}}.{{classname}} = null; + [XmlElements(name="{{classVarName}}", type="{{package}}.{{classname}}")] + public var {{classVarName}}: Array = new Array(); + + public function getList(): Array{ + return {{classVarName}}; + } + +} +{{/model}} + {{/models}} + +} diff --git a/src/main/scala/FlashPetstoreCodegen.scala b/src/main/scala/FlashPetstoreCodegen.scala new file mode 100644 index 00000000000..81e4b36198f --- /dev/null +++ b/src/main/scala/FlashPetstoreCodegen.scala @@ -0,0 +1,27 @@ +import com.wordnik.swagger.codegen.BasicFlashCodegen + +object FlashPetstoreCodegen extends BasicFlashCodegen { + def main(args: Array[String]) = generateClient(args) + + override def packageName = "com.wordnik.client" + + override def destinationRoot = "samples/petstore/flash" + + // where to write generated code + override def destinationDir = destinationRoot + "/src/main/flex" + + // package for models + override def modelPackage = Some("com.wordnik.client.model") + + // package for api classes + override def apiPackage = Some("com.wordnik.client.api") + + // supporting classes + override def supportingFiles = baseSupportingFiles ++ List() +} + +object FlashPetstoreCodegenRunner { + def main(args: Array[String]) { + FlashPetstoreCodegen.main(args) + } +} \ No newline at end of file diff --git a/src/main/scala/com/wordnik/swagger/codegen/BasicFlashCodegen.scala b/src/main/scala/com/wordnik/swagger/codegen/BasicFlashCodegen.scala new file mode 100644 index 00000000000..b9fa87112da --- /dev/null +++ b/src/main/scala/com/wordnik/swagger/codegen/BasicFlashCodegen.scala @@ -0,0 +1,158 @@ +package com.wordnik.swagger.codegen + +import com.wordnik.swagger.core._ + +abstract class BasicFlashCodegen extends BasicGenerator { + override def defaultIncludes = Set( + "Date", + "double", + "int", + "long", + "float", + "String", + "boolean") + + override def typeMapping = Map( + "boolean" -> "Boolean", + "string" -> "String", + "int" -> "Number", + "float" -> "Number", + "long" -> "Number", + "double" -> "Number") + + override def packageName = "com.wordnik.client" + + // location of templates + override def templateDir = "flash" + + // template used for models + modelTemplateFiles += "model.mustache" -> ".as" + modelTemplateFiles += "modelList.mustache" -> "List.as" + + // template used for models + apiTemplateFiles += "api.mustache" -> ".as" + + // where to write generated code + override def destinationDir = "src/test/flash" + + + // import/require statements for specific datatypes + override def importMapping = Map() + + + // package for models + override def modelPackage = Some("com.wordnik.client.model") + + // package for api classes + override def apiPackage = Some("com.wordnik.client.api") + + // file suffix + override def fileSuffix = ".as" + + override def toVarName(name: String): String = { + name.substring(0, 1).toLowerCase + name.substring(1, name.length) + } + + // response classes + override def processResponseClass(responseClass: String): Option[String] = { + responseClass match { + case "void" => None + case e: String => Some(e) + } + } + + override def processResponseDeclaration(responseClass: String): Option[String] = { + responseClass match { + case "void" => None + case e: String => { + responseClass.startsWith("List") match { + case true => { + val responseSubClass = responseClass.dropRight(1).substring(5) + typeMapping.contains(responseSubClass) match { + case true => Some("Array") + case false => Some(packageName + ".model." + + responseSubClass + "List") + } + } + case false => Some(responseClass) + } + } + } + } + + override def toDeclaredType(dt: String): String = { + val declaredType = dt.indexOf("[") match { + case -1 => dt + case n: Int => { + if (dt.substring(0, n) == "Array") { + "Array" + } else if (dt.substring(0, n) == "List") { + "Array" + } else dt + } + case _ => dt + } + typeMapping.getOrElse(declaredType, declaredType) + } + + override def toDeclaration(obj: DocumentationSchema) = { + var declaredType = toDeclaredType(obj.getType) + + declaredType match { + case "Array" => { + declaredType = "Array" + } + case "List" => { + declaredType = "Array" + } + case e: String => e + } + + val defaultValue = toDefaultValue(declaredType, obj) + declaredType match { + case "List" => "Array" + case _ => + } + (declaredType, defaultValue) + } + + // default values + override def toDefaultValue(properCase: String, obj: DocumentationSchema) = { + properCase match { + case "Boolean" => "false" + case "Number" => "0.0" + case "List" => "new Array()" + case "Array" => "new Array()" + case _ => "null" + } + } + + def destinationRoot: String + + // supporting classes + def baseSupportingFiles = List( + ("ApiInvoker.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/common", "ApiInvoker.as"), + ("ApiUrlHelper.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/common", "ApiUrlHelper.as"), + ("ApiUserCredentials.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/common", "ApiUserCredentials.as"), + ("ListWrapper.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/common", "ListWrapper.as"), + ("SwaggerApi.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/common", "SwaggerApi.as"), + ("XMLWriter.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/common", "XMLWriter.as"), + + ("ApiError.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/exception", "ApiError.as"), + ("ApiErrorCodes.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/exception", "ApiErrorCodes.as"), + + ("ApiClientEvent.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/event", "ApiClientEvent.as"), + ("Response.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/event", "Response.as"), + + ("build.properties", destinationRoot, "build.properties"), + ("build.xml", destinationRoot, "build.xml"), + ("AirExecutorApp-app.xml", destinationRoot + "/bin", "AirExecutorApp-app.xml"), + + ("ASAXB-0.1.1.swc", destinationRoot + "/lib", "ASAXB-0.1.1.swc"), + ("as3corelib.swc", destinationRoot + "/lib/ext", "as3corelib.swc"), + ("flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc", destinationRoot + "/lib/ext", "flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc"), + ("flexunit-aircilistener-4.1.0_RC2-28-3.5.0.12683.swc", destinationRoot + "/lib/ext", "flexunit-aircilistener-4.1.0_RC2-28-3.5.0.12683.swc"), + ("flexunit-cilistener-4.1.0_RC2-28-3.5.0.12683.swc", destinationRoot + "/lib/ext", "flexunit-cilistener-4.1.0_RC2-28-3.5.0.12683.swc"), + ("flexunit-core-flex-4.0.0.2-sdk3.5.0.12683.swc", destinationRoot + "/lib/ext", "flexunit-core-flex-4.0.0.2-sdk3.5.0.12683.swc") + ) +} \ No newline at end of file