From: David ‘Bombe’ Roden Date: Fri, 29 Oct 2010 19:41:01 +0000 (+0200) Subject: Add basic plugin communication ability. X-Git-Tag: 0.2-RC1~96 X-Git-Url: https://git.pterodactylus.net/?a=commitdiff_plain;h=725d85403a7b5e2bad4cef7369aba9db7b5c0b60;p=Sone.git Add basic plugin communication ability. --- diff --git a/src/main/java/net/pterodactylus/sone/freenet/wot/ConnectorListener.java b/src/main/java/net/pterodactylus/sone/freenet/wot/ConnectorListener.java new file mode 100644 index 0000000..cf1d1e3 --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/freenet/wot/ConnectorListener.java @@ -0,0 +1,50 @@ +/* + * Sone - ConnectorListener.java - Copyright © 2010 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 3 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, see . + */ + +package net.pterodactylus.sone.freenet.wot; + +import java.util.EventListener; + +import freenet.support.SimpleFieldSet; +import freenet.support.api.Bucket; + +/** + * Interface for objects that want to be notified if a {@link PluginConnector} + * receives a reply from a plugin. As a connection listener is always + * {@link PluginConnector#addConnectorListener(String, String, ConnectorListener) + * added} for a specific plugin, it will always be notified for replies from the + * correct plugin (unless you register the same listener for multiple + * plugins—which you subsequently should not do). + * + * @author David ‘Bombe’ Roden + */ +public interface ConnectorListener extends EventListener { + + /** + * A reply was received from the plugin this connection listener was added + * for. + * + * @param pluginConnector + * The plugin connector that received the reply + * @param fields + * The fields of the reply + * @param data + * The data of the reply (may be null) + */ + public void receivedReply(PluginConnector pluginConnector, SimpleFieldSet fields, Bucket data); + +} diff --git a/src/main/java/net/pterodactylus/sone/freenet/wot/ConnectorListenerManager.java b/src/main/java/net/pterodactylus/sone/freenet/wot/ConnectorListenerManager.java new file mode 100644 index 0000000..3962eef --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/freenet/wot/ConnectorListenerManager.java @@ -0,0 +1,60 @@ +/* + * Sone - ConnectorListenerManager.java - Copyright © 2010 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 3 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, see . + */ + +package net.pterodactylus.sone.freenet.wot; + +import net.pterodactylus.util.event.AbstractListenerManager; +import freenet.support.SimpleFieldSet; +import freenet.support.api.Bucket; + +/** + * Manages {@link ConnectorListener}s and fire events. + * + * @author David ‘Bombe’ Roden + */ +public class ConnectorListenerManager extends AbstractListenerManager { + + /** + * Creates a new manager for {@link ConnectorListener}s. + * + * @param pluginConnector + * The plugin connector that is the source for all events + */ + public ConnectorListenerManager(PluginConnector pluginConnector) { + super(pluginConnector); + } + + // + // ACTIONS + // + + /** + * Notifies all registered listeners that a reply from the plugin was + * received. + * + * @param fields + * The fields of the reply + * @param data + * The data of the reply (may be null) + */ + public void fireReceivedReply(SimpleFieldSet fields, Bucket data) { + for (ConnectorListener connectorListener : getListeners()) { + connectorListener.receivedReply(getSource(), fields, data); + } + } + +} diff --git a/src/main/java/net/pterodactylus/sone/freenet/wot/PluginConnector.java b/src/main/java/net/pterodactylus/sone/freenet/wot/PluginConnector.java new file mode 100644 index 0000000..561f092 --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/freenet/wot/PluginConnector.java @@ -0,0 +1,203 @@ +/* + * Sone - PluginConnector.java - Copyright © 2010 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 3 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, see . + */ + +package net.pterodactylus.sone.freenet.wot; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import net.pterodactylus.util.collection.Pair; +import freenet.pluginmanager.FredPluginTalker; +import freenet.pluginmanager.PluginNotFoundException; +import freenet.pluginmanager.PluginRespirator; +import freenet.pluginmanager.PluginTalker; +import freenet.support.SimpleFieldSet; +import freenet.support.api.Bucket; + +/** + * Interface for talking to other plugins. Other plugins are identified by their + * name and a unique connection identifier. + * + * @author David ‘Bombe’ Roden + */ +public class PluginConnector implements FredPluginTalker { + + /** The plugin respirator. */ + private final PluginRespirator pluginRespirator; + + /** Connector listener managers for all plugin connections. */ + private final Map, ConnectorListenerManager> connectorListenerManagers = Collections.synchronizedMap(new HashMap, ConnectorListenerManager>()); + + /** + * Creates a new plugin connector. + * + * @param pluginRespirator + * The plugin respirator + */ + public PluginConnector(PluginRespirator pluginRespirator) { + this.pluginRespirator = pluginRespirator; + } + + // + // LISTENER MANAGEMENT + // + + /** + * Adds a connection listener for the given plugin connection. + * + * @param pluginName + * The name of the plugin + * @param identifier + * The identifier of the connection + * @param connectorListener + * The listener to add + */ + public void addConnectorListener(String pluginName, String identifier, ConnectorListener connectorListener) { + getConnectorListenerManager(pluginName, identifier).addListener(connectorListener); + } + + /** + * Removes a connection listener for the given plugin connection. + * + * @param pluginName + * The name of the plugin + * @param identifier + * The identifier of the connection + * @param connectorListener + * The listener to remove + */ + public void removeConnectorListener(String pluginName, String identifier, ConnectorListener connectorListener) { + getConnectorListenerManager(pluginName, identifier).removeListener(connectorListener); + } + + // + // ACTIONS + // + + /** + * Sends a request to the given plugin. + * + * @param pluginName + * The name of the plugin + * @param identifier + * The identifier of the connection + * @param fields + * The fields of the message + * @throws PluginException + * if the plugin can not be found + */ + public void sendRequest(String pluginName, String identifier, SimpleFieldSet fields) throws PluginException { + sendRequest(pluginName, identifier, fields, null); + } + + /** + * Sends a request to the given plugin. + * + * @param pluginName + * The name of the plugin + * @param identifier + * The identifier of the connection + * @param fields + * The fields of the message + * @param data + * The payload of the message (may be null) + * @throws PluginException + * if the plugin can not be found + */ + public void sendRequest(String pluginName, String identifier, SimpleFieldSet fields, Bucket data) throws PluginException { + getPluginTalker(pluginName, identifier).send(fields, data); + } + + // + // PRIVATE METHODS + // + + /** + * Returns the connection listener manager for the given plugin connection, + * creating a new one if none does exist yet. + * + * @param pluginName + * The name of the plugin + * @param identifier + * The identifier of the connection + * @return The connection listener manager + */ + private ConnectorListenerManager getConnectorListenerManager(String pluginName, String identifier) { + return getConnectorListenerManager(pluginName, identifier, true); + } + + /** + * Returns the connection listener manager for the given plugin connection, + * optionally creating a new one if none does exist yet. + * + * @param pluginName + * The name of the plugin + * @param identifier + * The identifier of the connection + * @param create + * {@code true} to create a new manager if there is none, + * {@code false} to return {@code null} in that case + * @return The connection listener manager, or {@code null} if none existed + * and {@code create} is {@code false} + */ + private ConnectorListenerManager getConnectorListenerManager(String pluginName, String identifier, boolean create) { + ConnectorListenerManager connectorListenerManager = connectorListenerManagers.get(new Pair(pluginName, identifier)); + if (create && (connectorListenerManager == null)) { + connectorListenerManager = new ConnectorListenerManager(this); + connectorListenerManagers.put(new Pair(pluginName, identifier), connectorListenerManager); + } + return connectorListenerManager; + } + + /** + * Returns the plugin talker for the given plugin connection. + * + * @param pluginName + * The name of the plugin + * @param identifier + * The identifier of the connection + * @return The plugin talker + * @throws PluginException + * if the plugin can not be found + */ + private PluginTalker getPluginTalker(String pluginName, String identifier) throws PluginException { + try { + return pluginRespirator.getPluginTalker(this, pluginName, identifier); + } catch (PluginNotFoundException pnfe1) { + throw new PluginException(pnfe1); + } + } + + // + // INTERFACE FredPluginTalker + // + + /** + * {@inheritDoc} + */ + @Override + public void onReply(String pluginName, String identifier, SimpleFieldSet params, Bucket data) { + ConnectorListenerManager connectorListenerManager = getConnectorListenerManager(pluginName, identifier, false); + if (connectorListenerManager == null) { + /* we don’t care about events for this plugin. */ + return; + } + connectorListenerManager.fireReceivedReply(params, data); + } + +} diff --git a/src/main/java/net/pterodactylus/sone/freenet/wot/PluginException.java b/src/main/java/net/pterodactylus/sone/freenet/wot/PluginException.java new file mode 100644 index 0000000..36cf49a --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/freenet/wot/PluginException.java @@ -0,0 +1,66 @@ +/* + * Sone - PluginException.java - Copyright © 2010 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 3 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, see . + */ + +package net.pterodactylus.sone.freenet.wot; + +/** + * Exception that signals an error when communicating with a plugin. + * + * @author David ‘Bombe’ Roden + */ +public class PluginException extends Exception { + + /** + * Creates a new plugin exception. + */ + public PluginException() { + super(); + } + + /** + * Creates a new plugin exception. + * + * @param message + * The message of the exception + */ + public PluginException(String message) { + super(message); + } + + /** + * Creates a new plugin exception. + * + * @param cause + * The cause of the exception + */ + public PluginException(Throwable cause) { + super(cause); + } + + /** + * Creates a new plugin exception. + * + * @param message + * The message of the exception + * @param cause + * The cause of the exception + */ + public PluginException(String message, Throwable cause) { + super(message, cause); + } + +}