From: David ‘Bombe’ Roden Date: Mon, 12 May 2008 21:29:45 +0000 (+0000) Subject: add request management X-Git-Url: https://git.pterodactylus.net/?a=commitdiff_plain;h=7ccb1fcb746198ee1417bb2f92c846132bf6bc96;p=jSite2.git add request management git-svn-id: http://trooper/svn/projects/jSite/trunk@804 c3eda9e8-030b-0410-8277-bc7414b0a119 --- diff --git a/src/net/pterodactylus/jsite/core/CoreImpl.java b/src/net/pterodactylus/jsite/core/CoreImpl.java index 8fe64da..9c68d44 100644 --- a/src/net/pterodactylus/jsite/core/CoreImpl.java +++ b/src/net/pterodactylus/jsite/core/CoreImpl.java @@ -25,11 +25,11 @@ import java.util.List; /** * The core of jSite. - * + * * @author David ‘Bombe’ Roden <bombe@freenetproject.org> * @version $Id$ */ -public class CoreImpl implements Core, NodeListener { +public class CoreImpl implements Core, NodeListener, RequestListener { /** The core listeners. */ private final List coreListeners = new ArrayList(); @@ -40,6 +40,11 @@ public class CoreImpl implements Core, NodeListener { /** The node manager. */ private NodeManager nodeManager; + /** The request manager. */ + /* TODO - remove */ + @SuppressWarnings("unused") + private RequestManager requestManager; + // // LISTENER MANAGEMENT // @@ -60,7 +65,7 @@ public class CoreImpl implements Core, NodeListener { /** * Notifies all listeners that the projects were loaded successfully. - * + * * @param directory * The directory the projects were loaded from */ @@ -73,7 +78,7 @@ public class CoreImpl implements Core, NodeListener { /** * Notifies all core listeners that loading the projects from the given * directory has failed. - * + * * @param directory * The directory the projects were tried to load from * @param throwable @@ -87,7 +92,7 @@ public class CoreImpl implements Core, NodeListener { /** * Notifies all listeners that the projects were successfully saved. - * + * * @param directory * The directory the projects were saved to */ @@ -99,7 +104,7 @@ public class CoreImpl implements Core, NodeListener { /** * Notifies all listeners that the projects could not be saved. - * + * * @param directory * The directory the projects were to be saved to * @param throwable @@ -113,7 +118,7 @@ public class CoreImpl implements Core, NodeListener { /** * Notifies all listeners that the nodes were successfully loaded. - * + * * @param directory * The directory the nodes were loaded from */ @@ -125,7 +130,7 @@ public class CoreImpl implements Core, NodeListener { /** * Notifies all listeners that loading the nodes has failed. - * + * * @param directory * The directory the nodes were loaded from * @param throwable @@ -139,7 +144,7 @@ public class CoreImpl implements Core, NodeListener { /** * Notifies all listeners that the nodes were saved successfully. - * + * * @param directory * The directory the nodes were saved to */ @@ -151,7 +156,7 @@ public class CoreImpl implements Core, NodeListener { /** * Notifies all listeners that saving the nodes has failed. - * + * * @param directory * The directory the nodes were saved to * @param throwable @@ -184,7 +189,7 @@ public class CoreImpl implements Core, NodeListener { /** * Notifies all listeners that a connection to the given node is now being * established. - * + * * @param node * The node that is being connected to */ @@ -196,7 +201,7 @@ public class CoreImpl implements Core, NodeListener { /** * Notifies all listeners that the given node is now connected. - * + * * @param node * The node that is now connected */ @@ -208,7 +213,7 @@ public class CoreImpl implements Core, NodeListener { /** * Notifies all listeners that the given node was disconnected. - * + * * @param node * The node that is now disconnected * @param throwable @@ -221,13 +226,27 @@ public class CoreImpl implements Core, NodeListener { } } + /** + * Notifies all listeners that a request was added to a node. + * + * @param node + * The node the request was added to + * @param request + * The request that was added + */ + private void fireRequestAdded(Node node, Request request) { + for (CoreListener coreListener: coreListeners) { + coreListener.requestAdded(node, request); + } + } + // // ACCESSORS // /** * Returns the project manager. - * + * * @return The project manager */ public ProjectManager getProjectManager() { @@ -236,7 +255,7 @@ public class CoreImpl implements Core, NodeListener { /** * Sets the project manager to use. - * + * * @param projectManager * The project manager to use */ @@ -246,7 +265,7 @@ public class CoreImpl implements Core, NodeListener { /** * Returns the node manager. - * + * * @return The node manager */ public NodeManager getNodeManager() { @@ -255,7 +274,7 @@ public class CoreImpl implements Core, NodeListener { /** * Sets the node manager to use. - * + * * @param nodeManager * The node manager to use */ @@ -264,6 +283,16 @@ public class CoreImpl implements Core, NodeListener { } /** + * Sets the request manager to use. + * + * @param requestManager + * The request manager to use + */ + public void setRequestManager(RequestManager requestManager) { + this.requestManager = requestManager; + } + + /** * {@inheritDoc} */ public List getNodes() { @@ -373,4 +402,15 @@ public class CoreImpl implements Core, NodeListener { fireNodeDisconnected(node, throwable); } + // + // INTERFACE RequestListener + // + + /** + * {@inheritDoc} + */ + public void requestAdded(Node node, Request request) { + fireRequestAdded(node, request); + } + } diff --git a/src/net/pterodactylus/jsite/core/CoreListener.java b/src/net/pterodactylus/jsite/core/CoreListener.java index b4a2574..cef057a 100644 --- a/src/net/pterodactylus/jsite/core/CoreListener.java +++ b/src/net/pterodactylus/jsite/core/CoreListener.java @@ -21,7 +21,7 @@ package net.pterodactylus.jsite.core; /** * Interface definition for user interfaces. - * + * * @author David ‘Bombe’ Roden <bombe@freenetproject.org> * @version $Id$ */ @@ -33,7 +33,7 @@ public interface CoreListener { /** * Notifies a listener that loading the projects finished successfully. - * + * * @param directory * The directory the nodes were loaded from */ @@ -41,7 +41,7 @@ public interface CoreListener { /** * Notifies all listeners that loading the projects has failed. - * + * * @param directory * The directory the projects were tried to load from * @param throwable @@ -52,7 +52,7 @@ public interface CoreListener { /** * Notifies a listener that the projects were successfully saved to the * given directory. - * + * * @param directory * The directory the projects were saved to */ @@ -60,7 +60,7 @@ public interface CoreListener { /** * Notifies a listener that saving the projects has failed. - * + * * @param directory * The directory the projects were to be saved to * @param throwable @@ -74,7 +74,7 @@ public interface CoreListener { /** * Notifies a listener that the nodes were successfully loaded. - * + * * @param directory * The directory the nodes were loaded from */ @@ -82,7 +82,7 @@ public interface CoreListener { /** * Notifies a listener that loading the nodes has failed. - * + * * @param directory * The directory the nodes were loaded from * @param throwable @@ -92,7 +92,7 @@ public interface CoreListener { /** * Notifies a listener that the nodes were successfully saved. - * + * * @param directory * The directory the nodes were saved to */ @@ -100,7 +100,7 @@ public interface CoreListener { /** * Notifies a listener that saving the nodes has failed. - * + * * @param directory * The directory the nodes were saved to * @param throwable @@ -129,7 +129,7 @@ public interface CoreListener { /** * Notifies all listeners that the core started connecting to the given * node. - * + * * @param node * The node that is being connected */ @@ -137,7 +137,7 @@ public interface CoreListener { /** * Notifies all listeners that the core connected to the given node. - * + * * @param node * The node that is connected */ @@ -145,7 +145,7 @@ public interface CoreListener { /** * Notifies all listeners that the core disconnected from the given node. - * + * * @param node * The node that was diconnected * @param throwable @@ -154,4 +154,18 @@ public interface CoreListener { */ public void nodeDisconnected(Node node, Throwable throwable); + // + // request stuff + // + + /** + * Notifies a listener that a request was added to a node. + * + * @param node + * The node the request was added to + * @param request + * The request that was added + */ + public void requestAdded(Node node, Request request); + } diff --git a/src/net/pterodactylus/jsite/core/NodeListener.java b/src/net/pterodactylus/jsite/core/NodeListener.java index 80a01ce..23f1a4c 100644 --- a/src/net/pterodactylus/jsite/core/NodeListener.java +++ b/src/net/pterodactylus/jsite/core/NodeListener.java @@ -23,7 +23,7 @@ import java.util.EventListener; /** * Interface for listeners that want to be notified about node events. - * + * * @author David ‘Bombe’ Roden <bombe@freenetproject.org> * @version $Id$ */ @@ -31,7 +31,7 @@ public interface NodeListener extends EventListener { /** * Notifies a listener that a connection to the given node was established. - * + * * @param node * The node that is now connected */ @@ -40,7 +40,7 @@ public interface NodeListener extends EventListener { /** * Notifies a listener that a connection to the given node was severed. The * listener is responsible for - * + * * @param node * The node that is now disconnected * @param throwable diff --git a/src/net/pterodactylus/jsite/core/NodeManager.java b/src/net/pterodactylus/jsite/core/NodeManager.java index fe52fd7..70da6d6 100644 --- a/src/net/pterodactylus/jsite/core/NodeManager.java +++ b/src/net/pterodactylus/jsite/core/NodeManager.java @@ -337,6 +337,56 @@ public class NodeManager implements HighLevelClientListener { return Collections.unmodifiableList(nodes); } + /** + * “Borrows” a high-level client for the given node. A borrowed client + * has to be returned to the node manager using + * {@link #returnHighLevelClient(HighLevelClient)} when it is no longer in + * use, i.e. after a message has been sent! This method will block until a + * high-level client for the given node is available. + * + * @param node + * The node to get a high-level client for + * @return The high-level client for a node, or null if the + * node was disconnected or removed + */ + public HighLevelClient borrowHighLevelClient(Node node) { + synchronized (syncObject) { + if (!nodeClients.containsKey(node)) { + return null; + } + HighLevelClient highLevelClient = nodeClients.get(node); + while (nodeClients.containsKey(node) && usedConnections.contains(highLevelClient)) { + try { + syncObject.wait(); + } catch (InterruptedException ie1) { + /* ignore. TODO - check. */ + } + } + if (!nodeClients.containsKey(node)) { + return null; + } + usedConnections.add(highLevelClient); + return highLevelClient; + } + } + + /** + * Returns a borrowed high-level client. + * + * @see #borrowHighLevelClient(Node) + * @param highLevelClient + * The high-level client to return + */ + public void returnHighLevelClient(HighLevelClient highLevelClient) { + synchronized (syncObject) { + if (!clientNodes.containsKey(highLevelClient)) { + return; + } + usedConnections.remove(highLevelClient); + syncObject.notifyAll(); + } + } + // // PRIVATE METHODS // diff --git a/src/net/pterodactylus/jsite/core/Request.java b/src/net/pterodactylus/jsite/core/Request.java new file mode 100644 index 0000000..47349ca --- /dev/null +++ b/src/net/pterodactylus/jsite/core/Request.java @@ -0,0 +1,52 @@ +/* + * jSite2 - Request.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.jsite.core; + +/** + * A request is an ongoing download or upload reported by the freenet node. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class Request { + + /** The identifier of the request. */ + private final String identifier; + + /** + * Creates a new request with the given identifier. + * + * @param identifier + * The identifier of the request + */ + Request(String identifier) { + this.identifier = identifier; + } + + /** + * Returns the identifier of the request. It is unique per node. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return identifier; + } + +} diff --git a/src/net/pterodactylus/jsite/core/RequestListener.java b/src/net/pterodactylus/jsite/core/RequestListener.java new file mode 100644 index 0000000..eb0433a --- /dev/null +++ b/src/net/pterodactylus/jsite/core/RequestListener.java @@ -0,0 +1,42 @@ +/* + * jSite2 - RequestListener.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.jsite.core; + +import java.util.EventListener; + +/** + * Interface for objects that want to be notified on request events. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public interface RequestListener extends EventListener { + + /** + * Notifies a listener that a request was added to a node. + * + * @param node + * The node the request was added to + * @param request + * The request that was added + */ + public void requestAdded(Node node, Request request); + +} diff --git a/src/net/pterodactylus/jsite/core/RequestManager.java b/src/net/pterodactylus/jsite/core/RequestManager.java new file mode 100644 index 0000000..f2aa23f --- /dev/null +++ b/src/net/pterodactylus/jsite/core/RequestManager.java @@ -0,0 +1,170 @@ +/* + * jSite2 - RequestManager.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.jsite.core; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import net.pterodactylus.fcp.highlevel.HighLevelCallback; +import net.pterodactylus.fcp.highlevel.HighLevelCallbackListener; +import net.pterodactylus.fcp.highlevel.HighLevelClient; +import net.pterodactylus.fcp.highlevel.RequestListResult; +import net.pterodactylus.fcp.highlevel.RequestResult; +import net.pterodactylus.util.logging.Logging; + +/** + * The request manager keeps track of all the request on all connected nodes. + * The request manager is added to the {@link NodeManager} as a + * {@link NodeListener} so that it can fire request-removed events in case a + * node is disconnected. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class RequestManager implements NodeListener { + + /** Logger. */ + private static final Logger logger = Logging.getLogger(RequestManager.class.getName()); + + /** Request listeners. */ + private List requestListeners = Collections.synchronizedList(new ArrayList()); + + /** The node manager. */ + private NodeManager nodeManager; + + // + // EVENT MANAGEMENT + // + + /** + * Adds a request listener. + * + * @param requestListener + * The request listener to add + */ + public void addRequestListener(RequestListener requestListener) { + requestListeners.add(requestListener); + } + + /** + * Removes a request listener. + * + * @param requestListener + * The request listener to remove + */ + public void removeRequestListener(RequestListener requestListener) { + requestListeners.remove(requestListener); + } + + /** + * Notifies all listeners that a request was added. + * + * @param node + * The node that added the request + * @param request + * The request that was added + */ + private void fireRequestAdded(Node node, Request request) { + for (RequestListener requestListener: requestListeners) { + requestListener.requestAdded(node, request); + } + } + + // + // ACCESSORS + // + + /** + * Sets the node manager to use. + * + * @param nodeManager + * The node manager + */ + public void setNodeManager(NodeManager nodeManager) { + this.nodeManager = nodeManager; + } + + // + // ACTIONS + // + + /** + * Requests a list of all running requests from a node. This method will + * block until the request has been sent! + * + * @param node + * The node to get all requests for + * @throws IOException + * if an I/O error occurs while communicating with the node + */ + public void getRequests(final Node node) throws IOException { + HighLevelClient highLevelClient = nodeManager.borrowHighLevelClient(node); + if (highLevelClient == null) { + logger.log(Level.WARNING, "no client for node: " + node); + return; + } + try { + HighLevelCallback requestListCallback = highLevelClient.getRequests(); + requestListCallback.addHighLevelCallbackListener(new HighLevelCallbackListener() { + + @SuppressWarnings("synthetic-access") + public void gotResult(HighLevelCallback highLevelCallback) { + RequestListResult requestListResult; + try { + requestListResult = highLevelCallback.getResult(); + } catch (InterruptedException e) { + logger.log(Level.SEVERE, "getResult() blocked and was interrupted"); + return; + } + for (RequestResult requestResult: requestListResult) { + Request request = new Request(requestResult.getIdentifier()); + /* TODO - fill request */ + fireRequestAdded(node, request); + } + } + }); + } finally { + nodeManager.returnHighLevelClient(highLevelClient); + } + } + + // + // INTERFACE NodeListener + // + + /** + * {@inheritDoc} + */ + public void nodeConnected(Node node) { + /* TODO - get all requests. */ + } + + /** + * {@inheritDoc} + */ + public void nodeDisconnected(Node node, Throwable throwable) { + /* TODO - remove all requests. */ + } + +} diff --git a/src/net/pterodactylus/jsite/gui/SwingInterface.java b/src/net/pterodactylus/jsite/gui/SwingInterface.java index b79cdc9..f868f85 100644 --- a/src/net/pterodactylus/jsite/gui/SwingInterface.java +++ b/src/net/pterodactylus/jsite/gui/SwingInterface.java @@ -47,6 +47,7 @@ import net.pterodactylus.jsite.core.Core; import net.pterodactylus.jsite.core.CoreListener; import net.pterodactylus.jsite.core.Node; import net.pterodactylus.jsite.core.Project; +import net.pterodactylus.jsite.core.Request; import net.pterodactylus.jsite.i18n.I18n; import net.pterodactylus.jsite.i18n.gui.I18nAction; import net.pterodactylus.util.image.IconLoader; @@ -889,6 +890,14 @@ public class SwingInterface implements CoreListener, LoggingListener { mainWindow.refreshNodeMenuItems(); } + /** + * {@inheritDoc} + */ + public void requestAdded(Node node, Request request) { + logger.log(Level.INFO, "request added to node: " + request + ", " + node); + /* TODO - implement */ + } + // // INTERFACE LoggingListener // diff --git a/src/net/pterodactylus/jsite/main/Main.java b/src/net/pterodactylus/jsite/main/Main.java index dab65f5..be543eb 100644 --- a/src/net/pterodactylus/jsite/main/Main.java +++ b/src/net/pterodactylus/jsite/main/Main.java @@ -24,12 +24,13 @@ import java.io.File; import net.pterodactylus.jsite.core.CoreImpl; import net.pterodactylus.jsite.core.NodeManager; import net.pterodactylus.jsite.core.ProjectManager; +import net.pterodactylus.jsite.core.RequestManager; import net.pterodactylus.jsite.gui.SwingInterface; import net.pterodactylus.util.logging.Logging; /** * Main class that is called by the VM. - * + * * @author David ‘Bombe’ Roden <bombe@freenetproject.org> * @version $Id$ */ @@ -37,7 +38,7 @@ public class Main { /** * Main entry method for the VM. - * + * * @param args * The command-line arguments */ @@ -62,6 +63,12 @@ public class Main { core.setNodeManager(nodeManager); nodeManager.addNodeListener(core); + RequestManager requestManager = new RequestManager(); + core.setRequestManager(requestManager); + nodeManager.addNodeListener(requestManager); + requestManager.setNodeManager(nodeManager); + requestManager.addRequestListener(core); + SwingInterface swingInterface = new SwingInterface(core, configDirectory); core.addCoreListener(swingInterface); Logging.addLoggingListener(swingInterface);