/** * com.sekati.services.SOAPClient * @version 1.0.6 * @author jason m horwitz | sekati.com * Copyright (C) 2007 jason m horwitz, Sekat LLC. All Rights Reserved. * Released under the MIT License: http://www.opensource.org/licenses/mit-license.php */ import com.sekati.core.CoreObject; import com.sekati.events.Dispatcher; import com.sekati.log.Logger; import com.sekati.services.ISOAPClient; import com.sekati.services.SOAPEvent; import com.sekati.utils.Delegate; import com.sekati.validate.TypeValidation; import mx.services.SOAPCall; import mx.services.WebService; /** * Soap Client class to be used with JNuSOAP.
* TODO Replace Singleton Dispatcher for call result handling granularity. * *
Q: 'There are multiple possible ports in the WSDL file; please specify a service name and port name!?' *
A: add port to class instance, seach for "port" in the wsdl & see url's below for more info. * * @see http://www.intangibleinc.com/movabletype/archives/000007.html * @see http://livedocs.macromedia.com/fms/2/docs/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000796.html * @see http://www.flash-db.com/Tutorials/lclasses/lclasses.php?page=2 * @see http://www.adobe.com/devnet/flash/articles/flmxpro_webservices_03.html */ class com.sekati.services.SOAPClient extends CoreObject implements ISOAPClient { private static var _instance:SOAPClient; private var _ws:WebService; private var _wsdl:String; private var _port:String; private var _isConnected:Boolean; private var _isVerbose:Boolean; /** * Singleton Private Constructor */ private function SOAPClient() { super( ); _isConnected = false; _isVerbose = false; } /** * Singleton Accessor. * @return SOAPClient */ public static function getInstance():SOAPClient { if (!_instance) { _instance = new SOAPClient( ); } return _instance; } /** * shorthand singleton accessor getter. * @return SOAPClient */ public static function get $():SOAPClient { return SOAPClient.getInstance( ); } /** * Connect the SOAP client to webservice. * @param wsdl (String) wsdl URL. * @param port (String) optional service port - see more * @return Void */ public function connect(wsdl:String, port:String):Void { _wsdl = wsdl; _port = port; _ws = new WebService( _wsdl ); if (port) _ws._portName = port; _ws.onLoad = Delegate.create( _instance, connectLoad ); _ws.onFault = Delegate.create( _instance, connectFault ); } /** * SOAP webservice method call. * @param method (String) service method name * @param args (Array) array of service method arguments * @return Void */ public function call(method:String, args:Array):Void { /* * Call Remote WebService Method using args array; then broadcast the result/fault event. * NOTE: webservice method invocations return an asynchronous callback. * callback is undefined if the service itself is not created (and service.onFault fires) */ var _call:Function = _ws[method].apply( _ws, args ); _call.onResult = Delegate.create( _instance, callResult, method ); _call.onFault = Delegate.create( _instance, callFault, method, _call.request, _call.response ); } /** * Get verbosity SOAPClient sends to {@link Logger} * @return Boolean */ public function get verbose():Boolean { return _isVerbose; } /** * Set verbosity SOAPClient sends to {@link Logger} * @param b (Boolean) * @return Void */ public function set verbose(b:Boolean):Void { _isVerbose = b; } /** * Connect onLoad Handler * @param wsdl (String) * @return Void */ private function connectLoad(wsdl:String):Void { _isConnected = true; Dispatcher.$.dispatchEvent( new SOAPEvent( SOAPEvent.CONNECT, {wsdl:_wsdl} ) ); if (_isVerbose) Logger.$.status( _instance.toString( ), "Webservice Connection SUCCESS Load: '" + _wsdl + "'" ); } /** * Connect onFault Handler * @param fault (Object) * @return Void */ private function connectFault(fault:Object):Void { _isConnected = false; Dispatcher.$.dispatchEvent( new SOAPEvent( SOAPEvent.FAULT, {fault:fault} ) ); if (_isVerbose) Logger.$.fatal( _instance.toString( ), "Webservice Connection FAILURE Fault: '" + _wsdl + "'\nfaultstring: " + fault.faultstring + "\nfaultcode: " + fault.faultcode + "\ndetail: " + fault.detail + "\nfaultactor: " + fault.faultactor + "\nfault: " + fault ); } /** * Call onResult Handler * @param method (String) * @param result (Object) * @return Void */ private function callResult(method:String, result:Object):Void { Dispatcher.$.dispatchEvent( new SOAPEvent( SOAPEvent.CALL_RESULT, {method:method, result:result} ) ); if (_isVerbose) { Logger.$.info( _instance.toString( ), "Webservice Call Result: '" + method + "'\nresult (" + TypeValidation.getType( result ).name + "): " + result ); } } /** * Call onFault Handler * @param method (String) * @param fault (Object) * @return Void */ private function callFault(method:String, response:Object, request:Object, fault:Object):Void { Dispatcher.$.dispatchEvent( new SOAPEvent( SOAPEvent.CALL_FAULT, {method:method, fault:fault} ) ); if (_isVerbose) { var props:String = "", call:String = ""; for(var i:String in SOAPCall) props += "\nSOAPCall Properties: " + i + " " + this[i]; for (var j:String in SOAPCall) call += "\nSOAPCall-> " + j + " " + SOAPCall[j]; Logger.$.error( _instance.toString( ), "Webservice Call Fault: '" + method + "'\nfaultstring: " + fault.faultstring + "\nfaultcode: " + fault.faultcode + "\ndetail: " + fault.detail + "\nfaultactor: " + fault.faultactor + "\nrequest: " + request + "\nSOAP response envelope: " + response + "\nfault: " + fault + "\n" + props + "\n" + call ); } } }