--- /dev/null
+/*
+ * Sone - Identity.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 <http://www.gnu.org/licenses/>.
+ */
+
+package net.pterodactylus.sone.freenet.wot;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A Web of Trust identity.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class Identity {
+
+ /** The ID of the identity. */
+ private final String id;
+
+ /** The nickname of the identity. */
+ private final String nickname;
+
+ /** The request URI of the identity. */
+ private final String requestUri;
+
+ /** The contexts of the identity. */
+ protected final Set<String> contexts = Collections.synchronizedSet(new HashSet<String>());
+
+ /** The properties of the identity. */
+ private final Map<String, String> properties = Collections.synchronizedMap(new HashMap<String, String>());
+
+ /**
+ * Creates a new identity.
+ *
+ * @param id
+ * The ID of the identity
+ * @param nickname
+ * The nickname of the identity
+ * @param requestUri
+ * The request URI of the identity
+ */
+ public Identity(String id, String nickname, String requestUri) {
+ this.id = id;
+ this.nickname = nickname;
+ this.requestUri = requestUri;
+ }
+
+ //
+ // ACCESSORS
+ //
+
+ /**
+ * Returns the ID of the identity.
+ *
+ * @return The ID of the identity
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Returns the nickname of the identity.
+ *
+ * @return The nickname of the identity
+ */
+ public String getNickname() {
+ return nickname;
+ }
+
+ /**
+ * Returns the request URI of the identity.
+ *
+ * @return The request URI of the identity
+ */
+ public String getRequestUri() {
+ return requestUri;
+ }
+
+ /**
+ * Returns the contexts of the identity.
+ *
+ * @return The contexts of the identity
+ */
+ public Set<String> getContexts() {
+ return Collections.unmodifiableSet(contexts);
+ }
+
+ /**
+ * Returns whether the identity contains the given context.
+ *
+ * @param context
+ * The context to check for
+ * @return {@code true} if this identity has the given context,
+ * {@code false} otherwise
+ */
+ public boolean hasContext(String context) {
+ return contexts.contains(context);
+ }
+
+ /**
+ * Returns the properties of the identity.
+ *
+ * @return The properties of the identity
+ */
+ public Map<String, String> getProperties() {
+ return Collections.unmodifiableMap(properties);
+ }
+
+ /**
+ * Returns the value of the property with the given name.
+ *
+ * @param name
+ * The name of the property
+ * @return The value of the property, or {@code null} if there is no such
+ * property
+ */
+ public String getProperty(String name) {
+ return properties.get(name);
+ }
+
+ /**
+ * Sets the property with the given name to the given value.
+ *
+ * @param name
+ * The name of the property to set
+ * @param value
+ * The new value of the property
+ */
+ public void setProperty(String name, String value) {
+ properties.put(name, value);
+ /* TODO - set property. */
+ }
+
+ /**
+ * Removes the property with the given name.
+ *
+ * @param name
+ * The name of the property to remove
+ */
+ public void removeProperty(String name) {
+ properties.remove(name);
+ /* TODO - remove property. */
+ }
+
+ //
+ // OBJECT METHODS
+ //
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (!(object instanceof Identity)) {
+ return false;
+ }
+ Identity identity = (Identity) object;
+ return identity.id.equals(id);
+ }
+
+}
--- /dev/null
+/*
+ * Sone - OwnIdentity.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 <http://www.gnu.org/licenses/>.
+ */
+
+package net.pterodactylus.sone.freenet.wot;
+
+/**
+ * An own identity is an identity that the owner of the node has full control
+ * over.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class OwnIdentity extends Identity {
+
+ /** The insert URI of the identity. */
+ private final String insertUri;
+
+ /**
+ * Creates a new own identity.
+ *
+ * @param id
+ * The ID of the identity
+ * @param nickname
+ * The nickname of the identity
+ * @param requestUri
+ * The request URI of the identity
+ * @param insertUri
+ * The insert URI of the identity
+ */
+ public OwnIdentity(String id, String nickname, String requestUri, String insertUri) {
+ super(id, nickname, requestUri);
+ this.insertUri = insertUri;
+ }
+
+ //
+ // ACCESSORS
+ //
+
+ /**
+ * Returns the insert URI of the identity.
+ *
+ * @return The insert URI of the identity
+ */
+ public String getInsertUri() {
+ return insertUri;
+ }
+
+ /**
+ * Adds the given context to this identity.
+ *
+ * @param context
+ * The context to add
+ */
+ public void addContext(String context) {
+ if (contexts.add(context)) {
+ /* TODO - add. */
+ }
+ }
+
+ /**
+ * Removes the given context from this identity.
+ *
+ * @param context
+ * The context to remove
+ */
+ public void removeContext(String context) {
+ if (contexts.remove(context)) {
+ /* TODO - remove */
+ }
+ }
+
+ //
+ // OBJECT METHODS
+ //
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "[id=" + getId() + ",nickname=" + getNickname() + ",requestUri=" + getRequestUri() + ",insertUri=" + insertUri + "]";
+ }
+
+}
--- /dev/null
+/*
+ * Sone - WebOfTrustConnector.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 <http://www.gnu.org/licenses/>.
+ */
+
+package net.pterodactylus.sone.freenet.wot;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import net.pterodactylus.util.logging.Logging;
+import freenet.support.SimpleFieldSet;
+import freenet.support.api.Bucket;
+
+/**
+ * Connector for the Web of Trust plugin.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class WebOfTrustConnector implements ConnectorListener {
+
+ /** The logger. */
+ private static final Logger logger = Logging.getLogger(WebOfTrustConnector.class);
+
+ /** The name of the WoT plugin. */
+ private static final String WOT_PLUGIN_NAME = "plugins.WoT.WoT";
+
+ /** A random connection identifier. */
+ private static final String PLUGIN_CONNECTION_IDENTIFIER = "Sone-WoT-Connector-" + Math.abs(Math.random());
+
+ /** The current replies that we wait for. */
+ private final Map<String, Reply> replies = Collections.synchronizedMap(new HashMap<String, Reply>());
+
+ /** The plugin connector. */
+ private final PluginConnector pluginConnector;
+
+ /**
+ * Creates a new Web of Trust connector that uses the given plugin
+ * connector.
+ *
+ * @param pluginConnector
+ * The plugin connector
+ */
+ public WebOfTrustConnector(PluginConnector pluginConnector) {
+ this.pluginConnector = pluginConnector;
+ pluginConnector.addConnectorListener(WOT_PLUGIN_NAME, PLUGIN_CONNECTION_IDENTIFIER, this);
+ }
+
+ //
+ // ACTIONS
+ //
+
+ /**
+ * Loads all own identities from the Web of Trust plugin.
+ *
+ * @return All own identity
+ * @throws PluginException
+ * if the own identities can not be loaded
+ */
+ public Set<OwnIdentity> loadAllOwnIdentities() throws PluginException {
+ Reply reply = performRequest("OwnIdentities", SimpleFieldSetConstructor.create().put("Message", "GetOwnIdentities").get());
+ SimpleFieldSet fields = reply.getFields();
+ int ownIdentityCounter = -1;
+ Set<OwnIdentity> ownIdentities = new HashSet<OwnIdentity>();
+ while (true) {
+ String id = fields.get("Identity" + ++ownIdentityCounter);
+ if (id == null) {
+ break;
+ }
+ String requestUri = fields.get("RequestURI" + ownIdentityCounter);
+ String insertUri = fields.get("InsertURI" + ownIdentityCounter);
+ String nickname = fields.get("Nickname" + ownIdentityCounter);
+ OwnIdentity ownIdentity = new OwnIdentity(id, nickname, requestUri, insertUri);
+ ownIdentities.add(ownIdentity);
+ }
+ return ownIdentities;
+ }
+
+ //
+ // PRIVATE ACTIONS
+ //
+
+ /**
+ * Sends a request containing the given fields and waits for the target
+ * message.
+ *
+ * @param targetMessage
+ * The message of the reply to wait for
+ * @param fields
+ * The fields of the message
+ * @return The reply message
+ * @throws PluginException
+ * if the request could not be sent
+ */
+ private Reply performRequest(String targetMessage, SimpleFieldSet fields) throws PluginException {
+ return performRequest(targetMessage, fields, null);
+ }
+
+ /**
+ * Sends a request containing the given fields and waits for the target
+ * message.
+ *
+ * @param targetMessage
+ * The message of the reply to wait for
+ * @param fields
+ * The fields of the message
+ * @param data
+ * The payload of the message
+ * @return The reply message
+ * @throws PluginException
+ * if the request could not be sent
+ */
+ private Reply performRequest(String targetMessage, SimpleFieldSet fields, Bucket data) throws PluginException {
+ @SuppressWarnings("synthetic-access")
+ Reply reply = new Reply();
+ replies.put(targetMessage, reply);
+ synchronized (reply) {
+ pluginConnector.sendRequest(WOT_PLUGIN_NAME, PLUGIN_CONNECTION_IDENTIFIER, fields, data);
+ try {
+ reply.wait();
+ } catch (InterruptedException ie1) {
+ logger.log(Level.WARNING, "Got interrupted while waiting for reply on GetOwnIdentities.", ie1);
+ }
+ }
+ return reply;
+ }
+
+ //
+ // INTERFACE ConnectorListener
+ //
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void receivedReply(PluginConnector pluginConnector, SimpleFieldSet fields, Bucket data) {
+ String messageName = fields.get("Message");
+ Reply reply = replies.remove(messageName);
+ if (reply == null) {
+ logger.log(Level.FINE, "Not waiting for a “%s” message.", messageName);
+ return;
+ }
+ synchronized (reply) {
+ reply.setFields(fields);
+ reply.setData(data);
+ reply.notify();
+ }
+ }
+
+ /**
+ * Container for the data of the reply from a plugin.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+ private static class Reply {
+
+ /** The fields of the reply. */
+ private SimpleFieldSet fields;
+
+ /** The payload of the reply. */
+ private Bucket data;
+
+ /**
+ * Returns the fields of the reply.
+ *
+ * @return The fields of the reply
+ */
+ public SimpleFieldSet getFields() {
+ return fields;
+ }
+
+ /**
+ * Sets the fields of the reply.
+ *
+ * @param fields
+ * The fields of the reply
+ */
+ public void setFields(SimpleFieldSet fields) {
+ this.fields = fields;
+ }
+
+ /**
+ * Returns the payload of the reply.
+ *
+ * @return The payload of the reply (may be {@code null})
+ */
+ @SuppressWarnings("unused")
+ public Bucket getData() {
+ return data;
+ }
+
+ /**
+ * Sets the payload of the reply.
+ *
+ * @param data
+ * The payload of the reply (may be {@code null})
+ */
+ public void setData(Bucket data) {
+ this.data = data;
+ }
+
+ }
+
+ /**
+ * Helper method to create {@link SimpleFieldSet}s with terser code.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+ private static class SimpleFieldSetConstructor {
+
+ /** The field set being created. */
+ private SimpleFieldSet simpleFieldSet;
+
+ /**
+ * Creates a new simple field set constructor.
+ *
+ * @param shortLived
+ * {@code true} if the resulting simple field set should be
+ * short-lived, {@code false} otherwise
+ */
+ private SimpleFieldSetConstructor(boolean shortLived) {
+ simpleFieldSet = new SimpleFieldSet(shortLived);
+ }
+
+ //
+ // ACCESSORS
+ //
+
+ /**
+ * Returns the created simple field set.
+ *
+ * @return The created simple field set
+ */
+ public SimpleFieldSet get() {
+ return simpleFieldSet;
+ }
+
+ /**
+ * Sets the field with the given name to the given value.
+ *
+ * @param name
+ * The name of the fleld
+ * @param value
+ * The value of the field
+ * @return This constructor (for method chaining)
+ */
+ public SimpleFieldSetConstructor put(String name, String value) {
+ simpleFieldSet.putOverwrite(name, value);
+ return this;
+ }
+
+ //
+ // ACTIONS
+ //
+
+ /**
+ * Creates a new simple field set constructor.
+ *
+ * @return The created simple field set constructor
+ */
+ public static SimpleFieldSetConstructor create() {
+ return create(true);
+ }
+
+ /**
+ * Creates a new simple field set constructor.
+ *
+ * @param shortLived
+ * {@code true} if the resulting simple field set should be
+ * short-lived, {@code false} otherwise
+ * @return The created simple field set constructor
+ */
+ public static SimpleFieldSetConstructor create(boolean shortLived) {
+ SimpleFieldSetConstructor simpleFieldSetConstructor = new SimpleFieldSetConstructor(shortLived);
+ return simpleFieldSetConstructor;
+ }
+
+ }
+
+}