В AS3 проверить класса надежности


У меня на ActionScript 3 класса, что я хочу тебя проверить на прочность. Я знаю, что это довольно много кода, и это не обязательно, что вы просмотрите весь код, но, может быть, вы видите общие проблемы, как мне обрабатывать исключения или, может быть, вы заметили что-то, что может наделать бед.

Цель класса-загрузить локальный SWF и запустить его в воздух изолированной программной среде безопасности. Прежде чем сделать это, он может обновить SWF в двух направлениях:

  1. либо есть MyApp_update.SWF в настоящее время в приложения-хранилище каталогов - в этом случае его необходимо просто заменить текущего SWF на этот SWF.

  2. если это не так, он подключается к серверу и проверяет наличие новой версии доступен для загрузки в meta-info.xml и сравнив номер версии на сервере с версией количество местного meta-info.xml

Важно, что эта часть кода является надежной, т. к. остальные приложения можно легко удаленного обновления (в случае, если этот класс здесь делает это хорошо).

package
{

    import flash.desktop.NativeApplication;
    import flash.display.Loader;
    import flash.display.NativeWindow;
    import flash.display.NativeWindowInitOptions;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent;
    import flash.events.UncaughtErrorEvent;
    import flash.filesystem.File;
    import flash.filesystem.FileMode;
    import flash.filesystem.FileStream;
    import flash.net.URLLoader;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;
    import flash.system.ApplicationDomain;
    import flash.system.LoaderContext;
    import flash.utils.ByteArray;


    public class MyApp_Base extends Sprite
    {
        private var _remoteMetaRequest:URLRequest = new URLRequest("http://www.myServer.com/updater_test/my_app_meta.xml")
        private var _remoteSwfRequest:URLRequest = new URLRequest("http://www.myServer.com/updater_test/MyApp.swf");

        private var _localSwfFile:File = new File("app-storage:/application/MyApp.swf");
        private var _localSwfUpdateFile:File = new File("app-storage:/application/MyApp_update.swf");
        private var _localMetaFile:File = new File("app-storage:/application/my_app_meta.xml");
        private var _localMetaXML:XML;
        private var _remoteMetaXMLString:String;
        private var _remoteMetaXML:XML;

        private var _swfLoader:Loader = new Loader();
        private var _swfUrlLoader:URLLoader = new URLLoader();
        private var _progressBox:LoaderBox = new LoaderBox();
        private var _progressWindow:NativeWindow;

        public function MyApp_Base()
        {
            loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onUncaughtError);

            //check if a local swf update file is present. if so, replace the current version with it, delete the update file and skip checking the server
            if(_localSwfUpdateFile.exists){
                _swfUrlLoader.dataFormat = URLLoaderDataFormat.BINARY;
                _swfUrlLoader.addEventListener(Event.COMPLETE, updateSwfLoaded);
                _swfUrlLoader.addEventListener(IOErrorEvent.IO_ERROR, localUpdateError);

                try{
                    _swfUrlLoader.load(new URLRequest(_localSwfUpdateFile.nativePath));
                }
                catch(e:Error){
                    showError("Error", "Error 1 while loading local update file. If this error persists, please contact the application author. \n"+e.message);
                    return;
                }
            }
            else{ //check the server for a new update
                //load the local Metadata file:
                var s:FileStream = new FileStream();
                try{
                    s.open(_localMetaFile,FileMode.READ);
                    var xmlString:String = s.readUTFBytes(s.bytesAvailable);
                    _localMetaXML = new XML(xmlString);
                    s.close();
                }
                catch(e:Error){
                    showWarning("Warning", "There was an Error while loading the file " +_localMetaFile.nativePath +". This could mean that your installation is corrupted. The updateserver is not checked for updates: \n"+e.message);
                    loadAndRunLocalSwf();
                    return;
                }

                //load the remote Metadata file:
                var urlLoader:URLLoader = new URLLoader();
                urlLoader.addEventListener(Event.COMPLETE, remoteXMLLoaded);
                urlLoader.addEventListener(IOErrorEvent.IO_ERROR, remoteXMLError);
                try{
                    urlLoader.load(_remoteMetaRequest);
                }
                catch(e:Error){
                    showWarning("Warning", "There was an Error while loading the file " +_remoteMetaRequest.url +". This error does not affect application execution, but prevents the application from being updated. If this error persists, please contact the application author. \n"+e.message);
                    loadAndRunLocalSwf();
                    return;
                }
            }
        }

        private function remoteXMLLoaded(e:Event):void{
            if(e.target.bytesLoaded!=e.target.bytesTotal){
                trace("internet connection got interrupted during download of remoteXML");
                remoteXMLError(null);
                return;
            }

            try{
                _remoteMetaXMLString = e.target.data;
                _remoteMetaXML = new XML(_remoteMetaXMLString);
                var localVersion:int = _localMetaXML.version;
                var remoteVersion:int = _remoteMetaXML.version;
            }
            catch(e:Error){
                    showWarning("Warning", "The file " +_remoteMetaRequest.url +" is not correctly formatted. This error does not affect application execution, but prevents the application from being updated. If this error persists, please contact the application author. \n"+e.message);
                    loadAndRunLocalSwf();
                    return;     
            }

            if(remoteVersion>localVersion)
                updateSWF();
            else
                loadAndRunLocalSwf();
        }

        private function remoteXMLError(e:Event):void{
            loadAndRunLocalSwf();
        }


        private function updateSWF():void{
            _swfUrlLoader.dataFormat = URLLoaderDataFormat.BINARY;
            _swfUrlLoader.addEventListener(Event.COMPLETE, updateSwfLoaded);
            _swfUrlLoader.addEventListener(IOErrorEvent.IO_ERROR, remoteSwfError);
            _swfUrlLoader.addEventListener(ProgressEvent.PROGRESS, onProgressDownload);

            showProgressWindow("Downloading important software update");

            try{
                _swfUrlLoader.load(_remoteSwfRequest);
            }
            catch(e:Error){
                showWarning("Warning", "There was an Error while loading the file " +_remoteSwfRequest.url +". This error does not affect application execution, but prevents the application from being updated. If this error persists, please contact the application author. \n"+e.message);
                loadAndRunLocalSwf();
                return;
            }
        }

        private function remoteSwfError(e:Event):void{
            if(_progressWindow){
                try{
                    _swfUrlLoader.close();
                    _progressWindow.close();
                    _progressWindow = null;
                }
                catch(e:Error){}
            }
            loadAndRunLocalSwf();
        }

        private function localUpdateError(e:Event):void{
            showError("Error", "Error 2 while loading local update file. If this error persists, please contact the application author. \n"+e.toString);
        }

        private function updateSwfLoaded(e:Event):void{
            if(e.target.bytesLoaded!=e.target.bytesTotal){
                trace("internet connection got interrupted while downloading remote MyApp.swf");
                remoteSwfError(null);
                return;
            }
            if(_progressWindow)
                _progressWindow.close();
            _progressWindow = null;

            var ba:ByteArray = e.target.data;

            //if old backupfile exists, delete it
            var backup:File = new File("app-storage:/application/MyApp_backup.swf");
            if(backup.exists){
                try{
                    backup.deleteFile();
                }
                catch(e:Error){
                    showError("Error", "Error while deleting file "+backup.nativePath+" : \n"+e.message);
                    return;
                }
            }

            //make current SWF the backup
            var appFile:File = new File("app-storage:/application/MyApp.swf");
            try{
                appFile.moveTo(appFile.parent.resolvePath("MyApp_backup.swf"));
            }
            catch(e:Error){
                showError("Error", "Error while creating backup of "+ appFile.nativePath+" . Make sure that there is only one instance of the MyApp running. If this error persists, please contact the application author. \n"+e.message);
                return;
            }

            //write the downloaded SWF to the disk
            var s:FileStream = new FileStream();
            try{
                appFile = new File("app-storage:/application/MyApp.swf");
                s.open(appFile, FileMode.WRITE);
                s.writeBytes(ba);
                s.close();
            }
            catch(e:Error){
                showError("Error", "Error while writing MyApp.swf to disk. Will try to restore backup. If this error persists, please contact the application author. \n"+e.message);
                backup = new File("app-storage:/application/MyApp_backup.swf");
                backup.moveTo(backup.parent.resolvePath("MyApp.swf"));
                return;
            }

            if(_localSwfUpdateFile.exists){//the update was performed by a local update file
                try{
                    _localSwfUpdateFile.deleteFile();
                }
                catch(e:Error){
                    showError("Error", "Could not delete " + _localSwfUpdateFile.nativePath + ". If this error persists, please contact the application author. \n"+e.message);
                    return;
                }
            }
            else{   
                //write the downloaded MetaData to the disk
                try{
                    s.open(_localMetaFile,FileMode.WRITE);
                    s.writeUTFBytes(_remoteMetaXMLString);
                    s.close();
                }
                catch(e:Error){
                    showError("Error", "Error while writing "+ _localMetaFile.nativePath+" to disk. Make sure that there is only one instance of the MyApp running. If this error persists, please contact the application author.\n"+e.message);
                    return;
                }
            }

            //run the loaded SWF
            loadAndRunLocalSwf();
        }

        private function loadAndRunLocalSwf():void{
            var context:LoaderContext = new LoaderContext();
            context.allowLoadBytesCodeExecution = true;
            context.applicationDomain = ApplicationDomain.currentDomain;

            var s:FileStream = new FileStream();
            try{
                s.open(_localSwfFile,FileMode.READ);
                var ba:ByteArray = new ByteArray();
                s.readBytes(ba);
                s.close();

                _swfLoader.loadBytes(ba,context);
            }
            catch(e:Error){
                showError("Error", "Error while launching "+_localSwfFile.nativePath+". This could mean that your installation is corrupted. If this error persists, please contact the application author.\n"+e.message);
                return;
            }
        }

        private function onUncaughtError(e:UncaughtErrorEvent):void
        {
            e.preventDefault();
            var error:Error = e.error;
            showWarning("Uncaught Error:", error.message);
            return;
        }

        private function showError(title:String, msg:String):void{
            var errorBox:ErrorBox = new ErrorBox(msg);

            var nativeWinOpt:NativeWindowInitOptions = new NativeWindowInitOptions();
            nativeWinOpt.maximizable = false;
            nativeWinOpt.minimizable = true;
            nativeWinOpt.resizable = false;

            var window:NativeWindow = new NativeWindow(nativeWinOpt);
            window.stage.scaleMode = StageScaleMode.NO_SCALE;
            window.stage.align = StageAlign.TOP_LEFT;
            window.width = errorBox.width;
            window.height = errorBox.height;
            window.addEventListener(Event.CLOSE, closeApplication);
            errorBox.addEventListener(Event.CLOSE, closeApplication);
            window.title = title;
            window.stage.addChild(errorBox);
            window.activate();
        }

        private function showWarning(title:String, msg:String):void{
            var warningBox:WarningBox = new WarningBox(msg);

            var nativeWinOpt:NativeWindowInitOptions = new NativeWindowInitOptions();
            nativeWinOpt.maximizable = false;
            nativeWinOpt.minimizable = true;
            nativeWinOpt.resizable = false;

            var window:NativeWindow = new NativeWindow(nativeWinOpt);
            window.stage.scaleMode = StageScaleMode.NO_SCALE;
            window.stage.align = StageAlign.TOP_LEFT;
            window.width = warningBox.width;
            window.height = warningBox.height;
            window.title = title;
            window.stage.addChild(warningBox);
            window.activate();
        }

        private function showProgressWindow(msg:String):void{
            _progressBox.setMessage(msg);
            _progressBox.setProgress(0.0);

            var nativeWinOpt:NativeWindowInitOptions = new NativeWindowInitOptions();
            nativeWinOpt.maximizable = false;
            nativeWinOpt.minimizable = true;
            nativeWinOpt.resizable = false;

            _progressWindow = new NativeWindow(nativeWinOpt);
            _progressWindow.stage.scaleMode = StageScaleMode.NO_SCALE;
            _progressWindow.stage.align = StageAlign.TOP_LEFT;
            _progressWindow.width = _progressBox.width;
            _progressWindow.height = _progressBox.height;
            _progressWindow.addEventListener(Event.CLOSE, cancelDownload);
            _progressBox.addEventListener(Event.CLOSE, cancelDownload);
            _progressWindow.title = "Downloading...";
            _progressWindow.stage.addChild(_progressBox);
            _progressWindow.activate();
        }

        private function onProgressDownload(e:ProgressEvent):void{
            _progressBox.setProgress(e.bytesLoaded/e.bytesTotal);
        }

        private function cancelDownload(e:Event):void{
            if(_progressWindow){
                try{
                    _swfUrlLoader.close();
                    _progressWindow.close();
                    _progressWindow = null;
                    loadAndRunLocalSwf();
                }
                catch(e:Error){}
            }
        }

        private function closeApplication(e:Event):void{
            NativeApplication.nativeApplication.exit();
        }
    }
}


246
3
задан 14 июня 2011 в 06:06 Источник Поделиться
Комментарии