implement node addition and removal events
[jSite2.git] / src / net / pterodactylus / jsite / core / RequestManager.java
1 /*
2  * jSite2 - RequestManager.java -
3  * Copyright © 2008 David Roden
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 package net.pterodactylus.jsite.core;
21
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Set;
29 import java.util.logging.Level;
30 import java.util.logging.Logger;
31
32 import net.pterodactylus.fcp.highlevel.HighLevelCallback;
33 import net.pterodactylus.fcp.highlevel.HighLevelCallbackListener;
34 import net.pterodactylus.fcp.highlevel.HighLevelClient;
35 import net.pterodactylus.fcp.highlevel.RequestListResult;
36 import net.pterodactylus.fcp.highlevel.RequestResult;
37 import net.pterodactylus.util.logging.Logging;
38
39 /**
40  * The request manager keeps track of all the request on all connected nodes.
41  * The request manager is added to the {@link NodeManager} as a
42  * {@link NodeListener} so that it can fire request-removed events in case a
43  * node is disconnected.
44  * 
45  * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
46  * @version $Id$
47  */
48 public class RequestManager implements NodeListener {
49
50         /** Logger. */
51         private static final Logger logger = Logging.getLogger(RequestManager.class.getName());
52
53         /** Request listeners. */
54         private List<RequestListener> requestListeners = Collections.synchronizedList(new ArrayList<RequestListener>());
55
56         /** The node manager. */
57         private NodeManager nodeManager;
58
59         /** Request lists for all nodes. */
60         @SuppressWarnings("unused")
61         private Map<Node, Set<Request>> nodeRequests = Collections.synchronizedMap(new HashMap<Node, Set<Request>>());
62
63         //
64         // EVENT MANAGEMENT
65         //
66
67         /**
68          * Adds a request listener.
69          * 
70          * @param requestListener
71          *            The request listener to add
72          */
73         public void addRequestListener(RequestListener requestListener) {
74                 requestListeners.add(requestListener);
75         }
76
77         /**
78          * Removes a request listener.
79          * 
80          * @param requestListener
81          *            The request listener to remove
82          */
83         public void removeRequestListener(RequestListener requestListener) {
84                 requestListeners.remove(requestListener);
85         }
86
87         /**
88          * Notifies all listeners that a request was added.
89          * 
90          * @param node
91          *            The node that added the request
92          * @param request
93          *            The request that was added
94          */
95         private void fireRequestAdded(Node node, Request request) {
96                 for (RequestListener requestListener: requestListeners) {
97                         requestListener.requestAdded(node, request);
98                 }
99         }
100
101         //
102         // ACCESSORS
103         //
104
105         /**
106          * Sets the node manager to use.
107          * 
108          * @param nodeManager
109          *            The node manager
110          */
111         public void setNodeManager(NodeManager nodeManager) {
112                 this.nodeManager = nodeManager;
113         }
114
115         //
116         // ACTIONS
117         //
118
119         //
120         // PRIVATE ACTIONS
121         //
122
123         /**
124          * Requests a list of all running requests from a node. This method will
125          * block until the request has been sent!
126          * 
127          * @param node
128          *            The node to get all requests for
129          * @throws IOException
130          *             if an I/O error occurs while communicating with the node
131          */
132         private void getRequests(final Node node) throws IOException {
133                 HighLevelClient highLevelClient = nodeManager.borrowHighLevelClient(node);
134                 if (highLevelClient == null) {
135                         logger.log(Level.WARNING, "no client for node: " + node);
136                         return;
137                 }
138                 try {
139                         HighLevelCallback<RequestListResult> requestListCallback = highLevelClient.getRequests();
140                         requestListCallback.addHighLevelCallbackListener(new HighLevelCallbackListener<RequestListResult>() {
141
142                                 @SuppressWarnings("synthetic-access")
143                                 public void gotResult(HighLevelCallback<RequestListResult> highLevelCallback) {
144                                         RequestListResult requestListResult;
145                                         try {
146                                                 requestListResult = highLevelCallback.getResult();
147                                         } catch (InterruptedException e) {
148                                                 logger.log(Level.SEVERE, "getResult() blocked and was interrupted");
149                                                 return;
150                                         }
151                                         for (RequestResult requestResult: requestListResult) {
152                                                 Request request = new Request(requestResult.getIdentifier());
153                                                 /* TODO - fill request */
154                                                 fireRequestAdded(node, request);
155                                         }
156                                 }
157                         });
158                 } finally {
159                         nodeManager.returnHighLevelClient(highLevelClient);
160                 }
161         }
162
163         //
164         // INTERFACE NodeListener
165         //
166
167         /**
168          * {@inheritDoc}
169          */
170         public void nodeAdded(Node node) {
171                 /* ignore. */
172         }
173
174         /**
175          * {@inheritDoc}
176          */
177         public void nodeRemoved(Node node) {
178                 /* ignore. */
179         }
180
181         /**
182          * {@inheritDoc}
183          */
184         public void nodeConnected(Node node) {
185                 HighLevelClient highLevelClient = nodeManager.borrowHighLevelClient(node);
186                 if (highLevelClient == null) {
187                         logger.log(Level.WARNING, "got no high-level client for node " + node);
188                         return;
189                 }
190                 try {
191                         highLevelClient.setWatchGlobal(true);
192                 } catch (IOException ioe1) {
193                         /* ignore exception, disconnects are handled elsewhere. */
194                 } finally {
195                         nodeManager.returnHighLevelClient(highLevelClient);
196                 }
197                 try {
198                         getRequests(node);
199                 } catch (IOException e) {
200                         /* ignore exception, disconnects are handled elsewhere. */
201                 }
202         }
203
204         /**
205          * {@inheritDoc}
206          */
207         public void nodeDisconnected(Node node, Throwable throwable) {
208                 /* TODO - remove all requests. */
209         }
210
211 }