From ef3a12f01a57b74d8bca2db1d9035d3e2fa7b25a Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Fri, 7 Feb 2014 15:40:23 +0000
Subject: [PATCH]  * UpdateManager:    - Convert to RouterApp and remove update
 hooks from context      (ticket #1185)

---
 .../src/org/klomp/snark/SnarkManager.java     |  5 +-
 .../router/update/ConsoleUpdateManager.java   | 81 +++++++++++++++++--
 .../i2p/router/web/ConfigClientsHandler.java  |  4 +-
 .../i2p/router/web/ConfigUpdateHandler.java   |  2 +-
 .../src/net/i2p/router/web/PluginStarter.java |  2 +-
 .../i2p/router/web/RouterConsoleRunner.java   |  2 +-
 .../src/net/i2p/router/web/UpdateHandler.java | 15 +++-
 apps/routerconsole/jsp/debug.jsp              |  9 ++-
 core/java/src/net/i2p/I2PAppContext.java      |  9 ---
 .../src/net/i2p/update/UpdateManager.java     |  6 ++
 .../src/net/i2p/router/RouterContext.java     | 38 +--------
 11 files changed, 114 insertions(+), 59 deletions(-)

diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
index 3fe2b2ade3..21ffac7586 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
@@ -24,6 +24,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.LinkedBlockingQueue;
 
 import net.i2p.I2PAppContext;
+import net.i2p.app.ClientAppManager;
 import net.i2p.data.Base64;
 import net.i2p.data.DataHelper;
 import net.i2p.update.*;
@@ -198,7 +199,9 @@ public class SnarkManager implements CompleteListener {
         public void timeReached() {
             if (!_running)
                 return;
-            _umgr = _context.updateManager();
+            ClientAppManager cmgr = _context.clientAppManager();
+            if (cmgr != null)
+                _umgr = (UpdateManager) cmgr.getRegisteredApp(UpdateManager.APP_NAME);
             if (_umgr != null) {
                 _uhandler = new UpdateHandler(_context, _umgr, SnarkManager.this);
                 _umgr.register(_uhandler, UpdateType.ROUTER_SIGNED, UpdateMethod.TORRENT, 10);
diff --git a/apps/routerconsole/java/src/net/i2p/router/update/ConsoleUpdateManager.java b/apps/routerconsole/java/src/net/i2p/router/update/ConsoleUpdateManager.java
index 6efc217a92..84d656abec 100644
--- a/apps/routerconsole/java/src/net/i2p/router/update/ConsoleUpdateManager.java
+++ b/apps/routerconsole/java/src/net/i2p/router/update/ConsoleUpdateManager.java
@@ -17,12 +17,16 @@ import java.util.StringTokenizer;
 import java.util.concurrent.ConcurrentHashMap;
 
 import net.i2p.I2PAppContext;
+import net.i2p.app.ClientAppManager;
+import net.i2p.app.ClientAppState;
+import static net.i2p.app.ClientAppState.*;
 import net.i2p.crypto.SU3File;
 import net.i2p.crypto.TrustedUpdate;
 import net.i2p.data.DataHelper;
 import net.i2p.router.Router;
 import net.i2p.router.RouterContext;
 import net.i2p.router.RouterVersion;
+import net.i2p.router.app.RouterApp;
 import net.i2p.router.web.ConfigServiceHandler;
 import net.i2p.router.web.ConfigUpdateHandler;
 import net.i2p.router.web.Messages;
@@ -50,7 +54,7 @@ import net.i2p.util.VersionComparator;
  *
  *  @since 0.9.4
  */
-public class ConsoleUpdateManager implements UpdateManager {
+public class ConsoleUpdateManager implements UpdateManager, RouterApp {
     
     private final RouterContext _context;
     private final Log _log;
@@ -68,6 +72,8 @@ public class ConsoleUpdateManager implements UpdateManager {
     private final Map<UpdateItem, Version> _installed;
     private final boolean _allowTorrent;
     private static final DecimalFormat _pct = new DecimalFormat("0.0%");
+    private final ClientAppManager _cmgr;
+    private volatile ClientAppState _state = UNINITIALIZED;
 
     private volatile String _status;
 
@@ -77,8 +83,12 @@ public class ConsoleUpdateManager implements UpdateManager {
     private static final long TASK_CLEANER_TIME = 15*60*1000;
     private static final String PROP_UNSIGNED_AVAILABLE = "router.updateUnsignedAvailable";
 
-    public ConsoleUpdateManager(RouterContext ctx) {
+    /**
+     *  @param args ignored
+     */
+    public ConsoleUpdateManager(RouterContext ctx, ClientAppManager listener, String[] args) {
         _context = ctx;
+        _cmgr = listener;
         _log = ctx.logManager().getLog(ConsoleUpdateManager.class);
         _registeredUpdaters = new ConcurrentHashSet<RegisteredUpdater>();
         _registeredCheckers = new ConcurrentHashSet<RegisteredChecker>();
@@ -98,13 +108,34 @@ public class ConsoleUpdateManager implements UpdateManager {
         //_allowTorrent = RouterVersion.BUILD != 0 || _context.random().nextInt(100) < 60;
         // Finally, for 0.9.12, 18 months later...
         _allowTorrent = true;
+        _state = INITIALIZED;
     }
 
+    /**
+     *  @return null if not found
+     */
     public static ConsoleUpdateManager getInstance() {
-        return (ConsoleUpdateManager) I2PAppContext.getGlobalContext().updateManager();
+        ClientAppManager cmgr = I2PAppContext.getGlobalContext().clientAppManager();
+        if (cmgr == null)
+            return null;
+        return (ConsoleUpdateManager) cmgr.getRegisteredApp(APP_NAME);
     }
 
+    /////// ClientApp methods
+
+    /**
+     *  UpdateManager interface
+     */
     public void start() {
+        startup();
+    }
+
+    /**
+     *  ClientApp interface
+     *  @since 0.9.12
+     */
+    public synchronized void startup() {
+        changeState(STARTING);
         notifyInstalled(NEWS, "", Long.toString(NewsHelper.lastUpdated(_context)));
         notifyInstalled(ROUTER_SIGNED, "", RouterVersion.VERSION);
         notifyInstalled(ROUTER_SIGNED_SU3, "", RouterVersion.VERSION);
@@ -118,7 +149,6 @@ public class ConsoleUpdateManager implements UpdateManager {
                 notifyInstalled(PLUGIN, plugin, ver);
         }
 
-        _context.registerUpdateManager(this);
         DummyHandler dh = new DummyHandler(_context, this);
         register((Checker)dh, TYPE_DUMMY, METHOD_DUMMY, 0);
         register((Updater)dh, TYPE_DUMMY, METHOD_DUMMY, 0);
@@ -162,10 +192,27 @@ public class ConsoleUpdateManager implements UpdateManager {
         //register((Updater)puh, PLUGIN, FILE, 0);
         new NewsTimerTask(_context, this);
         _context.simpleScheduler().addPeriodicEvent(new TaskCleaner(), TASK_CLEANER_TIME);
+        changeState(RUNNING);
+        if (_cmgr != null)
+            _cmgr.register(this);
     }
 
+    /**
+     *  UpdateManager interface
+     */
     public void shutdown() {
-        _context.unregisterUpdateManager(this);
+        shutdown(null);
+    }
+
+    /**
+     *  ClientApp interface
+     *  @param args ignored
+     *  @since 0.9.12
+     */
+    public synchronized void shutdown(String[] args) {
+        if (_state == STOPPED)
+            return;
+        changeState(STOPPING);
         stopChecks();
         stopUpdates();
         _registeredUpdaters.clear();
@@ -173,6 +220,30 @@ public class ConsoleUpdateManager implements UpdateManager {
         _available.clear();
         _downloaded.clear();
         _installed.clear();
+        changeState(STOPPED);
+    }
+
+    /** @since 0.9.12 */
+    public ClientAppState getState() {
+        return _state;
+    }
+
+    /** @since 0.9.12 */
+    public String getName() {
+        return APP_NAME;
+    }
+
+    /** @since 0.9.12 */
+    public String getDisplayName() {
+        return "Console Update Manager";
+    }
+
+    /////// end ClientApp methods
+
+    private synchronized void changeState(ClientAppState state) {
+        _state = state;
+        if (_cmgr != null)
+            _cmgr.notify(this, state, null, null);
     }
 
     /**
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java
index b5f1e1c51f..09a0def7cf 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java
@@ -370,7 +370,7 @@ public class ConfigClientsHandler extends FormHandler {
      *  @param app null for a new install
      */
     private void installPlugin(String app, String url) {
-        ConsoleUpdateManager mgr = (ConsoleUpdateManager) _context.updateManager();
+        ConsoleUpdateManager mgr = UpdateHandler.updateManager(_context);
         if (mgr == null) {
             addFormError("Update manager not registered, cannot install");
             return;
@@ -397,7 +397,7 @@ public class ConfigClientsHandler extends FormHandler {
     }
 
     private void checkPlugin(String app) {
-        ConsoleUpdateManager mgr = (ConsoleUpdateManager) _context.updateManager();
+        ConsoleUpdateManager mgr = UpdateHandler.updateManager(_context);
         if (mgr == null) {
             addFormError("Update manager not registered, cannot check");
             return;
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java
index 09f00c388c..bbf8d390c9 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java
@@ -139,7 +139,7 @@ public class ConfigUpdateHandler extends FormHandler {
         if (_action == null)
             return;
         if (_action.equals(_("Check for updates"))) {
-            ConsoleUpdateManager mgr = (ConsoleUpdateManager) _context.updateManager();
+            ConsoleUpdateManager mgr = UpdateHandler.updateManager(_context);
             if (mgr == null) {
                 addFormError("Update manager not registered, cannot check");
                 return;
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java b/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java
index 24633f495c..cb09a1e5eb 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java
@@ -121,7 +121,7 @@ public class PluginStarter implements Runnable {
         if (toUpdate.isEmpty())
             return;
 
-        ConsoleUpdateManager mgr = (ConsoleUpdateManager) ctx.updateManager();
+        ConsoleUpdateManager mgr = UpdateHandler.updateManager(ctx);
         if (mgr == null)
             return;
         if (mgr.isUpdateInProgress())
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java
index b931b0bee7..b8799df161 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java
@@ -645,7 +645,7 @@ public class RouterConsoleRunner implements RouterApp {
         t.setPriority(Thread.NORM_PRIORITY - 1);
         t.start();
         
-            ConsoleUpdateManager um = new ConsoleUpdateManager(_context);
+            ConsoleUpdateManager um = new ConsoleUpdateManager(_context, _mgr, null);
             um.start();
         
             if (PluginStarter.pluginsEnabled(_context)) {
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/UpdateHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/UpdateHandler.java
index 4148a63afa..cf2b737a21 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/UpdateHandler.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/UpdateHandler.java
@@ -1,7 +1,9 @@
 package net.i2p.router.web;
 
+import net.i2p.app.ClientAppManager;
 import net.i2p.router.RouterContext;
 import net.i2p.router.update.ConsoleUpdateManager;
+import net.i2p.update.UpdateManager;
 import net.i2p.update.UpdateType;
 import static net.i2p.update.UpdateType.*;
 import net.i2p.util.Log;
@@ -33,6 +35,17 @@ public class UpdateHandler {
         _context = ctx;
         _log = ctx.logManager().getLog(UpdateHandler.class);
     }
+
+    /**
+     *  @return null if not found
+     *  @since 0.9.12
+     */
+    public static ConsoleUpdateManager updateManager(RouterContext ctx) {
+        ClientAppManager cmgr = ctx.clientAppManager();
+        if (cmgr == null)
+            return null;
+        return (ConsoleUpdateManager) cmgr.getRegisteredApp(UpdateManager.APP_NAME);
+    }
     
     /**
      * Configure this bean to query a particular router context
@@ -75,7 +88,7 @@ public class UpdateHandler {
     }
 
     private void update(UpdateType type) {
-        ConsoleUpdateManager mgr = (ConsoleUpdateManager) _context.updateManager();
+        ConsoleUpdateManager mgr = updateManager(_context);
         if (mgr == null)
             return;
         if (mgr.isUpdateInProgress(ROUTER_SIGNED) || mgr.isUpdateInProgress(ROUTER_UNSIGNED) ||
diff --git a/apps/routerconsole/jsp/debug.jsp b/apps/routerconsole/jsp/debug.jsp
index f36e9f31ff..7744f651d4 100644
--- a/apps/routerconsole/jsp/debug.jsp
+++ b/apps/routerconsole/jsp/debug.jsp
@@ -30,7 +30,14 @@
     /*
      *  Print out the status for the UpdateManager
      */
-    ctx.updateManager().renderStatusHTML(out);
+    net.i2p.app.ClientAppManager cmgr = ctx.clientAppManager();
+    if (cmgr != null) {
+        net.i2p.router.update.ConsoleUpdateManager umgr =
+            (net.i2p.router.update.ConsoleUpdateManager) cmgr.getRegisteredApp(net.i2p.update.UpdateManager.APP_NAME);
+        if (umgr != null) {
+            umgr.renderStatusHTML(out);
+        }
+    }
 
     /*
      *  Print out the status for the AppManager
diff --git a/core/java/src/net/i2p/I2PAppContext.java b/core/java/src/net/i2p/I2PAppContext.java
index d20ceb982d..4eb2fcdbdb 100644
--- a/core/java/src/net/i2p/I2PAppContext.java
+++ b/core/java/src/net/i2p/I2PAppContext.java
@@ -1017,15 +1017,6 @@ public class I2PAppContext {
         }
     }
 
-    /**
-     *  The controller of router, plugin, and other updates.
-     *  @return always null in I2PAppContext, the update manager if in RouterContext and it is registered
-     *  @since 0.9.4
-     */
-    public UpdateManager updateManager() {
-        return null;
-    }
-
     /**
      *  The RouterAppManager in RouterContext, null always in I2PAppContext
      *  @return null always
diff --git a/core/java/src/net/i2p/update/UpdateManager.java b/core/java/src/net/i2p/update/UpdateManager.java
index 3a1315812b..ce18c59ee9 100644
--- a/core/java/src/net/i2p/update/UpdateManager.java
+++ b/core/java/src/net/i2p/update/UpdateManager.java
@@ -18,6 +18,12 @@ import java.util.Map;
  */
 public interface UpdateManager {
     
+    /**
+     *  The name we register with the ClientAppManager
+     *  @since 0.9.12
+     */
+    public static final String APP_NAME = "update";
+
     /**
      *  Call once for each type/method pair.
      */
diff --git a/router/java/src/net/i2p/router/RouterContext.java b/router/java/src/net/i2p/router/RouterContext.java
index ba837ccf2d..0afd98a7b5 100644
--- a/router/java/src/net/i2p/router/RouterContext.java
+++ b/router/java/src/net/i2p/router/RouterContext.java
@@ -67,7 +67,7 @@ public class RouterContext extends I2PAppContext {
     private final Set<Runnable> _finalShutdownTasks;
     // split up big lock on this to avoid deadlocks
     private volatile boolean _initialized;
-    private final Object _lock1 = new Object(), _lock2 = new Object(), _lock3 = new Object();
+    private final Object _lock1 = new Object(), _lock2 = new Object();
 
     private static final List<RouterContext> _contexts = new CopyOnWriteArrayList<RouterContext>();
     
@@ -546,42 +546,6 @@ public class RouterContext extends I2PAppContext {
         return _internalClientManager;
     }
 
-    /**
-     *  The controller of router, plugin, and other updates.
-     *  @return The manager if it is registered, else null
-     *  @since 0.9.4
-     */
-    @Override
-    public UpdateManager updateManager() {
-        return _updateManager;
-    }
-
-    /**
-     *  Register as the update manager.
-     *  @throws IllegalStateException if one was already registered
-     *  @since 0.9.4
-     */
-    public void registerUpdateManager(UpdateManager mgr) {
-        synchronized(_lock3) {
-            if (_updateManager != null)
-                throw new IllegalStateException();
-            _updateManager = mgr;
-        }
-    }
-
-    /**
-     *  Unregister the update manager.
-     *  @throws IllegalStateException if it was not registered
-     *  @since 0.9.4
-     */
-    public void unregisterUpdateManager(UpdateManager mgr) {
-        synchronized(_lock3) {
-            if (_updateManager != mgr)
-                throw new IllegalStateException();
-            _updateManager = null;
-        }
-    }
-
     /**
      *  The RouterAppManager.
      *  @return the manager
-- 
GitLab