1
+ package io.swagger.common {
2
+ import io.swagger.event.ApiClientEvent ;
3
+ import io.swagger.event.Response ;
4
+
5
+ public class ApiInvoker extends EventDispatcher {
6
+
7
+ private static const DELETE_DATA_DUMMY : String = "dummyDataRequiredForDeleteOverride" ;
8
+ private static const X_HTTP_OVERRIDE_KEY : String = "X-HTTP-Method-Override" ;
9
+ private static const CONTENT_TYPE_HEADER_KEY : String = "Content-Type" ;
10
+
11
+ public function ApiInvoker (apiUsageCredentials :ApiUserCredentials , eventNotifier :EventDispatcher , useProxy :Boolean = true ) {
12
+ _apiUsageCredentials = apiUsageCredentials;
13
+ _useProxyServer = useProxy ;
14
+ if (_apiUsageCredentials . hostName != null ) {
15
+ _proxyHostName = _apiUsageCredentials . hostName;
16
+ }
17
+ _apiPath = _apiUsageCredentials . apiPath;
18
+ _proxyPath = _apiUsageCredentials . proxyPath;
19
+ _apiProxyServerUrl = _apiUsageCredentials . apiProxyServerUrl;
20
+ _apiEventNotifier = eventNotifier;
21
+ }
22
+ public var _apiEventNotifier : EventDispatcher ;
23
+ internal var _apiProxyServerUrl : String = "" ;
24
+ internal var _useProxyServer : Boolean = true ;
25
+ private var _apiUsageCredentials : ApiUserCredentials;
26
+ private var _baseUrl : String = "" ;
27
+ private var _proxyHostName : String = "" ;
28
+ private var _apiPath : String = "" ;
29
+ private var _proxyPath : String = "" ;
30
+
31
+ public function invokeAPI (resourceURL :String , method :String , queryParams :Dictionary , postObject :Object , headerParams :Dictionary ):AsyncToken {
32
+ //make the communication
33
+ if (_useProxyServer ) {
34
+ resourceURL = _apiProxyServerUrl + resourceURL;
35
+ }
36
+ else {
37
+ resourceURL = "http://" + _proxyHostName + _apiPath + resourceURL;
38
+ }
39
+
40
+ var counter: int = 0 ;
41
+ var symbol: String = "&" ;
42
+ var paramValue: Object ;
43
+ for (var paramName: String in queryParams) {
44
+ paramValue = queryParams[ paramName];
45
+ //var key:String = paramName;
46
+ // do stuff
47
+ symbol = "&" ;
48
+ if (counter == 0 ) {
49
+ symbol = "?" ;
50
+ }
51
+ resourceURL = resourceURL + symbol + paramName + "=" + paramValue. toString ();
52
+ counter++;
53
+
54
+ }
55
+ // trace(resourceURL);
56
+ //create a httpservice and invoke the rest url waiting for response
57
+ var requestHeader: Object = new Object ();
58
+ if (headerParams != null ) {
59
+ for (var key: String in headerParams) {
60
+ requestHeader[ key] = headerParams[ key];
61
+ }
62
+ }
63
+
64
+ resourceURL = ApiUrlHelper. appendTokenInfo(resourceURL, requestHeader, _apiUsageCredentials );
65
+
66
+ var bodyData: String = marshal(postObject). toString (); //restRequest.postData;
67
+
68
+ return doRestCall(resourceURL, onApiRequestResult, onApiRequestFault, method , bodyData, requestHeader, "application/xml" );
69
+
70
+
71
+ }
72
+
73
+ public function marshal (source :Object ):Object {
74
+ // trace("marshal got - " + source)
75
+ if (source is String ) {
76
+ return source ;
77
+ } else if (source is Array && source . length > 0 ) {
78
+ var writer: XMLWriter = new XMLWriter();
79
+ var sourceArray: Array = source as Array ;
80
+ var arrayEnclosure: String = getArrayEnclosure(sourceArray);
81
+ writer. xml . setName (arrayEnclosure);
82
+
83
+ for (var i: int = 0 ; i < sourceArray. length ; i++ ) {
84
+ var o: Object = sourceArray[ i];
85
+ writer. xml . appendChild (marshal(o));
86
+ }
87
+ return writer. xml ;
88
+ } else
89
+ return marshalObject(source );
90
+ }
91
+
92
+ public function marshalObject (source :Object ):XML {
93
+ var writer: XMLWriter = new XMLWriter();
94
+ var objDescriptor: XML = describeType (source );
95
+ var property : XML ;
96
+ var propertyType: String ;
97
+ var propertyValue: Object ;
98
+
99
+ var qualifiedClassName: String = objDescriptor. @name ;
100
+ qualifiedClassName = qualifiedClassName. replace ("::" , "." );
101
+ var className : String = qualifiedClassName. substring (qualifiedClassName. lastIndexOf ("." ) + 1 );
102
+ className = className (). toLowerCase () + className . substring (1 );
103
+ writer. xml . setName (className );
104
+
105
+ for each (property in objDescriptor. elements ("variable" )) {
106
+ propertyValue = source [ property . @name ];
107
+ if (propertyValue != null ) {
108
+ if (ObjectUtil . isSimple (propertyValue)) {
109
+ writer. addProperty(property . @name , propertyValue. toString ());
110
+ }
111
+ else {
112
+ writer. addProperty(property . @name , marshal(propertyValue). toXMLString ());
113
+ }
114
+ }
115
+ }
116
+ for each (property in objDescriptor. elements ("accessor" )) {
117
+ if (property . @access == "readonly" ) {
118
+ continue ;
119
+ }
120
+ propertyValue = source [ property . @name ];
121
+ if (source [ property . @name ] != null ) {
122
+ if (ObjectUtil . isSimple (propertyValue)) {
123
+ writer. addProperty(property . @name , propertyValue. toString ());
124
+ }
125
+ else {
126
+ writer. addProperty(property . @name , marshal(propertyValue). toXMLString ());
127
+ }
128
+ }
129
+ }
130
+ return writer. xml ;
131
+ }
132
+
133
+ public function escapeString (str :String ):String {
134
+ return str;
135
+ }
136
+
137
+ private function doRestCall (url :String , resultFunction :Function , faultFunction :Function = null ,
138
+ restMethod :String = "GET" ,
139
+ bodyData :Object = null , headers :Object = null , contentType :String = "application/xml" ):AsyncToken {
140
+ var httpService: HTTPService = new HTTPService ();
141
+
142
+ if (headers == null ) {
143
+ headers = new Object ();
144
+ }
145
+ httpService. method = restMethod;
146
+
147
+ if (restMethod. toUpperCase () != HTTPRequestMessage . GET_METHOD ) {
148
+ //httpService.method = HTTPRequestMessage.POST_METHOD; - not required as we're using the proxy
149
+ if (bodyData == null ) {
150
+ bodyData = new Object ();
151
+ }
152
+
153
+ if (restMethod == HTTPRequestMessage . DELETE_METHOD ) {
154
+ headers [ X_HTTP_OVERRIDE_KEY ] = HTTPRequestMessage . DELETE_METHOD ;
155
+ bodyData = DELETE_DATA_DUMMY ;
156
+ }
157
+ else if (restMethod == HTTPRequestMessage . PUT_METHOD ) {
158
+ headers [ X_HTTP_OVERRIDE_KEY ] = HTTPRequestMessage . PUT_METHOD ;
159
+ }
160
+ else {
161
+ headers [ CONTENT_TYPE_HEADER_KEY ] = contentType ;
162
+ }
163
+ }
164
+ else {
165
+ //if the request type is GET and content type is xml then the Flex HTTPService converts it to a POST ... yeah
166
+ contentType = null ;
167
+ }
168
+
169
+ httpService. url = url ;
170
+ httpService. contentType = contentType ;
171
+ httpService. resultFormat = "e4x" ;
172
+ httpService. headers = headers ;
173
+ httpService. addEventListener (ResultEvent . RESULT , resultFunction);
174
+ if (faultFunction != null ) {
175
+ httpService. addEventListener (FaultEvent . FAULT , faultFunction);
176
+ }
177
+ if (_useProxyServer ) {
178
+ httpService. useProxy = true ;
179
+
180
+ var channelSet : ChannelSet = new ChannelSet ();
181
+ var httpChannel: HTTPChannel = new HTTPChannel ();
182
+ httpChannel. uri = ApiUrlHelper. getProxyUrl(_proxyHostName , _proxyPath );
183
+ channelSet . addChannel (httpChannel);
184
+ httpService. channelSet = channelSet ;
185
+ }
186
+
187
+ return httpService. send (bodyData);
188
+ }
189
+
190
+ private function onApiRequestResult (event :ResultEvent ):void {
191
+ var completionListener: Function = event. token . completionListener;
192
+ var result : Object = event. result ;
193
+ var resultType: Class = event. token . returnType ;
194
+ var resultObject: Object ;
195
+ if (resultType != null ) {
196
+ var context: ASAXBContext = ASAXBContext. newInstance (resultType);
197
+ var unmarshaller: Unmarshaller = context. createUnmarshaller();
198
+ var resultXML: XML = new XML (event. result );
199
+ try {
200
+ resultObject = unmarshaller. unmarshal(resultXML);
201
+ }
202
+ catch (error : TypeError ) {
203
+ var errorResponse: Response = new Response(false , null , "Could not unmarshall response" );
204
+ if (_apiEventNotifier != null ) { //dispatch event via assigned dispatcher
205
+ var failureEvent: ApiClientEvent = new ApiClientEvent(event. token . completionEventType);
206
+ failureEvent. response = errorResponse;
207
+ _apiEventNotifier . dispatchEvent (failureEvent);
208
+ }
209
+ }
210
+
211
+ if (resultObject is ListWrapper) {
212
+ resultObject = ListWrapper(resultObject). getList();
213
+ }
214
+ }
215
+
216
+ var response: Response = new Response(true , resultObject);
217
+ response. requestId = event. token . requestId;
218
+ var successEventType: String = event. token . completionEventType != null ? event. token . completionEventType : ApiClientEvent. SUCCESS_EVENT ;
219
+
220
+ if (_apiEventNotifier != null ) { //dispatch event via assigned dispatcher
221
+ var successEvent: ApiClientEvent = new ApiClientEvent(successEventType);
222
+ successEvent. response = response;
223
+ _apiEventNotifier . dispatchEvent (successEvent);
224
+ }
225
+ }
226
+
227
+ private function onApiRequestFault (event :FaultEvent ):void {
228
+ var completionListener: Function = event. token . completionListener;
229
+ if (completionListener != null ) {
230
+ completionListener. call (null , new Response(false , null , event. fault . faultString ));
231
+ }
232
+
233
+ var failureEventType: String = event. token . completionEventType != null ? event. token . completionEventType : ApiClientEvent. FAILURE_EVENT ;
234
+
235
+ if (_apiEventNotifier != null ) { //dispatch event via assigned dispatcher
236
+ var failureEvent: ApiClientEvent = new ApiClientEvent(failureEventType);
237
+ failureEvent. response = new Response(false , null , event. fault . faultString );
238
+ _apiEventNotifier . dispatchEvent (failureEvent);
239
+ }
240
+ }
241
+
242
+ private function getArrayEnclosure (arr :Array ):String {
243
+ if (arr != null && arr. length > 0 ) {
244
+ var className : String = flash. utils. getQualifiedClassName(arr[ 0 ] )
245
+ if (className . indexOf ("::" ) > 0 )
246
+ className = className . substr (className . indexOf ("::" ) + 2 , className . length )
247
+
248
+ return className . substring (0 , 1 ). toLowerCase () + className . substring (1 , className . length ) + "s" ;
249
+ } else
250
+ return "" ;
251
+ }
252
+
253
+
254
+ }
255
+ }
0 commit comments