Asynchronous calls in custom validator's doValidation method

View: New views
1 Messages — Rating Filter:   Alert me  

Asynchronous calls in custom validator's doValidation method

by pmstp :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi all,

I'm trying to call an asynchronous WebService in a custom validator's doValidation (which is a synchronous method).
I'm using a while loop around a boolean variable as a poor man's spinlock but that causes the CPU usage to dramatically increase leading to the browser
asking users if they want to keep the script executing or stop it (after 15 seconds).
Also the WebService handlers take a long time (> 1 minute) to finally set the spinlock.  
But without the spin lock the doValidation exists immediately.  Is there a way to pause/sleep the current function (thread?) until the
WebService callback runs?


TIA,
Pedro Proenca


PS: Here's how my code looks like:

package validators {
    import mx.validators.*;
    import mx.rpc.events.*;
    import mx.rpc.soap.*;
    import mx.utils.StringUtil;
    import mx.controls.Alert;                

    
    
    public class SharePointURLValidator extends Validator
    {
        protected const BASE_URL:String = "http://sharepoint/";


        protected var results:Array;
        protected var validSite:Boolean = false;
        protected var SOAPCallbackDone:Boolean = false;
        protected var sharePointSvc:WebService;

        
        public function SharePointURLValidator():void
        {
            super();
            sharePointSvc = new WebService();                
        }
        

        override protected function doValidation(value:Object):Array
        {
            results = [];
            
            results = super.doValidation(value);
            if (results.length > 0)
                return results;
            
            if (!(value is String)) {
                results.push(new ValidationResult(true, null, "Type Error", "String required"));
                return results;
            }

            if (!isValidSharePointURL(value as String))
                results.push(new ValidationResult(true, null, "Bad URL", "Not a valid SharePoint site. Make sure it starts with http://sharepoint/"));

                return results;
        }


        protected function isValidSharePointURL(url:String):Boolean
        {            
            trace(getTime() + " isValidSharePointURL called");
            
            if (url == null || StringUtil.trim(url).length == 0)
                    return false;
                    
            if ((url.length < BASE_URL.length) || (url.substr(0, BASE_URL.length).toLocaleLowerCase() != BASE_URL))
                url = BASE_URL + url;

            sharePointSvc.wsdl = url + "/_vti_bin/webs.asmx?WSDL";
            sharePointSvc.loadWSDL();
            sharePointSvc.GetWebCollection.addEventListener(ResultEvent.RESULT, resultHandler);
            sharePointSvc.GetWebCollection.addEventListener(FaultEvent.FAULT, faultHandler);
            Alert.show(getTime() + " Calling SharePoint");        
            sharePointSvc.GetWebCollection();
                    
            while(!SOAPCallbackDone);
            
            return validSite;
        }
            
            

            private function resultHandler(event:ResultEvent):void
            {
                sharePointSvc.GetWebCollection.removeEventListener(ResultEvent.RESULT, resultHandler);
                sharePointSvc.GetWebCollection.removeEventListener(FaultEvent.FAULT, faultHandler);

                Alert.show(getTime() + " SOAP call succeeded");
                validSite = true;
                SOAPCallbackDone = true;
            }


            private function faultHandler(event:FaultEvent):void
            {
                sharePointSvc.GetWebCollection.removeEventListener(ResultEvent.RESULT, resultHandler);
                sharePointSvc.GetWebCollection.removeEventListener(FaultEvent.FAULT, faultHandler);

                Alert.show(getTime() + " SOAP called failed");
                validSite = false;
                SOAPCallbackDone = true;
            }
        
        
          private function getTime():String
      {
                var currentTime:Date = new Date();
                return currentTime.toString();
            }
    }

}