/**
* 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<CoreListener> coreListeners = new ArrayList<CoreListener>();
/** The node manager. */
private NodeManager nodeManager;
+ /** The request manager. */
+ /* TODO - remove */
+ @SuppressWarnings("unused")
+ private RequestManager requestManager;
+
//
// LISTENER MANAGEMENT
//
/**
* Notifies all listeners that the projects were loaded successfully.
- *
+ *
* @param directory
* The directory the projects were loaded from
*/
/**
* 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
/**
* Notifies all listeners that the projects were successfully saved.
- *
+ *
* @param directory
* The directory the projects were saved to
*/
/**
* Notifies all listeners that the projects could not be saved.
- *
+ *
* @param directory
* The directory the projects were to be saved to
* @param throwable
/**
* Notifies all listeners that the nodes were successfully loaded.
- *
+ *
* @param directory
* The directory the nodes were loaded from
*/
/**
* Notifies all listeners that loading the nodes has failed.
- *
+ *
* @param directory
* The directory the nodes were loaded from
* @param throwable
/**
* Notifies all listeners that the nodes were saved successfully.
- *
+ *
* @param directory
* The directory the nodes were saved to
*/
/**
* Notifies all listeners that saving the nodes has failed.
- *
+ *
* @param directory
* The directory the nodes were saved to
* @param throwable
/**
* Notifies all listeners that a connection to the given node is now being
* established.
- *
+ *
* @param node
* The node that is being connected to
*/
/**
* Notifies all listeners that the given node is now connected.
- *
+ *
* @param node
* The node that is now connected
*/
/**
* Notifies all listeners that the given node was disconnected.
- *
+ *
* @param node
* The node that is now disconnected
* @param throwable
}
}
+ /**
+ * 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() {
/**
* Sets the project manager to use.
- *
+ *
* @param projectManager
* The project manager to use
*/
/**
* Returns the node manager.
- *
+ *
* @return The node manager
*/
public NodeManager getNodeManager() {
/**
* Sets the node manager to use.
- *
+ *
* @param nodeManager
* The node manager to use
*/
}
/**
+ * Sets the request manager to use.
+ *
+ * @param requestManager
+ * The request manager to use
+ */
+ public void setRequestManager(RequestManager requestManager) {
+ this.requestManager = requestManager;
+ }
+
+ /**
* {@inheritDoc}
*/
public List<Node> getNodes() {
fireNodeDisconnected(node, throwable);
}
+ //
+ // INTERFACE RequestListener
+ //
+
+ /**
+ * {@inheritDoc}
+ */
+ public void requestAdded(Node node, Request request) {
+ fireRequestAdded(node, request);
+ }
+
}
/**
* Interface definition for user interfaces.
- *
+ *
* @author David ‘Bombe’ Roden <bombe@freenetproject.org>
* @version $Id$
*/
/**
* Notifies a listener that loading the projects finished successfully.
- *
+ *
* @param directory
* The directory the nodes were loaded from
*/
/**
* Notifies all listeners that loading the projects has failed.
- *
+ *
* @param directory
* The directory the projects were tried to load from
* @param throwable
/**
* Notifies a listener that the projects were successfully saved to the
* given directory.
- *
+ *
* @param directory
* The directory the projects were saved to
*/
/**
* Notifies a listener that saving the projects has failed.
- *
+ *
* @param directory
* The directory the projects were to be saved to
* @param throwable
/**
* Notifies a listener that the nodes were successfully loaded.
- *
+ *
* @param directory
* The directory the nodes were loaded from
*/
/**
* Notifies a listener that loading the nodes has failed.
- *
+ *
* @param directory
* The directory the nodes were loaded from
* @param throwable
/**
* Notifies a listener that the nodes were successfully saved.
- *
+ *
* @param directory
* The directory the nodes were saved to
*/
/**
* Notifies a listener that saving the nodes has failed.
- *
+ *
* @param directory
* The directory the nodes were saved to
* @param throwable
/**
* Notifies all listeners that the core started connecting to the given
* node.
- *
+ *
* @param node
* The node that is being connected
*/
/**
* Notifies all listeners that the core connected to the given node.
- *
+ *
* @param node
* The node that is connected
*/
/**
* Notifies all listeners that the core disconnected from the given node.
- *
+ *
* @param node
* The node that was diconnected
* @param throwable
*/
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);
+
}
/**
* Interface for listeners that want to be notified about node events.
- *
+ *
* @author David ‘Bombe’ Roden <bombe@freenetproject.org>
* @version $Id$
*/
/**
* Notifies a listener that a connection to the given node was established.
- *
+ *
* @param node
* The node that is now connected
*/
/**
* 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
return Collections.unmodifiableList(nodes);
}
+ /**
+ * “Borrows” a high-level client for the given node. A borrowed client
+ * <strong>has</strong> 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 <code>null</code> 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
//
--- /dev/null
+/*
+ * 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;
+ }
+
+}
--- /dev/null
+/*
+ * 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);
+
+}
--- /dev/null
+/*
+ * 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<RequestListener> requestListeners = Collections.synchronizedList(new ArrayList<RequestListener>());
+
+ /** 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<RequestListResult> requestListCallback = highLevelClient.getRequests();
+ requestListCallback.addHighLevelCallbackListener(new HighLevelCallbackListener<RequestListResult>() {
+
+ @SuppressWarnings("synthetic-access")
+ public void gotResult(HighLevelCallback<RequestListResult> 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. */
+ }
+
+}
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;
mainWindow.refreshNodeMenuItems();
}
+ /**
+ * {@inheritDoc}
+ */
+ public void requestAdded(Node node, Request request) {
+ logger.log(Level.INFO, "request added to node: " + request + ", " + node);
+ /* TODO - implement */
+ }
+
//
// INTERFACE LoggingListener
//
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$
*/
/**
* Main entry method for the VM.
- *
+ *
* @param args
* The command-line arguments
*/
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);