home *** CD-ROM | disk | FTP | other *** search
/ Computer Active 2010 August / CA08.iso / Multimedija / shufflr.air / ShufflrClient.swf / scripts / air / update / ApplicationUpdater.as next >
Encoding:
Text File  |  2010-06-23  |  19.1 KB  |  556 lines

  1. package air.update
  2. {
  3.    import air.update.core.UpdaterConfiguration;
  4.    import air.update.core.UpdaterHSM;
  5.    import air.update.core.UpdaterState;
  6.    import air.update.events.DownloadErrorEvent;
  7.    import air.update.events.StatusFileUpdateErrorEvent;
  8.    import air.update.events.StatusFileUpdateEvent;
  9.    import air.update.events.StatusUpdateErrorEvent;
  10.    import air.update.events.StatusUpdateEvent;
  11.    import air.update.events.UpdateEvent;
  12.    import air.update.logging.Logger;
  13.    import air.update.states.HSM;
  14.    import air.update.states.HSMEvent;
  15.    import air.update.states.UpdateState;
  16.    import air.update.utils.Constants;
  17.    import air.update.utils.FileUtils;
  18.    import air.update.utils.VersionUtils;
  19.    import flash.desktop.Updater;
  20.    import flash.events.ErrorEvent;
  21.    import flash.events.Event;
  22.    import flash.events.ProgressEvent;
  23.    import flash.events.TimerEvent;
  24.    import flash.filesystem.File;
  25.    import flash.utils.Timer;
  26.    
  27.    public class ApplicationUpdater extends HSM
  28.    {
  29.       private static var logger:Logger = Logger.getLogger("air.update.ApplicationUpdater");
  30.       
  31.       private static const EVENT_INITIALIZE:String = "initialize";
  32.       
  33.       private static const EVENT_CHECK_URL:String = "check.url";
  34.       
  35.       private static const EVENT_CHECK_FILE:String = "check.file";
  36.       
  37.       protected var state:UpdaterState;
  38.       
  39.       private var _isFirstRun:Boolean = false;
  40.       
  41.       private var _previousVersion:String = "";
  42.       
  43.       private var _wasPendingUpdate:Boolean = false;
  44.       
  45.       private var installFile:File = null;
  46.       
  47.       protected var updaterHSM:UpdaterHSM;
  48.       
  49.       private var _previousStorage:File = null;
  50.       
  51.       private var isInitialized:Boolean = false;
  52.       
  53.       private var timer:Timer;
  54.       
  55.       protected var configuration:UpdaterConfiguration;
  56.       
  57.       public function ApplicationUpdater()
  58.       {
  59.          super(this.stateUninitialized);
  60.          init();
  61.          this.configuration = new UpdaterConfiguration();
  62.          this.state = new UpdaterState();
  63.          this.updaterHSM = new UpdaterHSM();
  64.          this.updaterHSM.configuration = this.configuration;
  65.          this.updaterHSM.addEventListener(UpdateEvent.CHECK_FOR_UPDATE,dispatch);
  66.          this.updaterHSM.addEventListener(StatusUpdateEvent.UPDATE_STATUS,dispatch);
  67.          this.updaterHSM.addEventListener(UpdateEvent.DOWNLOAD_START,dispatch);
  68.          this.updaterHSM.addEventListener(ProgressEvent.PROGRESS,dispatch);
  69.          this.updaterHSM.addEventListener(UpdateEvent.DOWNLOAD_COMPLETE,dispatch);
  70.          this.updaterHSM.addEventListener(UpdateEvent.BEFORE_INSTALL,dispatch);
  71.          this.updaterHSM.addEventListener(StatusUpdateErrorEvent.UPDATE_ERROR,dispatch);
  72.          this.updaterHSM.addEventListener(DownloadErrorEvent.DOWNLOAD_ERROR,dispatch);
  73.          this.updaterHSM.addEventListener(UpdaterHSM.EVENT_INSTALL_TRIGGER,dispatch);
  74.          this.updaterHSM.addEventListener(UpdaterHSM.EVENT_FILE_INSTALL_TRIGGER,dispatch);
  75.          this.updaterHSM.addEventListener(UpdaterHSM.EVENT_STATE_CLEAR_TRIGGER,this.onStateClear);
  76.          this.updaterHSM.addEventListener(ErrorEvent.ERROR,dispatch);
  77.          this.updaterHSM.addEventListener(StatusFileUpdateEvent.FILE_UPDATE_STATUS,dispatch);
  78.          this.updaterHSM.addEventListener(StatusFileUpdateErrorEvent.FILE_UPDATE_ERROR,dispatch);
  79.          this.timer = new Timer(0);
  80.          this.timer.addEventListener(TimerEvent.TIMER,this.onTimer);
  81.       }
  82.       
  83.       public function get delay() : Number
  84.       {
  85.          return this.configuration.delay;
  86.       }
  87.       
  88.       public function get isFirstRun() : Boolean
  89.       {
  90.          return this._isFirstRun;
  91.       }
  92.       
  93.       public function set delay(param1:Number) : void
  94.       {
  95.          this.configuration.delay = param1;
  96.          if(this.isInitialized)
  97.          {
  98.             this.handlePeriodicalCheck();
  99.          }
  100.       }
  101.       
  102.       protected function stateUninitialized(param1:Event) : void
  103.       {
  104.          logger.finest("stateUninitialized: " + param1.type);
  105.          switch(param1.type)
  106.          {
  107.             case HSMEvent.ENTER:
  108.                this.isInitialized = false;
  109.                break;
  110.             case EVENT_INITIALIZE:
  111.                transition(this.stateInitializing);
  112.          }
  113.       }
  114.       
  115.       public function get isNewerVersionFunction() : Function
  116.       {
  117.          return this.configuration.isNewerVersionFunction;
  118.       }
  119.       
  120.       public function initialize() : void
  121.       {
  122.          dispatch(new Event(EVENT_INITIALIZE));
  123.       }
  124.       
  125.       protected function stateReady(param1:Event) : void
  126.       {
  127.          logger.finest("stateReady: " + param1.type);
  128.          switch(param1.type)
  129.          {
  130.             case HSMEvent.ENTER:
  131.                break;
  132.             case EVENT_CHECK_URL:
  133.                transition(this.stateRunning);
  134.                dispatch(param1);
  135.                break;
  136.             case EVENT_CHECK_FILE:
  137.                transition(this.stateRunning);
  138.                dispatch(param1);
  139.                break;
  140.             case ErrorEvent.ERROR:
  141.                dispatchEvent(param1);
  142.          }
  143.       }
  144.       
  145.       public function set isNewerVersionFunction(param1:Function) : void
  146.       {
  147.          this.configuration.isNewerVersionFunction = param1;
  148.       }
  149.       
  150.       protected function handleFirstRun() : Boolean
  151.       {
  152.          var updateFile:File = null;
  153.          var updater:Updater = null;
  154.          var result:Boolean = true;
  155.          if(!this.state.descriptor.currentVersion)
  156.          {
  157.             return true;
  158.          }
  159.          if(this.state.descriptor.updaterLaunched)
  160.          {
  161.             this._wasPendingUpdate = true;
  162.             if(this.state.descriptor.currentVersion == VersionUtils.getApplicationVersion())
  163.             {
  164.                this._isFirstRun = true;
  165.                this._previousVersion = this.state.descriptor.previousVersion;
  166.                if(this.state.descriptor.storage.nativePath != File.applicationStorageDirectory.nativePath)
  167.                {
  168.                   this._previousStorage = this.state.descriptor.storage;
  169.                }
  170.                this.state.removeAllFailedUpdates();
  171.                this.state.resetUpdateData();
  172.                this.state.removePreviousStorageData(this._previousStorage);
  173.                this.state.saveToStorage();
  174.             }
  175.             else if(this.state.descriptor.previousVersion == VersionUtils.getApplicationVersion())
  176.             {
  177.                this.state.addFailedUpdate(this.state.descriptor.currentVersion);
  178.                this.state.resetUpdateData();
  179.                this.state.saveToStorage();
  180.             }
  181.             else
  182.             {
  183.                this._wasPendingUpdate = false;
  184.                this.state.removeAllFailedUpdates();
  185.                this.state.resetUpdateData();
  186.                this.state.saveToStorage();
  187.             }
  188.          }
  189.          else if(this.state.descriptor.previousVersion == VersionUtils.getApplicationVersion())
  190.          {
  191.             updateFile = FileUtils.getLocalUpdateFile();
  192.             if(!updateFile.exists)
  193.             {
  194.                this.state.resetUpdateData();
  195.                return true;
  196.             }
  197.             try
  198.             {
  199.                this.state.descriptor.updaterLaunched = true;
  200.                this.state.saveToStorage();
  201.                this.state.saveToDocuments();
  202.                updater = new Updater();
  203.                updater.update(updateFile,this.state.descriptor.currentVersion);
  204.                result = false;
  205.             }
  206.             catch(e:Error)
  207.             {
  208.                logger.warning("The application cannot be updated when is launched from ADL." + e.message);
  209.                state.resetUpdateData();
  210.                state.saveToStorage();
  211.             }
  212.          }
  213.          else if(this.state.descriptor.currentVersion == VersionUtils.getApplicationVersion())
  214.          {
  215.             this.state.removeAllFailedUpdates();
  216.             this.state.resetUpdateData();
  217.             this.state.saveToStorage();
  218.          }
  219.          else
  220.          {
  221.             this.state.removeAllFailedUpdates();
  222.             this.state.resetUpdateData();
  223.             this.state.saveToStorage();
  224.          }
  225.          return result;
  226.       }
  227.       
  228.       public function get currentVersion() : String
  229.       {
  230.          return VersionUtils.getApplicationVersion();
  231.       }
  232.       
  233.       protected function onFileInstall() : void
  234.       {
  235.          var updater:Updater = null;
  236.          var updateFile:File = this.updaterHSM.airFile;
  237.          if(!updateFile.exists)
  238.          {
  239.             logger.finest("Update file doesn\'t exist at update");
  240.             this.state.resetUpdateData();
  241.             this.state.saveToStorage();
  242.             this.updaterHSM.cancel();
  243.             throw new Error("Missing update file at install time",Constants.ERROR_APPLICATION_UPDATE_NO_FILE);
  244.          }
  245.          try
  246.          {
  247.             this.state.descriptor.updaterLaunched = true;
  248.             this.state.saveToStorage();
  249.             this.state.saveToDocuments();
  250.             updater = new Updater();
  251.             updater.update(updateFile,this.updaterHSM.applicationDescriptor.version);
  252.          }
  253.          catch(e:Error)
  254.          {
  255.             logger.warning("The application cannot be updated (file)." + e.message);
  256.             state.resetUpdateData();
  257.             state.saveToStorage();
  258.             updaterHSM.cancel();
  259.             throw new Error("Cannot update (from file)",Constants.ERROR_APPLICATION_UPDATE);
  260.          }
  261.       }
  262.       
  263.       public function get configurationFile() : File
  264.       {
  265.          return this.configuration.configurationFile;
  266.       }
  267.       
  268.       protected function dispatchProxy(param1:Event) : void
  269.       {
  270.          if(param1.type != ProgressEvent.PROGRESS)
  271.          {
  272.             logger.info("Dispatching event ",param1);
  273.          }
  274.          if(!dispatchEvent(param1))
  275.          {
  276.             param1.preventDefault();
  277.          }
  278.       }
  279.       
  280.       protected function onTimer(param1:TimerEvent) : void
  281.       {
  282.          var _loc2_:* = this.timer.currentCount == this.timer.repeatCount;
  283.          this.handlePeriodicalCheck();
  284.          if(_loc2_)
  285.          {
  286.             dispatch(new Event(EVENT_CHECK_URL));
  287.          }
  288.       }
  289.       
  290.       public function get updateDescriptor() : XML
  291.       {
  292.          if(this.updaterHSM.descriptor)
  293.          {
  294.             return this.updaterHSM.descriptor.getXML();
  295.          }
  296.          return null;
  297.       }
  298.       
  299.       public function set configurationFile(param1:File) : void
  300.       {
  301.          this.configuration.configurationFile = param1;
  302.       }
  303.       
  304.       public function checkNow() : void
  305.       {
  306.          dispatch(new Event(EVENT_CHECK_URL));
  307.       }
  308.       
  309.       public function get currentState() : String
  310.       {
  311.          if(!this.isInitialized)
  312.          {
  313.             return UpdateState.getStateName(UpdateState.UNINITIALIZED);
  314.          }
  315.          return UpdateState.getStateName(this.updaterHSM.getUpdateState());
  316.       }
  317.       
  318.       public function get previousApplicationStorageDirectory() : File
  319.       {
  320.          return this._previousStorage;
  321.       }
  322.       
  323.       protected function onInitializationComplete() : void
  324.       {
  325.          dispatch(new UpdateEvent(UpdateEvent.INITIALIZED));
  326.       }
  327.       
  328.       protected function onInstall() : void
  329.       {
  330.          var updater:Updater = null;
  331.          var updateFile:File = FileUtils.getLocalUpdateFile();
  332.          if(!updateFile.exists)
  333.          {
  334.             logger.finest("Update file doesn\'t exist at update");
  335.             this.state.resetUpdateData();
  336.             this.state.saveToStorage();
  337.             this.updaterHSM.cancel();
  338.             throw new Error("Missing update file  at install time",Constants.ERROR_APPLICATION_UPDATE_NO_FILE);
  339.          }
  340.          try
  341.          {
  342.             this.state.descriptor.updaterLaunched = true;
  343.             this.state.saveToStorage();
  344.             this.state.saveToDocuments();
  345.             updater = new Updater();
  346.             updater.update(updateFile,this.updaterHSM.descriptor.version);
  347.          }
  348.          catch(e:Error)
  349.          {
  350.             logger.warning("The application cannot be updated (url)." + e.message);
  351.             state.resetUpdateData();
  352.             state.saveToStorage();
  353.             updaterHSM.cancel();
  354.             throw new Error("Cannot update (from remote)",Constants.ERROR_APPLICATION_UPDATE);
  355.          }
  356.       }
  357.       
  358.       protected function stateCancelled(param1:Event) : void
  359.       {
  360.          logger.finest("stateCancelled: " + param1.type);
  361.          switch(param1.type)
  362.          {
  363.             case HSMEvent.ENTER:
  364.                this.updaterHSM.cancel();
  365.                transition(this.stateReady);
  366.          }
  367.       }
  368.       
  369.       public function installFromAIRFile(param1:File) : void
  370.       {
  371.          this.installFile = param1;
  372.          dispatch(new Event(EVENT_CHECK_FILE));
  373.          this.updaterHSM.installFile(param1);
  374.       }
  375.       
  376.       public function installUpdate() : void
  377.       {
  378.          dispatch(new Event(UpdaterHSM.EVENT_INSTALL));
  379.       }
  380.       
  381.       protected function onFileStatus(param1:StatusFileUpdateEvent) : void
  382.       {
  383.          if(param1.available)
  384.          {
  385.             this.state.descriptor.previousVersion = VersionUtils.getApplicationVersion();
  386.             this.state.descriptor.currentVersion = param1.version;
  387.             this.state.descriptor.storage = File.applicationStorageDirectory;
  388.             this.state.saveToStorage();
  389.          }
  390.          this.dispatchProxy(param1);
  391.       }
  392.       
  393.       protected function onInitialize() : void
  394.       {
  395.          this.configuration.validate();
  396.          this.state.load();
  397.          if(this.handleFirstRun())
  398.          {
  399.             this.onInitializationComplete();
  400.          }
  401.       }
  402.       
  403.       public function checkForUpdate() : void
  404.       {
  405.          dispatch(new Event(UpdaterHSM.EVENT_CHECK));
  406.       }
  407.       
  408.       public function set updateURL(param1:String) : void
  409.       {
  410.          this.configuration.updateURL = param1;
  411.       }
  412.       
  413.       public function get wasPendingUpdate() : Boolean
  414.       {
  415.          return this._wasPendingUpdate;
  416.       }
  417.       
  418.       protected function handlePeriodicalCheck() : void
  419.       {
  420.          var _loc2_:Number = NaN;
  421.          var _loc3_:Number = NaN;
  422.          logger.finest("PeriodicalCheck: " + this.configuration.delay);
  423.          if(this.configuration.delay == 0)
  424.          {
  425.             return;
  426.          }
  427.          this.timer.reset();
  428.          this.timer.repeatCount = 1;
  429.          var _loc1_:Number = new Date().time - this.state.descriptor.lastCheckDate.time;
  430.          logger.finest("Difference: " + _loc1_ + " > " + this.configuration.delayAsMilliseconds + "(" + this.state.descriptor.lastCheckDate + ")");
  431.          if(_loc1_ > this.configuration.delayAsMilliseconds)
  432.          {
  433.             this.timer.delay = 1;
  434.          }
  435.          else
  436.          {
  437.             _loc2_ = this.configuration.delayAsMilliseconds - _loc1_;
  438.             _loc3_ = Math.floor(_loc2_ / Constants.DAY_IN_MILLISECONDS) + 1;
  439.             if(_loc2_ > Constants.DAY_IN_MILLISECONDS)
  440.             {
  441.                _loc2_ = Constants.DAY_IN_MILLISECONDS;
  442.             }
  443.             this.timer.delay = _loc2_;
  444.             this.timer.repeatCount = _loc3_;
  445.          }
  446.          this.timer.start();
  447.          logger.finest("PeriodicalCheck: started with delay: " + this.timer.delay + " and count: " + this.timer.repeatCount);
  448.       }
  449.       
  450.       protected function onDownloadComplete(param1:UpdateEvent) : void
  451.       {
  452.          this.state.descriptor.previousVersion = VersionUtils.getApplicationVersion();
  453.          this.state.descriptor.currentVersion = this.updaterHSM.descriptor.version;
  454.          this.state.descriptor.storage = File.applicationStorageDirectory;
  455.          this.state.saveToStorage();
  456.          this.dispatchProxy(param1);
  457.       }
  458.       
  459.       public function get previousVersion() : String
  460.       {
  461.          return this._previousVersion;
  462.       }
  463.       
  464.       public function cancelUpdate() : void
  465.       {
  466.          transition(this.stateCancelled);
  467.       }
  468.       
  469.       public function get updateURL() : String
  470.       {
  471.          return this.configuration.updateURL;
  472.       }
  473.       
  474.       public function downloadUpdate() : void
  475.       {
  476.          dispatch(new Event(UpdaterHSM.EVENT_DOWNLOAD));
  477.       }
  478.       
  479.       protected function stateRunning(param1:Event) : void
  480.       {
  481.          logger.finest("stateRunning: " + param1.type);
  482.          switch(param1.type)
  483.          {
  484.             case HSMEvent.ENTER:
  485.                break;
  486.             case EVENT_CHECK_URL:
  487.                this.state.descriptor.lastCheckDate = new Date();
  488.                this.state.saveToStorage();
  489.                this.handlePeriodicalCheck();
  490.                this.updaterHSM.checkAsync(this.configuration.updateURL);
  491.                break;
  492.             case EVENT_CHECK_FILE:
  493.                this.updaterHSM.installFile(this.installFile);
  494.                break;
  495.             case UpdaterHSM.EVENT_CHECK:
  496.             case UpdaterHSM.EVENT_DOWNLOAD:
  497.             case UpdaterHSM.EVENT_INSTALL:
  498.                this.updaterHSM.dispatch(param1);
  499.                break;
  500.             case UpdateEvent.CHECK_FOR_UPDATE:
  501.             case StatusUpdateEvent.UPDATE_STATUS:
  502.             case UpdateEvent.DOWNLOAD_START:
  503.             case ProgressEvent.PROGRESS:
  504.             case UpdateEvent.BEFORE_INSTALL:
  505.                this.dispatchProxy(param1);
  506.                break;
  507.             case StatusUpdateErrorEvent.UPDATE_ERROR:
  508.             case DownloadErrorEvent.DOWNLOAD_ERROR:
  509.             case StatusFileUpdateErrorEvent.FILE_UPDATE_ERROR:
  510.             case ErrorEvent.ERROR:
  511.                this.dispatchProxy(param1);
  512.                transition(this.stateReady);
  513.                break;
  514.             case StatusFileUpdateEvent.FILE_UPDATE_STATUS:
  515.                this.onFileStatus(param1 as StatusFileUpdateEvent);
  516.                break;
  517.             case UpdateEvent.DOWNLOAD_COMPLETE:
  518.                this.onDownloadComplete(param1 as UpdateEvent);
  519.                break;
  520.             case UpdaterHSM.EVENT_INSTALL_TRIGGER:
  521.                this.onInstall();
  522.                break;
  523.             case UpdaterHSM.EVENT_FILE_INSTALL_TRIGGER:
  524.                this.onFileInstall();
  525.          }
  526.       }
  527.       
  528.       protected function onStateClear(param1:Event) : void
  529.       {
  530.          this.state.resetUpdateData();
  531.          this.state.saveToStorage();
  532.       }
  533.       
  534.       protected function stateInitializing(param1:Event) : void
  535.       {
  536.          logger.finest("stateInitializing: " + param1.type);
  537.          switch(param1.type)
  538.          {
  539.             case HSMEvent.ENTER:
  540.                this.onInitialize();
  541.                break;
  542.             case UpdateEvent.INITIALIZED:
  543.                this.isInitialized = true;
  544.                transition(this.stateReady);
  545.                dispatchEvent(param1);
  546.                this.handlePeriodicalCheck();
  547.                break;
  548.             case ErrorEvent.ERROR:
  549.                transition(this.stateUninitialized);
  550.                dispatchEvent(param1.clone());
  551.          }
  552.       }
  553.    }
  554. }
  555.  
  556.