implement node addition and removal events
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Tue, 13 May 2008 06:53:33 +0000 (06:53 +0000)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Tue, 13 May 2008 06:53:33 +0000 (06:53 +0000)
git-svn-id: http://trooper/svn/projects/jSite/trunk@806 c3eda9e8-030b-0410-8277-bc7414b0a119

src/net/pterodactylus/jsite/core/Core.java
src/net/pterodactylus/jsite/core/CoreImpl.java
src/net/pterodactylus/jsite/core/CoreListener.java
src/net/pterodactylus/jsite/core/NodeListener.java
src/net/pterodactylus/jsite/core/NodeManager.java
src/net/pterodactylus/jsite/core/RequestManager.java
src/net/pterodactylus/jsite/gui/MainWindow.java
src/net/pterodactylus/jsite/gui/SwingInterface.java

index 731076b..0bf2cca 100644 (file)
@@ -23,7 +23,7 @@ import java.util.List;
 
 /**
  * Interface for the core.
- *
+ * 
  * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
  * @version $Id$
  */
@@ -31,7 +31,7 @@ public interface Core {
 
        /**
         * Adds the given listener to the list of registered listeners.
-        *
+        * 
         * @param coreListener
         *            The listener to add
         */
@@ -39,22 +39,38 @@ public interface Core {
 
        /**
         * Removes the given listener from the list of registered listeners.
-        *
+        * 
         * @param coreListener
         *            The listener to remove
         */
        public void removeCoreListener(CoreListener coreListener);
 
        /**
+        * Adds the given node to the core.
+        * 
+        * @param node
+        *            The node to add
+        */
+       public void addNode(Node node);
+
+       /**
+        * Removes the given node from the core.
+        * 
+        * @param node
+        *            The node to remove
+        */
+       public void removeNode(Node node);
+
+       /**
         * Returns the list of all configured nodes.
-        *
+        * 
         * @return All configured nodes
         */
        public List<Node> getNodes();
 
        /**
         * Returns whether the core is currently connected to the given node.
-        *
+        * 
         * @param node
         *            The node to check
         * @return <code>true</code> if the core is currently connected to the
@@ -74,7 +90,7 @@ public interface Core {
 
        /**
         * Connects to the given node.
-        *
+        * 
         * @param node
         *            The node to connect to
         */
@@ -82,7 +98,7 @@ public interface Core {
 
        /**
         * Disconnects from the given node.
-        *
+        * 
         * @param node
         *            The node to disconnect from
         */
index 9c68d44..f3ac5c0 100644 (file)
@@ -187,6 +187,30 @@ public class CoreImpl implements Core, NodeListener, RequestListener {
        }
 
        /**
+        * Notifies all listeners that a node was added to the core.
+        * 
+        * @param node
+        *            The node that was added
+        */
+       private void fireNodeAdded(Node node) {
+               for (CoreListener coreListener: coreListeners) {
+                       coreListener.nodeAdded(node);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a node was removed from the core.
+        * 
+        * @param node
+        *            The node that was removed
+        */
+       private void fireNodeRemoved(Node node) {
+               for (CoreListener coreListener: coreListeners) {
+                       coreListener.nodeRemoved(node);
+               }
+       }
+
+       /**
         * Notifies all listeners that a connection to the given node is now being
         * established.
         * 
@@ -351,6 +375,22 @@ public class CoreImpl implements Core, NodeListener, RequestListener {
        /**
         * {@inheritDoc}
         */
+       public void addNode(Node node) {
+               nodeManager.addNode(node);
+               fireNodeAdded(node);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void removeNode(Node node) {
+               nodeManager.removeNode(node);
+               fireNodeRemoved(node);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
        public void connectToNode(Node node) {
                fireNodeConnecting(node);
                nodeManager.addNode(node);
@@ -391,6 +431,20 @@ public class CoreImpl implements Core, NodeListener, RequestListener {
        /**
         * {@inheritDoc}
         */
+       public void nodeAdded(Node node) {
+               fireNodeAdded(node);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void nodeRemoved(Node node) {
+               fireNodeRemoved(node);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
        public void nodeConnected(Node node) {
                fireNodeConnected(node);
        }
index cef057a..fb109d7 100644 (file)
@@ -127,8 +127,27 @@ public interface CoreListener {
        //
 
        /**
+        * Notifies a listener that a node was added to the core.
+        * 
+        * @param node
+        *            The node that was added.
+        */
+       public void nodeAdded(Node node);
+
+       /**
+        * Notifies a listener that a node was removed from the core. Before a node
+        * is removed, it will be disconnected (and
+        * {@link #nodeDisconnected(Node, Throwable)} will be called).
+        * 
+        * @param node
+        *            The node that was removed
+        */
+       public void nodeRemoved(Node node);
+
+       /**
         * Notifies all listeners that the core started connecting to the given
-        * node.
+        * node. Before a node is connected, it will be added (and
+        * {@link #nodeAdded(Node)} will be called).
         * 
         * @param node
         *            The node that is being connected
@@ -168,4 +187,25 @@ public interface CoreListener {
         */
        public void requestAdded(Node node, Request request);
 
+       /**
+        * Notifies a listener that a request made some progress.
+        * 
+        * @param request
+        *            The request that made the progress
+        * @param totalBlocks
+        *            The total number of blocks
+        * @param requiredBlocks
+        *            The number of required blocks
+        * @param successfulBlocks
+        *            The number of successful blocks
+        * @param failedBlocks
+        *            The number of failed blocks
+        * @param fatallyFailedBlocks
+        *            The number of fatally failed blocks
+        * @param finalizedTotal
+        *            <code>true</code> if the number of total blocks is
+        *            finalized, <code>false</code> if it is not
+        */
+       public void requestProgressed(Request request, int totalBlocks, int requiredBlocks, int successfulBlocks, int failedBlocks, int fatallyFailedBlocks, boolean finalizedTotal);
+
 }
index 23f1a4c..95254c1 100644 (file)
@@ -30,6 +30,22 @@ import java.util.EventListener;
 public interface NodeListener extends EventListener {
 
        /**
+        * Notifies a listener that a node was added.
+        * 
+        * @param node
+        *            The node that was added
+        */
+       public void nodeAdded(Node node);
+
+       /**
+        * Notifies a listener that a node was removed.
+        * 
+        * @param node
+        *            The node that was removed
+        */
+       public void nodeRemoved(Node node);
+
+       /**
         * Notifies a listener that a connection to the given node was established.
         * 
         * @param node
index 70da6d6..b919cfe 100644 (file)
@@ -29,6 +29,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
@@ -47,7 +48,7 @@ import net.pterodactylus.util.logging.Logging;
  * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
  * @version $Id$
  */
-public class NodeManager implements HighLevelClientListener {
+public class NodeManager implements Iterable<Node>, HighLevelClientListener {
 
        /** Logger. */
        private static final Logger logger = Logging.getLogger(NodeManager.class.getName());
@@ -114,6 +115,30 @@ public class NodeManager implements HighLevelClientListener {
        }
 
        /**
+        * Notifies all listeners that a node was added.
+        * 
+        * @param node
+        *            The node that was added.
+        */
+       private void fireNodeAdded(Node node) {
+               for (NodeListener nodeListener: nodeListeners) {
+                       nodeListener.nodeAdded(node);
+               }
+       }
+
+       /**
+        * Notifies all listeners that a node was removed.
+        * 
+        * @param node
+        *            The node that was removed
+        */
+       private void fireNodeRemoved(Node node) {
+               for (NodeListener nodeListener: nodeListeners) {
+                       nodeListener.nodeRemoved(node);
+               }
+       }
+
+       /**
         * Notifies all listeners that the given node was connected.
         * 
         * @param node
@@ -165,6 +190,13 @@ public class NodeManager implements HighLevelClientListener {
                return nodes.contains(node);
        }
 
+       /**
+        * {@inheritDoc}
+        */
+       public Iterator<Node> iterator() {
+               return nodes.iterator();
+       }
+
        //
        // ACTIONS
        //
@@ -222,10 +254,14 @@ public class NodeManager implements HighLevelClientListener {
                        newNode.setPort(nodePort);
                        loadedNodes.add(newNode);
                }
+               logger.fine("loaded " + loadedNodes.size() + " nodes from config");
                synchronized (syncObject) {
                        nodes.clear();
                        nodes.addAll(loadedNodes);
                }
+               for (Node node: nodes) {
+                       fireNodeAdded(node);
+               }
        }
 
        /**
@@ -270,6 +306,7 @@ public class NodeManager implements HighLevelClientListener {
                synchronized (syncObject) {
                        if (!nodes.contains(node)) {
                                nodes.add(node);
+                               fireNodeAdded(node);
                        }
                }
        }
@@ -289,6 +326,7 @@ public class NodeManager implements HighLevelClientListener {
                        if (nodeClients.containsKey(node)) {
                                disconnect(node);
                        }
+                       fireNodeRemoved(node);
                }
        }
 
index f2aa23f..925573d 100644 (file)
@@ -22,7 +22,10 @@ package net.pterodactylus.jsite.core;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -53,6 +56,10 @@ public class RequestManager implements NodeListener {
        /** The node manager. */
        private NodeManager nodeManager;
 
+       /** Request lists for all nodes. */
+       @SuppressWarnings("unused")
+       private Map<Node, Set<Request>> nodeRequests = Collections.synchronizedMap(new HashMap<Node, Set<Request>>());
+
        //
        // EVENT MANAGEMENT
        //
@@ -109,6 +116,10 @@ public class RequestManager implements NodeListener {
        // ACTIONS
        //
 
+       //
+       // PRIVATE ACTIONS
+       //
+
        /**
         * Requests a list of all running requests from a node. This method will
         * block until the request has been sent!
@@ -118,7 +129,7 @@ public class RequestManager implements NodeListener {
         * @throws IOException
         *             if an I/O error occurs while communicating with the node
         */
-       public void getRequests(final Node node) throws IOException {
+       private void getRequests(final Node node) throws IOException {
                HighLevelClient highLevelClient = nodeManager.borrowHighLevelClient(node);
                if (highLevelClient == null) {
                        logger.log(Level.WARNING, "no client for node: " + node);
@@ -156,8 +167,38 @@ public class RequestManager implements NodeListener {
        /**
         * {@inheritDoc}
         */
+       public void nodeAdded(Node node) {
+               /* ignore. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void nodeRemoved(Node node) {
+               /* ignore. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
        public void nodeConnected(Node node) {
-               /* TODO - get all requests. */
+               HighLevelClient highLevelClient = nodeManager.borrowHighLevelClient(node);
+               if (highLevelClient == null) {
+                       logger.log(Level.WARNING, "got no high-level client for node " + node);
+                       return;
+               }
+               try {
+                       highLevelClient.setWatchGlobal(true);
+               } catch (IOException ioe1) {
+                       /* ignore exception, disconnects are handled elsewhere. */
+               } finally {
+                       nodeManager.returnHighLevelClient(highLevelClient);
+               }
+               try {
+                       getRequests(node);
+               } catch (IOException e) {
+                       /* ignore exception, disconnects are handled elsewhere. */
+               }
        }
 
        /**
index fc9986a..4eb7ab7 100644 (file)
@@ -24,6 +24,7 @@ import java.awt.Container;
 import java.awt.Dimension;
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
 
 import javax.swing.Action;
 import javax.swing.Box;
@@ -53,7 +54,7 @@ import net.pterodactylus.util.swing.SwingUtils;
  * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
  * @version $Id$
  */
-public class MainWindow extends JFrame implements I18nable {
+public class MainWindow extends JFrame implements WindowListener, I18nable {
 
        /** The swing interface that receives all actions. */
        private final SwingInterface swingInterface;
@@ -109,7 +110,7 @@ public class MainWindow extends JFrame implements I18nable {
                pack();
                SwingUtils.center(this);
                I18n.registerI18nable(this);
-               setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+               addWindowListener(this);
        }
 
        //
@@ -329,4 +330,57 @@ public class MainWindow extends JFrame implements I18nable {
                SwingUtils.repackCentered(this);
        }
 
+       //
+       // INTERFACE WindowListener
+       //
+       
+       /**
+        * {@inheritDoc}
+        */
+       public void windowActivated(WindowEvent e) {
+               /* do nothing. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void windowClosed(WindowEvent e) {
+               /* do nothing. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void windowClosing(WindowEvent e) {
+               swingInterface.getQuitAction().actionPerformed(null);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void windowDeactivated(WindowEvent e) {
+               /* do nothing. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void windowDeiconified(WindowEvent e) {
+               /* do nothing. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void windowIconified(WindowEvent e) {
+               /* do nothing. */
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void windowOpened(WindowEvent e) {
+               /* do nothing. */
+       }
+
 }
index f868f85..f634fa5 100644 (file)
@@ -142,7 +142,7 @@ public class SwingInterface implements CoreListener, LoggingListener {
        private ConfigurationDialog configurationDialog;
 
        /** The list of all defined nodes. */
-       private List<Node> nodeList;
+       private List<Node> nodeList = Collections.synchronizedList(new ArrayList<Node>());
 
        //
        // CONFIGURATION
@@ -624,6 +624,8 @@ public class SwingInterface implements CoreListener, LoggingListener {
         * Quits jSite.
         */
        private void quit() {
+               /* TODO - ask */
+               core.stop();
                saveConfig();
                System.exit(0);
        }
@@ -635,6 +637,7 @@ public class SwingInterface implements CoreListener, LoggingListener {
         *            The list of nodes
         */
        private void rebuildNodeActions(List<Node> nodes) {
+               logger.fine("rebuilding node actions…");
                nodeConnectActions.clear();
                nodeNodeConnectActions.clear();
                nodeConnectActionNodes.clear();
@@ -642,6 +645,7 @@ public class SwingInterface implements CoreListener, LoggingListener {
                nodeNodeDisconnectActions.clear();
                nodeDisconnectActionNodes.clear();
                for (Node node: nodes) {
+                       logger.finer("adding node “" + node + "” to menu");
                        Action nodeConnectAction = new AbstractAction(node.getName()) {
 
                                /**
@@ -847,8 +851,6 @@ public class SwingInterface implements CoreListener, LoggingListener {
         * {@inheritDoc}
         */
        public void coreLoaded() {
-               this.nodeList = core.getNodes();
-               manageNodesDialog.setNodeList(nodeList);
                mainWindow.setVisible(true);
                mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.coreLoaded"));
        }
@@ -863,6 +865,27 @@ public class SwingInterface implements CoreListener, LoggingListener {
        /**
         * {@inheritDoc}
         */
+       public void nodeAdded(Node node) {
+               logger.log(Level.INFO, "node added: " + node);
+               nodeList.add(node);
+               manageNodesDialog.setNodeList(nodeList);
+               rebuildNodeActions(nodeList);
+               mainWindow.refreshNodeMenuItems();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void nodeRemoved(Node node) {
+               logger.log(Level.INFO, "node removed: " + node);
+               nodeList.remove(node);
+               rebuildNodeActions(nodeList);
+               mainWindow.refreshNodeMenuItems();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
        public void nodeConnecting(Node node) {
                Action nodeConnectAction = nodeNodeConnectActions.get(node);
                nodeConnectActions.remove(nodeConnectAction);
@@ -897,7 +920,14 @@ public class SwingInterface implements CoreListener, LoggingListener {
                logger.log(Level.INFO, "request added to node: " + request + ", " + node);
                /* TODO - implement */
        }
-       
+
+       /**
+        * {@inheritDoc}
+        */
+       public void requestProgressed(Request request, int totalBlocks, int requiredBlocks, int successfulBlocks, int failedBlocks, int fatallyFailedBlocks, boolean finalizedTotal) {
+               /* TODO - update table model */
+       }
+
        //
        // INTERFACE LoggingListener
        //