2 * Sone - PluginConnector.java - Copyright © 2010–2012 David Roden
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 package net.pterodactylus.sone.freenet.plugin;
20 import java.util.Collections;
21 import java.util.HashMap;
24 import com.google.inject.Inject;
26 import freenet.pluginmanager.FredPluginTalker;
27 import freenet.pluginmanager.PluginNotFoundException;
28 import freenet.pluginmanager.PluginRespirator;
29 import freenet.pluginmanager.PluginTalker;
30 import freenet.support.SimpleFieldSet;
31 import freenet.support.api.Bucket;
34 * Interface for talking to other plugins. Other plugins are identified by their
35 * name and a unique connection identifier.
37 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
39 public class PluginConnector implements FredPluginTalker {
41 /** The plugin respirator. */
42 private final PluginRespirator pluginRespirator;
44 /** Connector listener managers for all plugin connections. */
45 private final Map<PluginIdentifier, ConnectorListenerManager> connectorListenerManagers = Collections.synchronizedMap(new HashMap<PluginIdentifier, ConnectorListenerManager>());
48 * Creates a new plugin connector.
50 * @param pluginRespirator
51 * The plugin respirator
54 public PluginConnector(PluginRespirator pluginRespirator) {
55 this.pluginRespirator = pluginRespirator;
59 // LISTENER MANAGEMENT
63 * Adds a connection listener for the given plugin connection.
66 * The name of the plugin
68 * The identifier of the connection
69 * @param connectorListener
72 public void addConnectorListener(String pluginName, String identifier, ConnectorListener connectorListener) {
73 getConnectorListenerManager(pluginName, identifier).addListener(connectorListener);
77 * Removes a connection listener for the given plugin connection.
80 * The name of the plugin
82 * The identifier of the connection
83 * @param connectorListener
84 * The listener to remove
86 public void removeConnectorListener(String pluginName, String identifier, ConnectorListener connectorListener) {
87 getConnectorListenerManager(pluginName, identifier).removeListener(connectorListener);
95 * Sends a request to the given plugin.
98 * The name of the plugin
100 * The identifier of the connection
102 * The fields of the message
103 * @throws PluginException
104 * if the plugin can not be found
106 public void sendRequest(String pluginName, String identifier, SimpleFieldSet fields) throws PluginException {
107 sendRequest(pluginName, identifier, fields, null);
111 * Sends a request to the given plugin.
114 * The name of the plugin
116 * The identifier of the connection
118 * The fields of the message
120 * The payload of the message (may be null)
121 * @throws PluginException
122 * if the plugin can not be found
124 public void sendRequest(String pluginName, String identifier, SimpleFieldSet fields, Bucket data) throws PluginException {
125 getPluginTalker(pluginName, identifier).send(fields, data);
133 * Returns the connection listener manager for the given plugin connection,
134 * creating a new one if none does exist yet.
137 * The name of the plugin
139 * The identifier of the connection
140 * @return The connection listener manager
142 private ConnectorListenerManager getConnectorListenerManager(String pluginName, String identifier) {
143 return getConnectorListenerManager(pluginName, identifier, true);
147 * Returns the connection listener manager for the given plugin connection,
148 * optionally creating a new one if none does exist yet.
151 * The name of the plugin
153 * The identifier of the connection
155 * {@code true} to create a new manager if there is none,
156 * {@code false} to return {@code null} in that case
157 * @return The connection listener manager, or {@code null} if none existed
158 * and {@code create} is {@code false}
160 private ConnectorListenerManager getConnectorListenerManager(String pluginName, String identifier, boolean create) {
161 ConnectorListenerManager connectorListenerManager = connectorListenerManagers.get(new PluginIdentifier(pluginName, identifier));
162 if (create && (connectorListenerManager == null)) {
163 connectorListenerManager = new ConnectorListenerManager(this);
164 connectorListenerManagers.put(new PluginIdentifier(pluginName, identifier), connectorListenerManager);
166 return connectorListenerManager;
170 * Returns the plugin talker for the given plugin connection.
173 * The name of the plugin
175 * The identifier of the connection
176 * @return The plugin talker
177 * @throws PluginException
178 * if the plugin can not be found
180 private PluginTalker getPluginTalker(String pluginName, String identifier) throws PluginException {
182 return pluginRespirator.getPluginTalker(this, pluginName, identifier);
183 } catch (PluginNotFoundException pnfe1) {
184 throw new PluginException(pnfe1);
189 // INTERFACE FredPluginTalker
196 public void onReply(String pluginName, String identifier, SimpleFieldSet params, Bucket data) {
197 ConnectorListenerManager connectorListenerManager = getConnectorListenerManager(pluginName, identifier, false);
198 if (connectorListenerManager == null) {
199 /* we don’t care about events for this plugin. */
202 connectorListenerManager.fireReceivedReply(params, data);
206 * Container for identifying plugins. Plugins are identified by their plugin
207 * name and their unique identifier.
209 * @author <a href="mailto:d.roden@xplosion.de">David Roden</a>
211 private static class PluginIdentifier {
213 /** The plugin name. */
214 private final String pluginName;
216 /** The plugin identifier. */
217 private final String identifier;
220 * Creates a new plugin identifier.
223 * The name of the plugin
225 * The identifier of the plugin
227 public PluginIdentifier(String pluginName, String identifier) {
228 this.pluginName = pluginName;
229 this.identifier = identifier;
240 public int hashCode() {
241 return pluginName.hashCode() ^ identifier.hashCode();
248 public boolean equals(Object object) {
249 if (!(object instanceof PluginIdentifier)) {
252 PluginIdentifier pluginIdentifier = (PluginIdentifier) object;
253 return pluginName.equals(pluginIdentifier.pluginName) && identifier.equals(pluginIdentifier.identifier);