Merge branch 'javascript-support'

This commit is contained in:
Ayush Gupta 2011-10-27 16:55:57 +05:30
commit d3e651e540
37 changed files with 2220 additions and 14 deletions

23
bin/generate-js-lib.sh Executable file
View File

@ -0,0 +1,23 @@
#!/bin/bash
if [ $# -ne 4 ]
then
echo "Error in $0 - Invalid Argument Count "
echo "Syntax: $0 location_of_service api_key package_name library_root"
exit
fi
echo "" > classpath.txt
for file in `ls lib`;
do echo -n 'lib/' >> classpath.txt;
echo -n $file >> classpath.txt;
echo -n ':' >> classpath.txt;
done
for file in `ls build`;
do echo -n 'build/' >> classpath.txt;
echo -n $file >> classpath.txt;
echo -n ':' >> classpath.txt;
done
export CLASSPATH=$(cat classpath.txt):conf/js/templates
export JAVA_OPTS="${JAVA_OPTS} -Dproperty=Xmx2g"
java $WORDNIK_OPTS $JAVA_CONFIG_OPTIONS $JAVA_OPTS -cp $CLASSPATH com.wordnik.swagger.codegen.config.js.JSLibCodeGen "$@"

18
bin/runas3TestCase.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/bash
echo "" > classpath.txt
for file in `ls lib`;
do echo -n 'lib/' >> classpath.txt;
echo -n $file >> classpath.txt;
echo -n ':' >> classpath.txt;
done
for file in `ls build`;
do echo -n 'build/' >> classpath.txt;
echo -n $file >> classpath.txt;
echo -n ':' >> classpath.txt;
done
echo -n 'build/main/java' >> classpath.txt;
echo -n ':' >> classpath.txt;
#first argument to the command line script give location of the library jar file
export CLASSPATH=$(cat classpath.txt)$2
export JAVA_OPTS="${JAVA_OPTS} -DrulePath=data -Dproperty=Xmx2g -DloggerPath=$BUILD_COMMON/test-config/log4j.properties"
java $WORDNIK_OPTS $JAVA_CONFIG_OPTIONS $JAVA_OPTS -cp $CLASSPATH "$@" com.wordnik.swagger.api ../swagger-sample-app/sdk-libs/bin/AirExecutorApp-app.xml "/Applications/Adobe Flash Builder 4/sdks/4.1.0"

23
bin/test-as3-lib.sh Executable file
View File

@ -0,0 +1,23 @@
#!/bin/bash
if [ $# -ne 7 ]
then
echo "Error in $0 - Invalid Argument Count - expected 7 but has "
echo "$#"
echo "Syntax: $0 location_of_service api_key test_script_location test_data_location test_data_class_name api_classes_package_name location_of_client_library"
exit
fi
echo "" > classpath.txt
for file in `ls lib`;
do echo -n 'lib/' >> classpath.txt;
echo -n $file >> classpath.txt;
echo -n ':' >> classpath.txt;
done
for file in `ls build`;
do echo -n 'build/' >> classpath.txt;
echo -n $file >> classpath.txt;
echo -n ':' >> classpath.txt;
done
export CLASSPATH=$(cat classpath.txt)$7
echo $CLASSPATH
export JAVA_OPTS="${JAVA_OPTS} -Dproperty=Xmx2g "
java $WORDNIK_OPTS $JAVA_CONFIG_OPTIONS $JAVA_OPTS -cp $CLASSPATH com.wordnik.swagger.testframework.APITestRunner "$@" AS3

View File

@ -5,11 +5,15 @@
<!-- import our build properties file --> <!-- import our build properties file -->
<property file="./build.properties"/> <property file="./build.properties"/>
<property environment="env"/> <property environment="env"/>
<property name="FLEX_HOME" value="${env.SDK_HOME}"/> <property name="FLEX_HOME" value="${FLEX4_SDK_HOME}"/>
<property name="FLEX4_HOME" value="${FLEX4_SDK_HOME}"/>
<!--<property name="flexunit.swc" value="../lib/ext/flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc" />
<property name="flexunit-uilistener.swc" value="../lib/ext/flexunit-uilistener-4.1.0_RC2-28-flex_3.5.0.12683.swc" />
<property name="flexunit-cilistener.swc" value="../lib/ext/flexunit-cilistener-4.1.0_RC2-28-flex_3.5.0.12683.swc" />-->
<!-- Flex Ant Tasks used to perform compc and mxml compiling more info at http://labs.adobe.com/wiki/index.php/Flex_Ant_Tasks --> <!-- Flex Ant Tasks used to perform compc and mxml compiling more info at http://labs.adobe.com/wiki/index.php/Flex_Ant_Tasks -->
<taskdef resource="flexTasks.tasks" classpath="${env.SDK_HOME}/ant/lib/flexTasks.jar"/> <taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar"/>
<target name="setup" description="perform an setup operations"/> <target name="setup" description="perform an setup operations"/>
@ -103,7 +107,7 @@
<keep-as3-metadata name="XmlRootNode"/> <keep-as3-metadata name="XmlRootNode"/>
<keep-as3-metadata name="XmlElement"/> <keep-as3-metadata name="XmlElement"/>
<keep-as3-metadata name="XmlElements"/> <keep-as3-metadata name="XmlElements"/>
<!-- include our Class packages into the build (com folder) --> <!-- include our Class packages into the build (com folder) -->
<include-sources dir="${sourcepath}" includes="*" /> <include-sources dir="${sourcepath}" includes="*" />
@ -128,4 +132,51 @@
<zip destfile="sample-as3-sdk.zip" basedir="${basedir}/dist" /> <zip destfile="sample-as3-sdk.zip" basedir="${basedir}/dist" />
</target> </target>
<!-- Compiles and creates a test app that can be run using the adl - AIR Debug Launcher from command line
Note: For the output file to be executed an xml file is needed which points to this output swf - this is not
generated here
-->
<target name="compile-test" depends="buildSWC">
<property name="FLEX_HOME" value="${FLEX4_SDK_HOME}"/>
<mxmlc
static-rsls="false"
fork="true"
maxmemory="512m"
file="${testsourcepath}/AirExecutorApp.mxml"
output="${basedir}/${liboutputfolder}/AirExecutorApp.swf"
warnings="false"
configname="air"
locale="en_US">
<load-config filename="${FLEX4_HOME}/frameworks/air-config.xml"/>
<source-path path-element="${FLEX_HOME}/frameworks"/>
<compiler.debug>true</compiler.debug>
<source-path path-element="${testsourcepath}" />
<!--<source-path path-element="${APP_ROOT}/locale/{locale}" />-->
<library-path dir="${FLEX_HOME}/frameworks/libs" append="true">
<include name="*.swc" />
</library-path>
<library-path dir="${FLEX_HOME}/frameworks/libs/air" append="true">
<include name="*.swc" />
</library-path>
<library-path dir="${FLEX_HOME}/frameworks/locale" append="true">
<include name="{locale}" />
</library-path>
<library-path dir="${basedir}/${libpath}" append="true">
<include name="*.swc" />
</library-path>
<library-path dir="${basedir}/${liboutputfolder}" append="true">
<include name="*.swc" />
</library-path>
<library-path dir="${basedir}/${libpath}/ext" append="true">
<include name="*.swc" />
</library-path>
<verbose-stacktraces>true</verbose-stacktraces>
</mxmlc>
</target>
</project> </project>

View File

@ -0,0 +1,42 @@
{
"userList":[
{
"username":"testuser1",
"password":"password1",
"email":"test1@dummy.com"
},
{
"username":"testuser2",
"password":"password2",
"email":"test2@dummy.com"
}
],
"petList":[
{
"id":101,
"name":"pet1",
"photoUrls":["url1","url2"],
"tags":[
{
"id":1,
"name":"tag1"
},
{
"id":2,
"name":"tag2"
}
],
"status":"available",
"category":{"id":1,"name":"cat1"}
}
],
"orderList":[
{
"id":101,
"petId":1,
"quantity":1,
"status":"placed",
"shipDate":13456789
}
]
}

View File

@ -0,0 +1,265 @@
{
"resources" : [
{
"id" : 1,
"name" : "Find Per by Id",
"httpMethod" : "GET",
"path" : "/pet.{format}/{petId}",
"suggestedMethodName" : "getPetById"
},
{
"id" : 2,
"name" : "Find pets by status",
"httpMethod" : "GET",
"path" : "/pet.{format}/findByStatus",
"suggestedMethodName" : "findPetsByStatus"
},
{
"id" : 3,
"name" : "Find pets by tags",
"httpMethod" : "GET",
"path" : "/pet.{format}/findByTags",
"suggestedMethodName" : "findPetsByTags"
},
{
"id" : 4,
"name" : "Add a pet",
"httpMethod" : "POST",
"path" : "/pet.{format}",
"suggestedMethodName" : "addPet"
},
{
"id" : 5,
"name" : "Update a pet",
"httpMethod" : "PUT",
"path" : "/pet.{format}",
"suggestedMethodName" : "updatePet"
},
{
"id" : 6,
"name" : "Create user",
"httpMethod" : "POST",
"path" : "/user.{format}",
"suggestedMethodName" : "createUser"
},
{
"id" : 7,
"name" : "Update user",
"httpMethod" : "PUT",
"path" : "/user.{format}/{username}",
"suggestedMethodName" : "updateUser"
},
{
"id" : 8,
"name" : "Delete user",
"httpMethod" : "DELETE",
"path" : "/user.{format}/{username}",
"suggestedMethodName" : "deleteUser"
},
{
"id" : 9,
"name" : "Get user by user name",
"httpMethod" : "GET",
"path" : "/user.{format}/{username}",
"suggestedMethodName" : "getUserByName"
},
{
"id" : 10,
"name" : "Login",
"httpMethod" : "GET",
"path" : "/user.{format}/login",
"suggestedMethodName" : "loginUser"
},
{
"id" : 11,
"name" : "Logout",
"httpMethod" : "GET",
"path" : "/user.{format}/logout",
"suggestedMethodName" : "logoutUser"
},
{
"id" : 12,
"name" : "Find order by id",
"httpMethod" : "GET",
"path" : "/store.{format}/order/{orderId}",
"suggestedMethodName" : "getOrderById"
},
{
"id" : 13,
"name" : "Delete order by id",
"httpMethod" : "DELETE",
"path" : "/store.{format}/order/{orderId}",
"suggestedMethodName" : "deleteOrder"
},
{
"id" : 14,
"name" : "Create order",
"httpMethod" : "POST",
"path" : "/store.{format}/order",
"suggestedMethodName" : "placeOrder"
}
],
"testSuites" : [
{
"id" : 1,
"name" : "Test User service related APIs",
"testCases" : [
{
"name" : "Create User",
"id" : 1,
"resourceId" : 6,
"input" : {
"postData":"${input.userList[0]}"
},
"assertions" : [
{
"actualOutput" : "${output(1.1)}",
"condition" : "!=",
"expectedOutput" : "EXCEPTION"
}
]
},
{
"name" : "Login User",
"id" : 2,
"resourceId" : 10,
"input" : {
"username":"${input.userList[0].username}",
"password":"${input.userList[0].password}"
},
"assertions" : [
{
"actualOutput" : "${output(1.2)}",
"condition" : "!=",
"expectedOutput" : "EXCEPTION"
}
]
},
{
"name" : "Find user by name",
"id" : 3,
"resourceId" : 9,
"input" : {
"username":"${input.userList[0].username}"
},
"assertions" : [
{
"actualOutput" : "${output(1.3).username}",
"condition" : "==",
"expectedOutput" : "${input.userList[0].username}"
}
]
},
{
"name" : "Delete user by name",
"id" : 4,
"resourceId" : 9,
"input" : {
"username":"${input.userList[0].username}"
},
"assertions" : [
{
"actualOutput" : "${output(1.4)}",
"condition" : "!=",
"expectedOutput" : "EXCEPTION"
}
]
}
]
},
{
"id" : 2,
"name" : "Test Pet service related APIs",
"testCases" : [
{
"name" : "Add pet",
"id" : 1,
"resourceId" : 4,
"input" : {
"postData":"${input.petList[0]}"
},
"assertions" : [
{
"actualOutput" : "${output(2.1)}",
"condition" : "!=",
"expectedOutput" : "EXCEPTION"
}
]
},
{
"name" : "Find pet by id",
"id" : 2,
"resourceId" : 1,
"input" : {
"petId":"1"
},
"assertions" : [
{
"actualOutput" : "${output(2.2)}",
"condition" : "!=",
"expectedOutput" : "NULL"
}
]
},
{
"name" : "Find pet by status",
"id" : 3,
"resourceId" : 2,
"input" : {
"status":"available,sold,pending"
},
"assertions" : [
{
"actualOutput" : "${output(2.3).size}",
"condition" : ">",
"expectedOutput" : "0"
}
]
}
]
},
{
"id" : 3,
"name" : "Test Store service related APIs",
"testCases" : [
{
"name" : "Find order by id",
"id" : 1,
"resourceId" : 12,
"input" : {
"orderId":"1"
},
"assertions" : [
{
"actualOutput" : "${output(3.1)}",
"condition" : "!=",
"expectedOutput" : "NULL"
}
]
},
{
"name" : "Place order",
"id" : 2,
"resourceId" : 14,
"input" : {
"postData":"${input.orderList[0]}"
},
"assertions" : [
{
"actualOutput" : "${output(1.2)}",
"condition" : "!=",
"expectedOutput" : "EXCEPTION"
}
]
}
]
}
]
}

View File

@ -0,0 +1,146 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<application xmlns="http://ns.adobe.com/air/application/2.0">
<!-- Adobe AIR Application Descriptor File Template.
Specifies parameters for identifying, installing, and launching AIR applications.
xmlns - The Adobe AIR namespace: http://ns.adobe.com/air/application/2.0
The last segment of the namespace specifies the version
of the AIR runtime required for this application to run.
minimumPatchLevel - The minimum patch level of the AIR runtime required to run
the application. Optional.
-->
<!-- A universally unique application identifier. Must be unique across all AIR applications.
Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. -->
<id>AirExecutorApp</id>
<!-- Used as the filename for the application. Required. -->
<filename>AirExecutorApp</filename>
<!-- The name that is displayed in the AIR application installer.
May have multiple values for each language. See samples or xsd schema file. Optional. -->
<name>AirExecutorApp</name>
<!-- An application version designator (such as "v1", "2.5", or "Alpha 1"). Required. -->
<version>v1</version>
<!-- Description, displayed in the AIR application installer.
May have multiple values for each language. See samples or xsd schema file. Optional. -->
<!-- <description></description> -->
<!-- Copyright information. Optional -->
<!-- <copyright></copyright> -->
<!-- Publisher ID. Used if you're updating an application created prior to 1.5.3 -->
<!-- <publisherID></publisherID> -->
<!-- Settings for the application's initial window. Required. -->
<initialWindow>
<!-- The main SWF or HTML file of the application. Required. -->
<!-- Note: In Flash Builder, the SWF reference is set automatically. -->
<content>AirExecutorApp.swf</content>
<!-- The title of the main window. Optional. -->
<!-- <title></title> -->
<!-- The type of system chrome to use (either "standard" or "none"). Optional. Default standard. -->
<!-- <systemChrome></systemChrome> -->
<!-- Whether the window is transparent. Only applicable when systemChrome is none. Optional. Default false. -->
<!-- <transparent></transparent> -->
<!-- Whether the window is initially visible. Optional. Default false. -->
<!-- <visible></visible> -->
<!-- Whether the user can minimize the window. Optional. Default true. -->
<!-- <minimizable></minimizable> -->
<!-- Whether the user can maximize the window. Optional. Default true. -->
<!-- <maximizable></maximizable> -->
<!-- Whether the user can resize the window. Optional. Default true. -->
<!-- <resizable></resizable> -->
<!-- The window's initial width in pixels. Optional. -->
<!-- <width></width> -->
<!-- The window's initial height in pixels. Optional. -->
<!-- <height></height> -->
<!-- The window's initial x position. Optional. -->
<!-- <x></x> -->
<!-- The window's initial y position. Optional. -->
<!-- <y></y> -->
<!-- The window's minimum size, specified as a width/height pair in pixels, such as "400 200". Optional. -->
<!-- <minSize></minSize> -->
<!-- The window's initial maximum size, specified as a width/height pair in pixels, such as "1600 1200". Optional. -->
<!-- <maxSize></maxSize> -->
</initialWindow>
<!-- We recommend omitting the supportedProfiles element, -->
<!-- which in turn permits your application to be deployed to all -->
<!-- devices supported by AIR. If you wish to restrict deployment -->
<!-- (i.e., to only mobile devices) then add this element and list -->
<!-- only the profiles which your application does support. -->
<!-- <supportedProfiles>desktop extendedDesktop mobileDevice extendedMobileDevice</supportedProfiles> -->
<!-- The subpath of the standard default installation location to use. Optional. -->
<!-- <installFolder></installFolder> -->
<!-- The subpath of the Programs menu to use. (Ignored on operating systems without a Programs menu.) Optional. -->
<!-- <programMenuFolder></programMenuFolder> -->
<!-- The icon the system uses for the application. For at least one resolution,
specify the path to a PNG file included in the AIR package. Optional. -->
<!-- <icon>
<image16x16></image16x16>
<image32x32></image32x32>
<image48x48></image48x48>
<image128x128></image128x128>
</icon> -->
<!-- Whether the application handles the update when a user double-clicks an update version
of the AIR file (true), or the default AIR application installer handles the update (false).
Optional. Default false. -->
<!-- <customUpdateUI></customUpdateUI> -->
<!-- Whether the application can be launched when the user clicks a link in a web browser.
Optional. Default false. -->
<!-- <allowBrowserInvocation></allowBrowserInvocation> -->
<!-- Listing of file types for which the application can register. Optional. -->
<!-- <fileTypes> -->
<!-- Defines one file type. Optional. -->
<!-- <fileType> -->
<!-- The name that the system displays for the registered file type. Required. -->
<!-- <name></name> -->
<!-- The extension to register. Required. -->
<!-- <extension></extension> -->
<!-- The description of the file type. Optional. -->
<!-- <description></description> -->
<!-- The MIME content type. -->
<!-- <contentType></contentType> -->
<!-- The icon to display for the file type. Optional. -->
<!-- <icon>
<image16x16></image16x16>
<image32x32></image32x32>
<image48x48></image48x48>
<image128x128></image128x128>
</icon> -->
<!-- </fileType> -->
<!-- </fileTypes> -->
</application>

View File

@ -16,11 +16,15 @@ libpath = lib
# The Location of the output folder for your generated documents # The Location of the output folder for your generated documents
docsoutputfolder = asdoc docsoutputfolder = asdoc
# The location of the test sources
testsourcepath = ./test/main/as3
# Home directory for flex sdk 3, change this to build for Mac or PC using # as comment # Home directory for flex sdk 3, change this to build for Mac or PC using # as comment
# SDK_HOME = C:/Program Files/Adobe/Flash Builder 4/sdks/3.5.0 # SDK_HOME = C:/Program Files/Adobe/Flash Builder 4/sdks/3.5.0
# SDK_HOME = /Applications/Adobe Flash Builder 4/sdks/3.5.0 # SDK_HOME = /Applications/Adobe Flash Builder 4/sdks/3.5.0
# SDK_HOME = /usr/local/flex_sdk_4.1.0/ # SDK_HOME = /usr/local/flex_sdk_4.1.0/
# FLEX_HOME = /usr/local/flex_sdk_4.1.0/ # FLEX_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 # 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 = C:/Program Files/Adobe/Flash Builder 4/sdks/3.5.0/bin/asdoc.exe

View File

@ -5,11 +5,15 @@
<!-- import our build properties file --> <!-- import our build properties file -->
<property file="./build.properties"/> <property file="./build.properties"/>
<property environment="env"/> <property environment="env"/>
<property name="FLEX_HOME" value="${env.SDK_HOME}"/> <property name="FLEX_HOME" value="${FLEX4_SDK_HOME}"/>
<property name="FLEX4_HOME" value="${FLEX4_SDK_HOME}"/>
<!--<property name="flexunit.swc" value="../lib/ext/flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc" />
<property name="flexunit-uilistener.swc" value="../lib/ext/flexunit-uilistener-4.1.0_RC2-28-flex_3.5.0.12683.swc" />
<property name="flexunit-cilistener.swc" value="../lib/ext/flexunit-cilistener-4.1.0_RC2-28-flex_3.5.0.12683.swc" />-->
<!-- Flex Ant Tasks used to perform compc and mxml compiling more info at http://labs.adobe.com/wiki/index.php/Flex_Ant_Tasks --> <!-- Flex Ant Tasks used to perform compc and mxml compiling more info at http://labs.adobe.com/wiki/index.php/Flex_Ant_Tasks -->
<taskdef resource="flexTasks.tasks" classpath="${env.SDK_HOME}/ant/lib/flexTasks.jar"/> <taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar"/>
<target name="setup" description="perform an setup operations"/> <target name="setup" description="perform an setup operations"/>
@ -128,4 +132,51 @@
<zip destfile="sample-as3-sdk.zip" basedir="${basedir}/dist" /> <zip destfile="sample-as3-sdk.zip" basedir="${basedir}/dist" />
</target> </target>
<!-- Compiles and creates a test app that can be run using the adl - AIR Debug Launcher from command line
Note: For the output file to be executed an xml file is needed which points to this output swf - this is not
generated here
-->
<target name="compile-test" depends="buildSWC">
<property name="FLEX_HOME" value="${FLEX4_SDK_HOME}"/>
<mxmlc
static-rsls="false"
fork="true"
maxmemory="512m"
file="${testsourcepath}/AirExecutorApp.mxml"
output="${basedir}/${liboutputfolder}/AirExecutorApp.swf"
warnings="false"
configname="air"
locale="en_US">
<load-config filename="${FLEX4_HOME}/frameworks/air-config.xml"/>
<source-path path-element="${FLEX_HOME}/frameworks"/>
<compiler.debug>true</compiler.debug>
<source-path path-element="${testsourcepath}" />
<!--<source-path path-element="${APP_ROOT}/locale/{locale}" />-->
<library-path dir="${FLEX_HOME}/frameworks/libs" append="true">
<include name="*.swc" />
</library-path>
<library-path dir="${FLEX_HOME}/frameworks/libs/air" append="true">
<include name="*.swc" />
</library-path>
<library-path dir="${FLEX_HOME}/frameworks/locale" append="true">
<include name="{locale}" />
</library-path>
<library-path dir="${basedir}/${libpath}" append="true">
<include name="*.swc" />
</library-path>
<library-path dir="${basedir}/${liboutputfolder}" append="true">
<include name="*.swc" />
</library-path>
<library-path dir="${basedir}/${libpath}/ext" append="true">
<include name="*.swc" />
</library-path>
<verbose-stacktraces>true</verbose-stacktraces>
</mxmlc>
</target>
</project> </project>

Binary file not shown.

View File

@ -151,7 +151,21 @@ package com.wordnik.swagger.common
var context:ASAXBContext = ASAXBContext.newInstance(resultType); var context:ASAXBContext = ASAXBContext.newInstance(resultType);
var unmarshaller:Unmarshaller = context.createUnmarshaller(); var unmarshaller:Unmarshaller = context.createUnmarshaller();
var resultXML: XML = new XML(event.result); var resultXML: XML = new XML(event.result);
resultObject = unmarshaller.unmarshal(resultXML); 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); var response : Response = new Response(true, resultObject);

View File

@ -0,0 +1,9 @@
package com.wordnik.swagger.common
{
public interface ListWrapper
{
function getList(): Array;
}
}

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="runMe()" invoke="onInvoke(event)">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import org.flexunit.listeners.AirCIListener;
import org.flexunit.runner.FlexUnitCore;
import test.TestExecutor;
private var core: FlexUnitCore;
public function runMe(): void{
core = new FlexUnitCore();
core.addListener(new AirCIListener());
core.run(test.TestExecutor);
}
public function onInvoke(event: InvokeEvent): void{
var arguments: Array = event.arguments;
trace(arguments.toString());
}
]]>
</fx:Script>
</s:WindowedApplication>

View File

@ -0,0 +1,432 @@
package test
{
import com.adobe.serialization.json.JSON;
import com.adobe.utils.DateUtil;
import com.wordnik.swagger.common.ApiInvoker;
import com.wordnik.swagger.common.ApiUserCredentials;
import com.wordnik.swagger.common.SwaggerApi;
import com.wordnik.swagger.event.ApiClientEvent;
import com.wordnik.swagger.event.Response;
import flash.desktop.NativeApplication;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.events.IOErrorEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.system.System;
import flash.utils.describeType;
import flash.utils.getDefinitionByName;
import flexunit.framework.TestCase;
import mx.core.ClassFactory;
import mx.rpc.events.FaultEvent;
import mx.utils.StringUtil;
public class TestExecutor extends TestCase
{
private var urlReq:URLRequest;
private var urlLdr:URLLoader;
private var apiInvoker: ApiInvoker;
private const MODEL_INFO_URL:String ="testData.json";
private const TIME_OUT:int = 5000;
private var testData: Object;
public function testApiMethod():void{
initializeRequest();
urlLdr.addEventListener(Event.COMPLETE, addAsync(executeTest, TIME_OUT));
urlLdr.addEventListener(IOErrorEvent.IO_ERROR, executeTest);
urlLdr.load(urlReq);
}
private function initializeRequest():void {
/* Initialize the URLRequest object with the URL to the file of name/value pairs. */
urlReq = new URLRequest(MODEL_INFO_URL);
/* Initialize the URLLoader object, assign the various event listeners, and load the specified URLRequest object. */
urlLdr = new URLLoader();
}
private function checkAndLoadModelXml(event:Event):Object {
var ldr:URLLoader = urlLdr;//event.currentTarget as URLLoader;
assertTrue("Test data info not found ", ldr.data != null);
var testData:Object = JSON.decode(ldr.data);
//var classList:XML = new XML(ldr.data);
assertTrue("Test data could not be loaded as xml ", testData != null);
return testData;
}
private function executeTest(event:Event):void {
testData = checkAndLoadModelXml(event);
//figure out class and method to execute
var className: String = getServiceName(testData.resource);
var methodName: String = testData.methodName;
var servicePackageName: String = testData.apiPackageName;
var fullClassName: String = servicePackageName + "." + className;
var apiUrl: String = testData.apiUrl;
var apiHostName : String = apiUrl.substring(apiUrl.indexOf("//")+2,
apiUrl.indexOf("/",apiUrl.indexOf("//")+2) );
var apiPath: String = apiUrl.substring(apiUrl.indexOf(apiHostName)+ apiHostName.length,
apiUrl.indexOf("/", apiUrl.indexOf(apiHostName)+ apiHostName.length + 1));
var useProxyServer: Boolean = false;
if(testData.useProxyServer != null){
useProxyServer = testData.useProxyServer == "true" ? true : false;
}
var params: Array;
//execute the test
var classRef:Class;
try{
classRef = getDefinitionByName(fullClassName) as Class;
}
catch(error: ReferenceError){
var classFailure: Response = new Response(false, null, "Api Class not found");
writeToFile( JSON.encode(classFailure) );
}
var apiCredentials: ApiUserCredentials = new ApiUserCredentials(testData.apiKey,
testData.authToken, apiHostName, -1, apiPath, testData.proxyServerUrl);
var apiInstance : * = new classRef(apiCredentials);
apiInstance.useProxyServer(useProxyServer);
apiInstance.addEventListener(methodName, addAsync(onApiCallResponse, TIME_OUT, {} , apiTimeOutHandler) );
apiInstance.addEventListener(ApiClientEvent.FAILURE_EVENT, onApiCallFault );
var queryAndPathParams: Object = new Object();
queryAndPathParams = testData.queryAndPathParams;
params = getArgumentsForTestCaseExecution(methodName, apiInstance,
queryAndPathParams, testData.postData, className, testData.resource);
if(apiInstance.hasOwnProperty(methodName)){
var method:Function = apiInstance[methodName];
var returnValue:* = method.apply(apiInstance, params);
}
else{
//write out error
var failureResponse: Response = new Response(false, null, "Method not found");
writeToFile( JSON.encode(failureResponse) );
}
//write out test data result to json file
}
private function onApiCallResponse(event: ApiClientEvent, tokenObject: Object = null): void{
var result: Response = event.response;
trace("writing to file");
writeToFile( JSON.encode(result) );
}
private function onApiCallFault(event:FaultEvent):void {
var failureResponse: Response = new Response(false, null, "Method invocation failure");
writeToFile( JSON.encode(failureResponse) );
}
private function writeToFile(data: String) : void {
var localFile: File = File.documentsDirectory.resolvePath("testOutput.json");
var localFileStream:FileStream = new FileStream();
localFileStream.open(localFile, FileMode.WRITE);
localFileStream.writeMultiByte( data, "utf-8");
localFileStream.close();
trace(data);
applicationExit();
}
private function apiTimeOutHandler(o: Object):void {
//fail("test timed out");
trace("Execution timed out");
var failureResponse: Response = new Response(false, null, "Method Execution timed out");
writeToFile( JSON.encode(failureResponse) );
}
/**
* Generate name of the service from resource path.
*
* Example: if input is /user.json the generated name for this path will be UserAPI
* If the input is /user.json/{userId}, the service name will still be generated as UserAPI
*
* @param resourcePath
* @return
*/
private function getServiceName(resourcePath: String): String {
var className:String = null;
var index: int = resourcePath.indexOf(".");
if(index >= 0) {
var resourceName: String = resourcePath.substring(1,index);
className = applyClassNamingPolicy(resourceName);
}else{
var paths: Array = resourcePath.split("/");
for each(var path: String in paths) {
if(path != null && path.length > 0) {
className = applyClassNamingPolicy(path);
break;
}
}
}
return className+ "API";
}
private function getArgumentsForTestCaseExecution(methodName: String, apiObject: Object, queryAndPathParameters: Object,
postData: String, className: String, resourcePath: String): Array{
var result: Array;
//get the xml data for the type
var classAsXML: XML = describeType(apiObject);
//get the parameters for the method
var argNamesArray: Array = [];
var argTypesArray: Array = [];
var list: XMLList = classAsXML.method;
var methodXml: XML;
var paramDefn: XML
var currentMethodName: String;
var methodParams: XMLList;
var methodArgumentNames: XMLList;
var argumentNames: String;
for each (methodXml in list) {
//get the names and types for the parameters
currentMethodName = methodXml.@name.toString();
if(methodName == currentMethodName){
methodParams = methodXml.parameter;
for each(paramDefn in methodParams){
argTypesArray.push(paramDefn.@type.toString());
}
methodArgumentNames = methodXml.metadata.(@name == "MethodArgumentNames");
if(methodArgumentNames.length() > 0){
argumentNames = methodArgumentNames.arg[0].@value.toString();
argNamesArray = argNamesArray.concat(argumentNames.split(","));
}
break;
}
}
if(argNamesArray != null && argNamesArray.length > 0){
result = [];
//get the value of the input type parameter
var inputClassName: String = getInputObjectName(className, resourcePath);
var argName: String;
var argType: String;
var argumentValue: Object;
for (var i: Number=0 ; i< argNamesArray.length ; i++){
argName = StringUtil.trim( argNamesArray[i].toString() );
argType = argTypesArray[i].toString();
//if the parameter type is of collated input type
if(argType == inputClassName){
//create an object of type input model and populate it
argumentValue = populateInputModelObject(argTypesArray[i], queryAndPathParameters);
}
//if it is a primitive type then
else if( isPrimitiveType(argType) ){
//get the value from the queryAndPathParameters
argumentValue = queryAndPathParameters[argName] ;
}
//if it is a POST param
else if( argName == "postData"){
//convert from JSON to object ? of type ?
if(postData.charAt(0) == "\"" && postData.charAt(postData.length - 1) == "\""){
postData = postData.slice(1, postData.length);
}
argumentValue = JSON.decode( postData.toString() );
argumentValue = mapToFlexObjects(argumentValue, argType);
}
else if(true){
//???some times input can be list of primitives for supporting multivalued values. however test case sends the input as comma separated values
//???so we need to convert comma separated string into JSON list format
argumentValue = queryAndPathParameters[argName].toString().split(",");
}
result.push(argumentValue);
}
}
return result;
}
/**
* Converts an instance of type 'Object' to a type of 'argType'
*/
private function mapToFlexObjects(obj:Object, argType: String):Object {
var fullClassName: String = argType.replace("::",".");
var classRef:Class;
try{
classRef = getDefinitionByName(fullClassName) as Class;
}
catch(error: ReferenceError){
var classFailure: Response = new Response(false, null, "Api Class not found");
writeToFile( JSON.encode(classFailure) );
}
var returnObject : * = new classRef();
var propertyMap:XML = describeType(returnObject);
var propertyTypeClass:Class;
for each (var property:XML in propertyMap.variable) {
if ((obj as Object).hasOwnProperty(property.@name)) {
propertyTypeClass = getDefinitionByName(property.@type) as Class;
if (obj[property.@name] is (propertyTypeClass)) {
returnObject[property.@name] = obj[property.@name];
}
if(property.@type == "Date"){
var dateValue:Date = DateUtil.parseW3CDTF( obj[property.@name] );
returnObject[property.@name] = dateValue;
}
if( !isPrimitiveType( property.@type )){
try{
var complexTypeObject: Object = mapToFlexObjects( obj[property.@name], property.@type );
returnObject[property.@name] = complexTypeObject;
}
catch(error: Error){
var mapToFlexFailure: Response = new Response(false, null, "Post data object could not be created");
writeToFile( JSON.encode(mapToFlexFailure) );
}
}
}
}
return returnObject;
}
private function isPrimitiveType(type: String): Boolean {
if(type == "String" || type == "int" || type == "integer" || type == "double" ||
type == "boolean" || type == "float" || type == "long" || type == "Number" ){
return true;
}
return false;
}
/**
* Converts the first character of the input into upper case .
* Example: If the input is word, the return value will be Word
* @param input
* @return
*/
private function applyClassNamingPolicy(input: String): String {
if(input != null && input.length > 0) {
return input.substring(0,1).toUpperCase() + input.substring(1);
}else{
throw new Error("Error converting input to first letter caps becuase of null or empty input");
}
}
private function getInputObjectName(serviceName: String, resourcePath: String): String {
//Since service name has API at the end remove that format he name
var inputobjectName: String = serviceName.substring(0, serviceName.length - 3);
var pathElements: Array = resourcePath.split("/");
var urlPath: String = "";
if(pathElements != null){
for each(var pathElement: String in pathElements){
if(pathElement != null && pathElement.length > 0) {
var position: int = pathElement.indexOf("{");
if(position < 0) {
inputobjectName = inputobjectName + applyClassNamingPolicy( pathElement ) + "Input";
}
}
}
}
return inputobjectName;
}
/**
* Populates the swagger input model object.
*
* Input model is created when number of inputs to a method exceed certain limit.
* @param inputDefinitions
* @return
*/
private function populateInputModelObject(swaggerInputClassName: String, inputDefinitions: Object): Object {
var inputModelObjectClass: Class = getDefinitionByName(swaggerInputClassName) as Class;
var inputObject: Object = new inputModelObjectClass();
for(var attributeName: String in inputDefinitions){
if(inputObject.hasOwnProperty(attributeName)){
inputObject[attributeName] = inputDefinitions[attributeName];
}
}
return inputObject;
}
public function applicationExit():void {
var exitingEvent:Event = new Event(Event.EXITING, false, true);
NativeApplication.nativeApplication.dispatchEvent(exitingEvent);
if (!exitingEvent.isDefaultPrevented()) {
NativeApplication.nativeApplication.exit();
}
}
// /**
// * Gets the list of input query and path parameters and post data vlues and covenrt them to arguments that
// * can be used for calling the method. This logic will be different in each driver language depends on how method
// * input arguments are created.
// */
// private function populateArgumentsForTestCaseExecution(methodToExecute: Function, queryAndPathParameters: Object,
// postData: String, serviceName: String, resourcePath: String): Array {
// MethodArgumentNames argNames = methodToExecute.getAnnotation(MethodArgumentNames.class);
// String[] argNamesArray = null;
// if(argNames != null && argNames.value().length() > 0) {
// argNamesArray = argNames.value().split(",");
// }
// Class[] argTypesArray = methodToExecute.getParameterTypes();
// Object output = null;
// String inputClassName = namingPolicyProvider.getInputObjectName(serviceName, resourcePath);
//
// if(argNamesArray != null && argNamesArray.length > 0){
// Object[] arguments = new Object[argNamesArray.length];
//
// for(int i=0; i < argNamesArray.length; i++){
// Object argument = null;
// //if the method takes input model instead of individual arguments, convert individual arguments into input model object
// if(argTypesArray[i].getName().equalsIgnoreCase(inputClassName)){
// argument = populateInputModelObject(argTypesArray[i], queryAndPathParameters);
// }else if(datatypeMppingProvider.isPrimitiveType(argTypesArray[i].getName())){
// argument = queryAndPathParameters.get(argNamesArray[i].trim());
// }else if (argNamesArray[i].trim().equals(APITestRunner.POST_PARAM_NAME)){
// argument = APITestRunner.convertJSONStringToObject(postData, argTypesArray[i]);
// }else{
// //some times input can be list of primitives for supporting multivalued values. however test case sends the input as comma separated values
// //so we need to convert comma separated string into JSON list format
// if(List.class.isAssignableFrom(argTypesArray[i]) && !queryAndPathParameters.get(argNamesArray[i].trim()).startsWith("[")){
// String listInput= "[";
// int x = 0;
// String[] values = queryAndPathParameters.get(argNamesArray[i].trim()).split(",");
// for(String value : values){
// if(x > 0){listInput = listInput + ",";}
// listInput = listInput + "\""+ value + "\"";
// x++;
// }
// listInput = listInput + "]";
// argument = APITestRunner.convertJSONStringToObject(listInput, argTypesArray[i]);
// }else{
// argument = APITestRunner.convertJSONStringToObject(queryAndPathParameters.get(argNamesArray[i].trim()), argTypesArray[i]);
// }
// }
// arguments[i] = argument;
// }
// return arguments;
// }
// return null;
// }
}
}

View File

@ -1,5 +1,7 @@
package $packageName$ { package $packageName$ {
import com.wordnik.swagger.api.*;
$imports:{ import | $imports:{ import |
import $import$; import $import$;
}$ }$

View File

@ -1,5 +1,6 @@
package $packageName$ { package $packageName$ {
import com.wordnik.swagger.common.ListWrapper;
$imports:{ import | $imports:{ import |
import $import$; import $import$;
}$ }$
@ -10,10 +11,9 @@ import $import$;
* @author deepak * @author deepak
* *
*/ */
public class $className$ extends $extends$ { public class $className$ extends $extends$ implements ListWrapper{
$fields:{ field | $fields:{ field |
/** /**
* $field.description$ * $field.description$
* $if(field.required)$@Required$endif$ * $if(field.required)$@Required$endif$
@ -23,7 +23,15 @@ $if(!field.fieldDefinition.collectionItemType)$
[XmlElement(name="$field.fieldDefinition.name$")]$endif$ [XmlElement(name="$field.fieldDefinition.name$")]$endif$
$if(field.fieldDefinition.collectionItemType)$ $if(field.fieldDefinition.collectionItemType)$
[XmlElements(name="$field.fieldDefinition.collectionItemName$", type="$field.fieldDefinition.collectionItemType$")]$endif$ [XmlElements(name="$field.fieldDefinition.collectionItemName$", type="$field.fieldDefinition.collectionItemType$")]$endif$
public var $field.fieldDefinition.name$: $field.fieldDefinition.returnType$ $field.fieldDefinition.initialization$;$\r$}$ public var $field.fieldDefinition.name$: $field.fieldDefinition.returnType$ $field.fieldDefinition.initialization$;}$
$fields:{ field |
/**
* Returns the list being wrapped by this wrapper class. There will be a single list item attribute in this class.
*/
$if(field.fieldDefinition.collectionItemType)$
public function getList(): $field.fieldDefinition.returnType${
return $field.fieldDefinition.name$;
}$endif$}$
} }
} }

View File

@ -0,0 +1,27 @@
{
"apiUrl":"http://localhost:8002/api/",
"apiKey":"special-key",
"defaultServiceBaseClass":"SwaggerApi",
"defaultModelBaseClass":"Object",
"serviceBaseClasses":{},
"defaultModelImports":[],
"defaultServiceImports":[],
"modelPackageName":"",
"apiPackageName":"",
"ignoreMethods":[],
"ignoreModels":[],
"outputDirectory":"../swagger-sample-app/sdk-libs/src/main/js/",
"libraryHome":"../swagger-sample-app/sdk-libs"
}

View File

@ -0,0 +1,73 @@
<!DOCTYPE html>
<html>
<head>
<title>Swagger Javascript Lib Sandbox</title>
<script src="src/main/js/lib/jquery-1.6.4.min.js" type="text/javascript" charset="utf-8"></script>
<script src="src/main/js/api-lib.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
function log(s) {
if(window.console) console.log(s);
}
function logResponse(event) {
log("-----------------------------");
log(event.type);
log(event);
}
function onUserCreated(event) {
logResponse(event);
// update the created user
var user = new User();
user.lastName = "Sanders Lama";
user.username = "vito";
user.phone = "405-607-8980";
user.email = "vito@sanders.com";
user.userStatus = 1;
user.firstName = "Vito";
user.password = "XXXXX";
UserAPI.updateUser("vito", user);
}
function onUserUpdated(event) {
logResponse(event);
// delete the created user
UserAPI.deleteUser("vito");
}
ApiInvoker.init("http://localhost:8002/api/", false);
ApiInvoker.addListener(PetAPI.event_getPetById, logResponse);
ApiInvoker.addListener(StoreAPI.event_getOrderById, logResponse);
ApiInvoker.addListener(UserAPI.event_getUserByName, logResponse);
ApiInvoker.addListener(UserAPI.event_loginUser, logResponse);
ApiInvoker.addListener(UserAPI.event_createUser, onUserCreated);
ApiInvoker.addListener(UserAPI.event_updateUser, onUserUpdated);
ApiInvoker.addListener(UserAPI.event_deleteUser, logResponse);
// Get some data
StoreAPI.getOrderById("1");
PetAPI.getPetById("1");
UserAPI.getUserByName("user1");
// login
UserAPI.loginUser("user1", "XXXXXXXXXXX")
// create new user
var user = new User();
user.lastName = "Sanders";
user.username = "vito";
user.phone = "405-607-8980";
user.email = "vito@sanders.com";
user.userStatus = 1;
user.firstName = "Vito";
user.password = "XXXXX";
UserAPI.createUser(user);
</script>
<body>
</body>

View File

@ -0,0 +1,203 @@
var ApiInvoker = new function() {
this.apiServer = null,
this.loggingEnabled = false,
this.trace = function(obj) {
if (this.loggingEnabled && window.console) console.log(obj);
},
this.init = function(apiServer, loggingEnabled) {
if (apiServer != null && apiServer.length > 0) {
if (apiServer.substring(apiServer.length - 1) == ("/")) {
apiServer = apiServer.substring(0, apiServer.length - 1);
}
this.apiServer = apiServer;
this.loggingEnabled = (loggingEnabled === null) ? false : loggingEnabled;
}
},
this.invokeAPI = function(authToken, resourceURL, method, queryParams, postObject, completionEvent, requestId, returnType, callback) {
if (this.apiServer == null) {
throw new Error("Please call ApiInvoker.init() to initialize the library");
}
this.trace("authToken = " + authToken);
this.trace("resourceURL = " + resourceURL);
this.trace("method = " + method);
// this.trace("returnType = " + returnType);
this.trace("completionEvent = " + completionEvent);
this.trace("requestId = " + requestId);
this.trace("queryParams:");
this.trace(queryParams);
this.trace("postObject:");
this.trace(postObject);
// create queryParam
var counter = 0;
var symbol = 0;
for (var paramName in queryParams) {
var paramValue = queryParams[paramName];
symbol = "&";
if (counter == 0) {
symbol = "?";
}
resourceURL = resourceURL + symbol + paramName + "=" + paramValue.toString();
counter++;
}
var callURL = this.apiServer + resourceURL;
var responseDataType = (returnType === null || returnType == String) ? "html" : "json";
this.trace("callURL = " + callURL);
this.trace("responseDataType = " + responseDataType);
if (method == "GET") {
$.get(callURL, postObject,
function(response) {
ApiInvoker.fire(completionEvent, returnType, requestId, response, callback);
}, responseDataType).complete(this.showCompleteStatus).error(this.showErrorStatus);
// $.getJSON(callURL,
// function(response) {
// ApiInvoker.fire(completionEvent, returnType, requestId, response);
// }).complete(this.showCompleteStatus).error(this.showErrorStatus);
} else if (method == "POST") {
this.trace("sending post");
this.trace(JSON.stringify(postObject));
$.ajax({
url: callURL,
data: JSON.stringify(postObject),
type: "POST",
dataType: "json",
contentType: "application/json",
success: function(response) {
ApiInvoker.fire(completionEvent, returnType, requestId, response, callback);
}
}).complete(this.showCompleteStatus).error(this.showErrorStatus);
} else if (method == "PUT") {
$.ajax({
url: callURL,
data: JSON.stringify(postObject),
type: "PUT",
dataType: "json",
contentType: "application/json",
success: function(response) {
ApiInvoker.fire(completionEvent, returnType, requestId, response, callback);
}
}).complete(this.showCompleteStatus).error(this.showErrorStatus);
} else if (method == "DELETE") {
$.ajax({
url: callURL,
data: JSON.stringify(postObject),
type: "DELETE",
dataType: "json",
contentType: "application/json",
success: function(response) {
ApiInvoker.fire(completionEvent, returnType, requestId, response, callback);
}
}).complete(this.showCompleteStatus).error(this.showErrorStatus);
}
},
this.guid = function() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,
function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
}).toUpperCase();
},
this._listeners = {},
this.addListener = function(type, listener) {
if (!this._listeners[type]) {
this._listeners[type] = [];
}
this._listeners[type].push(listener);
},
this.fire = function(completionEvent, returnType, requestId, response, callback) {
var event = new Object();
event.type = completionEvent;
event.requestId = requestId;
if (returnType === null || returnType == String) {
event.data = response;
} else {
event.data = eval("new " + returnType);
event.data.parse(response);
}
if (typeof event == "string") {
event = { type: event };
}
if (!event.target) {
event.target = this;
}
if (!event.type) {
throw new Error("Event object must have 'type' property");
}
this.trace(event.data);
if(callback) {
this.trace("invoking callback");
callback(event);
} else {
this.trace("firing event " + event.type);
if (this._listeners[event.type]) {
var listeners = this._listeners[event.type];
for (var i = 0; i < listeners.length; i++) {
listeners[i].call(this, event);
}
}
}
},
this.removeListener = function(type, listener) {
if (this._listeners[type]) {
var listeners = this._listeners[type];
for (var i = 0; i < listeners.length; i++) {
if (listeners[i] === listener) {
listeners.splice(i, 1);
break;
}
}
}
},
this.showErrorStatus = function(data) {
ApiInvoker.trace(data);
if (data.status != 200)
ApiInvoker.trace(data.status);
ApiInvoker.showStatus(data);
},
this.showCompleteStatus = function(data) {
ApiInvoker.trace("complete " + data.status);
// ApiInvoker.showStatus(data);
},
this.showStatus = function(data) {
ApiInvoker.trace(data);
ApiInvoker.trace(data.getAllResponseHeaders());
},
this.toPathValue = function(value) {
if(typeof value == Array){
return this.arrayToPathValue(value);
} else
return value == null ? "" : value.toString();
},
this.arrayToPathValue = function(objects) {
return objects.join(",");
}
};

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,30 @@
package $packageName$;
$imports:{ import |
import $import$;
}$
/**
* $enum.description$
* NOTE: This class is auto generated by the drive code generator program so please do not edit the class manually.
* @author deepak
*
*/
public enum $className$ {
$values: { value | $value.name$($value.value$)};separator=", "$;
final $enumValueType$ value;
$className$($enumValueType$ value) {
this.value = value;
}
public $enumValueType$ getValue() {
return value;
}
@Override public String toString() {
return String.valueOf(this.getValue());
}
};

View File

@ -0,0 +1,65 @@
/**
* $model.description$
*/
function $className$() {
$fields:{ field |
/**
* $field.description$
* $if(field.required)$@Required$endif$
* $if(field.allowableValues)$[AllowableValues(value="$field.allowedValuesString$"]$endif$
*/
this.$field.fieldDefinition.name$ = null;$\r$}$
this.parse = function(data) {
if(data) {
$fields:{ field |
$! //$field.fieldDefinition.returnType$ (primitive=$field.fieldDefinition.hasPrimitiveType$) !$
$if(field.fieldDefinition.hasListResponse)$
$if(field.fieldDefinition.hasPrimitiveType)$
this.$field.fieldDefinition.name$ = data.$field.fieldDefinition.name$;
$else$
this.$field.fieldDefinition.name$ = $field.fieldDefinition.collectionItemType$Object.parseArray(data.$field.fieldDefinition.name$);
$endif$
$elseif(field.fieldDefinition.hasSetResponse)$
$if(field.fieldDefinition.hasPrimitiveType)$
this.$field.fieldDefinition.name$ = data.$field.fieldDefinition.name$;
$else$
this.$field.fieldDefinition.name$ = $field.fieldDefinition.collectionItemType$Collection.get(data.$field.fieldDefinition.name$);
$endif$
$elseif(field.fieldDefinition.hasMapResponse)$
this.$field.fieldDefinition.name$ = data.$field.fieldDefinition.name$;
$elseif(field.fieldDefinition.hasDateResponse)$
this.$field.fieldDefinition.name$ = new Date(Date.parse(data.$field.fieldDefinition.name$));
$else$
$if(field.fieldDefinition.hasPrimitiveType)$
this.$field.fieldDefinition.name$ = data.$field.fieldDefinition.name$;
$else$
this.$field.fieldDefinition.name$ = new $field.fieldDefinition.returnType$(); this.$field.fieldDefinition.name$.parse(data.$field.fieldDefinition.name$);
$endif$
$endif$
}$
}
}
}
var $className$Object = new function() {
this.parseArray = function(arrayData) {
var responseArray = new Array();
if(arrayData != null && arrayData.length > 0) {
for(i = 0; i < arrayData.length; i++) {
var o = new $className$();
o.parse(arrayData[i]);
responseArray.push(o);
}
}
return responseArray;
}
}

View File

@ -0,0 +1,101 @@
/**
* NOTE: This class is auto generated by the drive code generator program so please do not edit the class manually.
*/
var $resource$ = new function() {
$methods:{ method |
this.event_$method.name$ = "$resource$.$method.name$";$\r$}$
// /**
// * Constructor for the $resource$ api client
// * @param apiCredentials Wrapper object for tokens and hostName required towards authentication
// * @param eventDispatcher Optional event dispatcher that when provided is used by the SDK to dispatch any Response
// */
// public function $resource$(apiCredentials: ApiUserCredentials, eventDispatcher: EventDispatcher = null) {
// super(apiCredentials, eventDispatcher);
// }
$methods:{ method |
/**
* $method.description$
$method.arguments:{ argument |
* @param $argument.name$ $argument.description$
$if(argument.allowedValues)$
* Allowed values are - $argument.allowedValues$
$endif$}$
*
$if(!method.responseVoid)$
* @return $method.returnValue$ {@link $method.returnClassName$} $endif$
* $if(method.hasArguments)$ $length(method.argumentNames)$ $endif$
*/
$if(method.hasArguments)$
this.$method.name$ = function($method.argumentNames; separator=", "$, callback)
$else$
this.$method.name$ = function(callback)
$endif$ {
$if(method.authToken)$
if(authToken == null || authToken.length == 0) {
throw new Error(ApiErrorCodes.AUTH_TOKEN_NOT_VALID);
}$endif$
var requestId = ApiInvoker.guid();
//parse inputs
var resourcePath = "$method.resourcePath$";
resourcePath = resourcePath.replace("{format}","json");
var method = "$method.methodType$";
var queryParams = new Object();
$if(!method.inputModel)$
$method.queryParameters:{ argument |
if( $argument.name$ != null) {
queryParams["$argument.name$"] = ApiInvoker.toPathValue($argument.name$);
}
}$
$method.pathParameters:{ argument |
if( $argument.name$ != null) {
resourcePath = resourcePath.replace("{$argument.name$}", $argument.name$);
}
}$
$endif$
$if(method.inputModel)$
$method.queryParameters:{ argument |
if( $argument.inputModelClassArgument$ != null && $argument.methodNameFromModelClass$ != null) {
queryParams["$argument.name$"] = $argument.methodNameFromModelClass$;
}
}$
$method.pathParameters:{ argument |
if( $argument.inputModelClassArgument$ != null && $argument.methodNameFromModelClass$ != null) {
resourcePath = resourcePath.replace("{$argument.name$}", $argument.methodNameFromModelClass$);
}
}$
$endif$
//make the API Call
var eventName = "$resource$.$method.name$";
var returnType = null;
$if(!method.responseVoid)$
returnType = $method.returnClassName$;
$endif$
$if(method.postObject)$
$if(method.authToken)$
ApiInvoker.invokeAPI(authToken, resourcePath, method, queryParams, postData, eventName, requestId, returnType, callback);
$endif$
$if(!method.authToken)$
ApiInvoker.invokeAPI(null, resourcePath, method, queryParams, postData, eventName, requestId, returnType, callback);
$endif$
$endif$
$if(!method.postObject)$
$if(method.authToken)$
ApiInvoker.invokeAPI(authToken, resourcePath, method, queryParams, null, eventName, requestId, returnType, callback);
$endif$
$if(!method.authToken)$
ApiInvoker.invokeAPI(null, resourcePath, method, queryParams, null, eventName, requestId, returnType, callback);
$endif$
$endif$
return requestId;
}
}$
}

View File

@ -0,0 +1,8 @@
/**
* Maintains the compatible server version against which the drive is written
*
*/
var VersionChecker = new function() {
this.compatibleVersion = "$apiVersion$";
}

View File

@ -0,0 +1,25 @@
/**
* $model.description$
* NOTE: This class is auto generated by the drive code generator program so please do not edit the class manually.
* @author deepak
*
*/
function $className$() {
$fields:{ field |
/**
* $field.description$
* $if(field.required)$@Required$endif$
* $if(field.allowableValues)$[AllowableValues(value="$field.allowedValuesString$"]$endif$
*/
this.$field.fieldDefinition.name$ $field.fieldDefinition.initialization$;}$
$fields:{ field |
/**
* Returns the list being wrapped by this wrapper class. There will be a single list item attribute in this class.
*/
$if(field.fieldDefinition.collectionItemType)$
this.getList = function() {
return this.$field.fieldDefinition.name$;
}$endif$}$
}

View File

@ -30,8 +30,10 @@ public class FieldDefinition {
private boolean hasListResponse; private boolean hasListResponse;
private boolean hasMapResponse; private boolean hasMapResponse;
private boolean hasSetResponse; private boolean hasSetResponse;
private boolean hasDateResponse;
private boolean hasPrimitiveType;
public boolean isHasListResponse() { public boolean isHasListResponse() {
return hasListResponse; return hasListResponse;
} }
@ -56,7 +58,15 @@ public class FieldDefinition {
this.hasSetResponse = hasSetResponse; this.hasSetResponse = hasSetResponse;
} }
public String getReturnType() { public boolean isHasPrimitiveType() {
return hasPrimitiveType;
}
public void setHasPrimitiveType(boolean hasPrimitiveType) {
this.hasPrimitiveType = hasPrimitiveType;
}
public String getReturnType() {
return returnType; return returnType;
} }
@ -110,4 +120,12 @@ public class FieldDefinition {
public void setCollectionItemName(String collectionItemName) { public void setCollectionItemName(String collectionItemName) {
this.collectionItemName = collectionItemName; this.collectionItemName = collectionItemName;
} }
public boolean isHasDateResponse() {
return hasDateResponse;
}
public void setHasDateResponse(boolean hasDateResponse) {
this.hasDateResponse = hasDateResponse;
}
} }

View File

@ -117,6 +117,11 @@ public class As3LibCodeGen extends LibraryCodeGenerator{
} }
} }
} }
refModelField = new ModelField();
refModelField.setName( nameGenerator.applyMethodNamingPolicy( resource.generateClassName(nameGenerator) ) );
refModelField.setParamType( resource.generateClassName(nameGenerator) );
refFields.add(refModelField);
} }
List<String> imports = new ArrayList<String>(); List<String> imports = new ArrayList<String>();
imports.addAll(this.config.getDefaultModelImports()); imports.addAll(this.config.getDefaultModelImports());

View File

@ -0,0 +1,188 @@
package com.wordnik.swagger.codegen.config.js;
import com.wordnik.swagger.codegen.config.DataTypeMappingProvider;
import com.wordnik.swagger.codegen.config.NamingPolicyProvider;
import com.wordnik.swagger.codegen.config.common.CamelCaseNamingPolicyProvider;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* User: ramesh
* Date: 5/31/11
* Time: 7:03 AM
*/
public class JSDataTypeMappingProvider implements DataTypeMappingProvider {
public static Map<String, String> primitiveValueMap = new HashMap<String, String>();
static{
primitiveValueMap.put("string", "String");
primitiveValueMap.put("String", "String");
primitiveValueMap.put("int", "Number");
primitiveValueMap.put("integer", "Number");
primitiveValueMap.put("Integer", "Number");
primitiveValueMap.put("boolean", "Boolean");
primitiveValueMap.put("Boolean", "Boolean");
primitiveValueMap.put("long", "Number");
primitiveValueMap.put("Long", "Number");
primitiveValueMap.put("double", "Number");
primitiveValueMap.put("Double", "Number");
primitiveValueMap.put("float", "Number");
primitiveValueMap.put("Float", "Number");
primitiveValueMap.put("Date", "Date");
primitiveValueMap.put("date", "Date");
}
public static Map<String, String> primitiveObjectMap = new HashMap<String, String>();
static{
primitiveObjectMap.put("string", "String");
primitiveObjectMap.put("String", "String");
primitiveObjectMap.put("int", "Number");
primitiveObjectMap.put("integer", "Number");
primitiveObjectMap.put("Integer", "Number");
primitiveObjectMap.put("boolean", "Boolean");
primitiveObjectMap.put("Boolean", "Boolean");
primitiveObjectMap.put("long", "Number");
primitiveObjectMap.put("Long", "Number");
primitiveObjectMap.put("double", "Number");
primitiveObjectMap.put("Double", "Number");
primitiveObjectMap.put("float", "Number");
primitiveObjectMap.put("Float", "Number");
primitiveObjectMap.put("Date", "Date");
primitiveObjectMap.put("date", "Date");
}
private NamingPolicyProvider nameGenerator = new CamelCaseNamingPolicyProvider();
public boolean isPrimitiveType(String type) {
if(type.equalsIgnoreCase("String") || type.equalsIgnoreCase("int") || type.equalsIgnoreCase("integer") || type.equalsIgnoreCase("double") ||
type.equalsIgnoreCase("boolean") || type.equalsIgnoreCase("float")|| type.equalsIgnoreCase("long") || type.equalsIgnoreCase("Number") ){
return true;
}
return false;
}
/**
* If the data type is primitive and it is expecting object structure then return primitive objects
* else return primitive types
* @param type
* @param primitiveObject -- indicates if the object is primitive or not
* @return
*/
public String getObjectType(String type, boolean primitiveObject) {
if(isPrimitiveType(type)){
if(primitiveObject){
return primitiveObjectMap.get(type);
}else{
return primitiveValueMap.get(type);
}
}else{
return nameGenerator.applyClassNamingPolicy(type);
}
}
public String getListReturnTypeSignature(String typeClass) {
return "Array";
}
public String getReturnTypeForVoidMethods() {
return "void";
}
public String getMapReturnTypeSignature(String typeClass) {
return "Object";
}
public String getSetReturnTypeSignature(String typeClass) {
return "Array";
}
public String generateListInitialization(String typeClass) {
return " new Array()";
}
public String generateMapInitialization(String typeClass) {
return " new Object()";
}
public String generateSetInitialization(String typeClass) {
return " new Array()";
}
public List<String> getListIncludes() {
List<String> imports = new ArrayList<String>();
return imports;
}
public List<String> getMapIncludes() {
List<String> imports = new ArrayList<String>();
return imports;
}
public List<String> getSetIncludes() {
List<String> imports = new ArrayList<String>();
return imports; }
public List<String> getDateIncludes() {
List<String> imports = new ArrayList<String>();
return imports;
}
/**
* Gets the short name of the class the class.
* Input can be MAP, LIST or regular string. In case of map or list the class name will be class name
* that map or list is returning.
* @param type
* @return
*/
public String getClassType(String type, boolean primitiveObject) {
String classShortName = "";
if(type.startsWith("List[")){
classShortName = type.substring(5, type.length()-1);
classShortName = getObjectType(classShortName, true);
}else if (type.startsWith("Map[")) {
classShortName = type.substring(4, type.length()-1);
classShortName = getObjectType(classShortName, true);
}else if (type.startsWith("Set[")) {
classShortName = type.substring(4, type.length()-1);
classShortName = getObjectType(classShortName, true);
}else if (type.equals("ok")) {
classShortName = "void";
}else{
classShortName = getObjectType(type, true);
}
return classShortName;
}
public String getArgumentDefinition(String argumentType, String argumentName) {
return argumentName + ": " + argumentType;
}
/**
* Gets the class of the expected return value for a type string. Examples of type Strings are int, User, List[User]
* If the type string is a collection type like a map or list the string value returned would be the class
* that map or list is returning.
*
* @param type
* @return
*/
public String getGenericType(String type) {
if(type.equalsIgnoreCase("void")|| type.equalsIgnoreCase("ok")){
return "void";
}
String classShortName = "";
if(type.startsWith("List[") || type.startsWith("Map[") || type.startsWith("Set[")){
classShortName = "Array";
}else{
classShortName = getObjectType(type, true);
}
return classShortName;
}
public String generateVariableInitialization(String typeClass) {
return "";
}
}

View File

@ -0,0 +1,132 @@
package com.wordnik.swagger.codegen.config.js;
import com.wordnik.swagger.codegen.LibraryCodeGenerator;
import com.wordnik.swagger.codegen.config.LanguageConfiguration;
import com.wordnik.swagger.codegen.exception.CodeGenerationException;
import com.wordnik.swagger.codegen.util.FileUtil;
import java.io.*;
/**
* @author ayush
* @since 10/24/11 7:47 PM
*/
public class JSLibCodeGen extends LibraryCodeGenerator {
private static final String DEFAULT_SERVICE_BASE_CLASS = "SwaggerApi";
public static void main(String[] args) {
if (args.length < 1) {
throw new CodeGenerationException("Invalid number of arguments passed: No command line argument was passed to the program for config json");
}
String libraryHome = null;
if (args.length == 1) {
String configPath = args[0];
JSLibCodeGen codeGenerator = new JSLibCodeGen(configPath);
codeGenerator.generateCode();
libraryHome = codeGenerator.getLanguageConfig().getLibraryHome();
}
if (args.length == 4) {
String apiServerURL = args[0];
if (!apiServerURL.endsWith("/")) {
apiServerURL = apiServerURL + "/";
}
String apiKey = args[1];
String packageName = args[2];
libraryHome = args[3];
if (libraryHome.endsWith("/")) {
libraryHome = libraryHome.substring(0, libraryHome.length() - 1);
}
String modelPackageName = packageName + ".model";
String apiPackageName = packageName + ".api";
String classOutputDir = libraryHome + "/src/main/js/" + packageName.replace(".", "/");
JSLibCodeGen codeGenerator = new JSLibCodeGen(apiServerURL, apiKey, modelPackageName,
apiPackageName, classOutputDir, libraryHome);
codeGenerator.getConfig().setDefaultServiceBaseClass(DEFAULT_SERVICE_BASE_CLASS);
codeGenerator.generateCode();
}
try {
if (libraryHome != null) {
concatinateFiles(libraryHome + "/src/main/js/api-lib.js", libraryHome + "/src/main/js/");
}
} catch (IOException e) {
System.out.println("Unable to combine files");
e.printStackTrace();
}
}
private static void concatinateFiles(String outFile, String sourcePath) throws IOException {
final PrintWriter pw = new PrintWriter(new FileOutputStream(outFile));
final File file = new File(sourcePath);
System.out.println("Scanning " + file);
appendFiles(pw, file.listFiles());
final File modelSource = new File(file, "model");
System.out.println("Scanning " + modelSource.getAbsolutePath());
appendFiles(pw, modelSource.listFiles());
final File apiSource = new File(file, "api");
System.out.println("Scanning " + apiSource.getAbsolutePath());
appendFiles(pw, apiSource.listFiles());
pw.close();
System.out.println("Concatenated to " + outFile);
}
private static void appendFiles(PrintWriter pw, File[] files) throws IOException {
for (int i = 0; i < files.length; i++) {
System.out.println("Processing " + files[i].getPath() + "...");
if(!files[i].isDirectory()) {
BufferedReader br = new BufferedReader(new FileReader(files[i]
.getPath()));
String line = br.readLine();
while (line != null) {
pw.println(line);
line = br.readLine();
}
br.close();
}
}
}
public JSLibCodeGen(String apiServerURL, String apiKey, String modelPackageName, String apiPackageName,
String classOutputDir, String libraryHome) {
super(apiServerURL, apiKey, modelPackageName, apiPackageName, classOutputDir, libraryHome);
this.setDataTypeMappingProvider(new JSDataTypeMappingProvider());
this.setNameGenerator(new JSNamingPolicyProvider());
}
public JSLibCodeGen(String configPath) {
super(configPath);
this.setDataTypeMappingProvider(new JSDataTypeMappingProvider());
this.setNameGenerator(new JSNamingPolicyProvider());
}
@Override
protected LanguageConfiguration initializeLangConfig(LanguageConfiguration jsConfiguration) {
jsConfiguration.setClassFileExtension(".js");
jsConfiguration.setTemplateLocation("conf/js/templates");
jsConfiguration.setStructureLocation("conf/js/structure");
jsConfiguration.setExceptionPackageName("com.wordnik.swagger.exception");
jsConfiguration.setAnnotationPackageName("com.wordnik.swagger.annotations");
//create ouput directories
FileUtil.createOutputDirectories(jsConfiguration.getModelClassLocation(), jsConfiguration.getClassFileExtension());
FileUtil.createOutputDirectories(jsConfiguration.getResourceClassLocation(), jsConfiguration.getClassFileExtension());
//delete previously generated files
FileUtil.clearFolder(jsConfiguration.getModelClassLocation());
FileUtil.clearFolder(jsConfiguration.getResourceClassLocation());
FileUtil.clearFolder(jsConfiguration.getLibraryHome() + "/src/main/js/com/wordnik/swagger/common");
FileUtil.clearFolder(jsConfiguration.getLibraryHome() + "/src/main/js/com/wordnik/swagger/exception");
FileUtil.clearFolder(jsConfiguration.getLibraryHome() + "/src/main/js/com/wordnik/swagger/event");
FileUtil.copyDirectory(new File(jsConfiguration.getStructureLocation()), new File(jsConfiguration.getLibraryHome()));
jsConfiguration.setModelEnumRequired(false);
jsConfiguration.setOutputWrapperRequired(true);
return jsConfiguration;
}
}

View File

@ -0,0 +1,24 @@
package com.wordnik.swagger.codegen.config.js;
import com.wordnik.swagger.codegen.config.common.CamelCaseNamingPolicyProvider;
/**
* @author ayush
* @since oct 24 2011
*/
public class JSNamingPolicyProvider extends CamelCaseNamingPolicyProvider {
/**
* Gets the signature of the method that gets value for give attribute name.
*
* Example: If class name is user and attibute name is email the out in java language will be
* <code>user.getEmail()</code>
*
* @param className
* @param attributeName
* @return
*/
public String createGetterMethodName(String className, String attributeName) {
return className+"."+ attributeName;
}
}

View File

@ -150,6 +150,7 @@ public class ModelField {
String type = paramType.trim(); String type = paramType.trim();
if(type.contains("date")||type.contains("Date") ){ if(type.contains("date")||type.contains("Date") ){
fieldDefinition.getImportDefinitions().addAll(dataTypeMapper.getDateIncludes()); fieldDefinition.getImportDefinitions().addAll(dataTypeMapper.getDateIncludes());
fieldDefinition.setHasDateResponse(true);
} }
if(type.startsWith("List[")){ if(type.startsWith("List[")){
fieldDefinition.getImportDefinitions().addAll(dataTypeMapper.getListIncludes()); fieldDefinition.getImportDefinitions().addAll(dataTypeMapper.getListIncludes());
@ -158,10 +159,13 @@ public class ModelField {
fieldDefinition.setCollectionItemType(entryType); fieldDefinition.setCollectionItemType(entryType);
fieldDefinition.setCollectionItemName(entryType); fieldDefinition.setCollectionItemName(entryType);
} else { } else {
fieldDefinition.setCollectionItemType(config.getModelPackageName() + "." + nameGenerator.applyClassNamingPolicy(entryType)); final String collectionItemType = config.getModelPackageName().length() == 0 ? nameGenerator.applyClassNamingPolicy(entryType) : config.getModelPackageName() + "." + nameGenerator.applyClassNamingPolicy(entryType);
fieldDefinition.setCollectionItemType(collectionItemType);
fieldDefinition.setCollectionItemName(nameGenerator.applyMethodNamingPolicy(entryType)); fieldDefinition.setCollectionItemName(nameGenerator.applyMethodNamingPolicy(entryType));
} }
entryType = dataTypeMapper.getClassType(entryType, true); entryType = dataTypeMapper.getClassType(entryType, true);
fieldDefinition.setHasPrimitiveType(dataTypeMapper.isPrimitiveType(entryType));
fieldDefinition.setHasListResponse(true);
String returnType = dataTypeMapper.getListReturnTypeSignature(entryType); String returnType = dataTypeMapper.getListReturnTypeSignature(entryType);
fieldDefinition.setReturnType(returnType); fieldDefinition.setReturnType(returnType);
fieldDefinition.setInitialization(" = " + dataTypeMapper.generateListInitialization(entryType)); fieldDefinition.setInitialization(" = " + dataTypeMapper.generateListInitialization(entryType));
@ -175,6 +179,8 @@ public class ModelField {
fieldDefinition.getImportDefinitions().addAll(dataTypeMapper.getSetIncludes()); fieldDefinition.getImportDefinitions().addAll(dataTypeMapper.getSetIncludes());
String entryType = type.substring(4, type.length()-1); String entryType = type.substring(4, type.length()-1);
entryType = dataTypeMapper.getClassType(entryType, true); entryType = dataTypeMapper.getClassType(entryType, true);
fieldDefinition.setHasPrimitiveType(dataTypeMapper.isPrimitiveType(entryType));
fieldDefinition.setHasSetResponse(true);
String returnType = dataTypeMapper.getSetReturnTypeSignature(entryType); String returnType = dataTypeMapper.getSetReturnTypeSignature(entryType);
fieldDefinition.setReturnType(returnType); fieldDefinition.setReturnType(returnType);
fieldDefinition.setInitialization(" = " + dataTypeMapper.generateSetInitialization(entryType)); fieldDefinition.setInitialization(" = " + dataTypeMapper.generateSetInitialization(entryType));
@ -190,6 +196,8 @@ public class ModelField {
String entryType = type.substring(4, type.length()-1); String entryType = type.substring(4, type.length()-1);
keyClass = entryType.substring(0, entryType.indexOf(",") ); keyClass = entryType.substring(0, entryType.indexOf(",") );
entryClass = entryType.substring(entryType.indexOf(",") + 1, entryType.length()); entryClass = entryType.substring(entryType.indexOf(",") + 1, entryType.length());
fieldDefinition.setHasPrimitiveType(dataTypeMapper.isPrimitiveType(entryClass));
fieldDefinition.setHasMapResponse(true);
//entryType = dataTypeMapper.getClassType(entryType, true); //entryType = dataTypeMapper.getClassType(entryType, true);
entryType = dataTypeMapper.getClassType(keyClass, true) + "," + dataTypeMapper.getClassType(entryClass, true); entryType = dataTypeMapper.getClassType(keyClass, true) + "," + dataTypeMapper.getClassType(entryClass, true);
String returnType = dataTypeMapper.getMapReturnTypeSignature(entryType); String returnType = dataTypeMapper.getMapReturnTypeSignature(entryType);
@ -204,6 +212,7 @@ public class ModelField {
fieldDefinition.setInitialization(dataTypeMapper.generateVariableInitialization(type)); fieldDefinition.setInitialization(dataTypeMapper.generateVariableInitialization(type));
fieldDefinition.setReturnType(dataTypeMapper.getClassType(type, false)); fieldDefinition.setReturnType(dataTypeMapper.getClassType(type, false));
fieldDefinition.setName(this.getName()); fieldDefinition.setName(this.getName());
fieldDefinition.setHasPrimitiveType(dataTypeMapper.isPrimitiveType(fieldDefinition.getReturnType()));
} }
} }
return fieldDefinition; return fieldDefinition;

View File

@ -59,7 +59,7 @@ public class APITestRunner {
private static String CONDITION_LESSER = "<"; private static String CONDITION_LESSER = "<";
private static String CONDITION_GREATER_EQUAL = ">="; private static String CONDITION_GREATER_EQUAL = ">=";
private static String CONDITION_LESSER_EQUAL = "<="; private static String CONDITION_LESSER_EQUAL = "<=";
private TestOutput testCaseOutput = new TestOutput(); private TestOutput testCaseOutput = new TestOutput();
private TestStatus testStatus = new TestStatus(); private TestStatus testStatus = new TestStatus();
private Object testData = null; private Object testData = null;
@ -538,6 +538,16 @@ public class APITestRunner {
}else if (language.equals(ANDROID)){ }else if (language.equals(ANDROID)){
command.add("../android/driver-test/bin/runandroid.sh"); command.add("../android/driver-test/bin/runandroid.sh");
command.add("com.wordnik.swagger.testframework.JavaTestCaseExecutor"); command.add("com.wordnik.swagger.testframework.JavaTestCaseExecutor");
}else if (language.equals(AS3)){
command.add("./bin/runas3TestCase.sh");
command.add("com.wordnik.swagger.testframework.AS3TestCaseExecutor");
if(postData == null){
postData = "\"\"";
}
else{
postData = "\"" + postData + "\"";
}
} }
command.addAll(getCommandInputs(apiServer, apiPackageName, apiKey, authToken, resource, httpMethod, command.addAll(getCommandInputs(apiServer, apiPackageName, apiKey, authToken, resource, httpMethod,

View File

@ -0,0 +1,167 @@
package com.wordnik.swagger.testframework;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* User: deepakmichael
* Date: 08/09/11
* Time: 10:34 AM
*/
public class AS3TestCaseExecutor {
/**
* Follow the following argument pattern
* Arguments in calling this method:
* ApiServerURL
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
AS3TestCaseExecutor runner = new AS3TestCaseExecutor();
String apiServer = args[0];
String servicePackageName = args[1];
String apiKey = args[2];
String authToken = args[3];
String resource = args[4];
String httpMethod = args[5];
String suggestedMethodName = args[6];
Map<String, String> queryAndPathParameters = new HashMap<String, String>();
String postData = null;
if(args.length > 7 && args[7].length() > 0){
String[] qpTuple = args[7].split("~");
for(String tuple: qpTuple){
String[] nameValue = tuple.split("=");
if (nameValue.length == 2 ) {
queryAndPathParameters.put(nameValue[0], nameValue[1]);
}
}
}
if(args.length > 8 ){
postData = args[8];
}
queryAndPathParameters.put("authToken", authToken);
servicePackageName = args[9];
String testAppConfigPath = args[10];
String flexHome = args[11];
runner.writeJSONTestData(apiServer, apiKey, authToken, httpMethod, resource, servicePackageName,
suggestedMethodName, queryAndPathParameters, postData, testAppConfigPath);
runner.executeTestCase(testAppConfigPath, flexHome);
}
private void executeTestCase(String testAppConfigPath, String flexHome) throws Exception {
String[] externalCommand = constructExternalCommand(testAppConfigPath, flexHome);
executeExternalTestCaseAndGetResult(externalCommand);
}
private void writeJSONTestData(String apiServer, String apiKey, String authToken, String httpMethod, String resource,
String servicePackageName, String suggestedMethodName, Map<String,
String> queryAndPathParameters, String postData, String testAppConfigPath) throws IOException {
//write JSON file
HashMap<String, Object> testInfo = new HashMap<String, Object>();
testInfo.put("apiUrl",apiServer);
testInfo.put("apiPackageName", servicePackageName);
testInfo.put("apiKey", apiKey);
testInfo.put("authToken", authToken);
testInfo.put("resource", resource);
testInfo.put("httpMethod", httpMethod);
testInfo.put("methodName", suggestedMethodName);
testInfo.put("queryAndPathParams",queryAndPathParameters);
testInfo.put("postData", postData);
testInfo.put("language","AS3");
JsonFactory factory = new JsonFactory();
ObjectMapper mapper = new ObjectMapper(factory);
File aFileInOutputPath = new File(testAppConfigPath);
String parentDirectory = aFileInOutputPath.getParent();
mapper.writeValue(new File(parentDirectory+"/testData.json"), testInfo);
}
private void executeExternalTestCaseAndGetResult(String[] command) throws Exception {
Process p = Runtime.getRuntime().exec(command);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
StringBuilder output = new StringBuilder();
String s = null;
boolean isStatusLine = true;
String status = "";
while ((s = stdInput.readLine()) != null) {
//System.out.println(s);
if(isStatusLine){
status = s;
if(status.equalsIgnoreCase("SUCCESS")||status.equalsIgnoreCase("OK") ) {
isStatusLine = false;
}
}else{
output.append(s);
}
//System.out.println(s);
}
String userDirectory = System.getProperty("user.home")+ File.separator+"Documents";
String outputFile = userDirectory + File.separator+"testOutput.json";
JsonFactory factory = new JsonFactory();
ObjectMapper mapper = new ObjectMapper(factory);
File from = new File(outputFile);
TypeReference<HashMap<String,Object>> typeRef
= new TypeReference<
HashMap<String,Object>
>() {};
HashMap<String,Object> o
= mapper.readValue(from, typeRef);
Boolean isSuccess = false;
if(o.containsKey("isSuccess")){
isSuccess = (Boolean) o.get("isSuccess");
}
System.out.println(isSuccess ? "SUCCESS" : "FAILURE");
if(isSuccess){
if ( o.get("payload") != null ) {
mapper.writeValue(System.out, o.get("payload"));
}
}
else{
mapper.writeValue(System.out, o.get("errorMessage"));
}
from.delete();
}
/**
* Get the java command line that needs to be executed for runnign a test case
* @param testAppConfigPath
* @param flexHome
*/
private String[] constructExternalCommand(String testAppConfigPath, String flexHome) {
List<String> command = new ArrayList<String>();
command.add(flexHome + "/bin/adl");
command.add(testAppConfigPath);
String[] commandArray = new String[command.size()];
command.toArray(commandArray);
return commandArray;
}
}