From 5ac1da7c51270ade6171b9755cc26c9b2385c426 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Fri, 29 Oct 2010 21:41:27 +0200 Subject: [PATCH] Add stub of Web of Trust plugin connector. --- .../pterodactylus/sone/freenet/wot/Identity.java | 185 +++++++++++++ .../sone/freenet/wot/OwnIdentity.java | 97 +++++++ .../sone/freenet/wot/WebOfTrustConnector.java | 297 +++++++++++++++++++++ 3 files changed, 579 insertions(+) create mode 100644 src/main/java/net/pterodactylus/sone/freenet/wot/Identity.java create mode 100644 src/main/java/net/pterodactylus/sone/freenet/wot/OwnIdentity.java create mode 100644 src/main/java/net/pterodactylus/sone/freenet/wot/WebOfTrustConnector.java diff --git a/src/main/java/net/pterodactylus/sone/freenet/wot/Identity.java b/src/main/java/net/pterodactylus/sone/freenet/wot/Identity.java new file mode 100644 index 0000000..c3053ae --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/freenet/wot/Identity.java @@ -0,0 +1,185 @@ +/* + * 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 . + */ + +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 David ‘Bombe’ Roden + */ +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 contexts = Collections.synchronizedSet(new HashSet()); + + /** The properties of the identity. */ + private final Map properties = Collections.synchronizedMap(new HashMap()); + + /** + * 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 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 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); + } + +} diff --git a/src/main/java/net/pterodactylus/sone/freenet/wot/OwnIdentity.java b/src/main/java/net/pterodactylus/sone/freenet/wot/OwnIdentity.java new file mode 100644 index 0000000..626c4a8 --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/freenet/wot/OwnIdentity.java @@ -0,0 +1,97 @@ +/* + * 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 . + */ + +package net.pterodactylus.sone.freenet.wot; + +/** + * An own identity is an identity that the owner of the node has full control + * over. + * + * @author David ‘Bombe’ Roden + */ +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 + "]"; + } + +} diff --git a/src/main/java/net/pterodactylus/sone/freenet/wot/WebOfTrustConnector.java b/src/main/java/net/pterodactylus/sone/freenet/wot/WebOfTrustConnector.java new file mode 100644 index 0000000..65b7ce8 --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/freenet/wot/WebOfTrustConnector.java @@ -0,0 +1,297 @@ +/* + * 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 . + */ + +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 David ‘Bombe’ Roden + */ +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 replies = Collections.synchronizedMap(new HashMap()); + + /** 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 loadAllOwnIdentities() throws PluginException { + Reply reply = performRequest("OwnIdentities", SimpleFieldSetConstructor.create().put("Message", "GetOwnIdentities").get()); + SimpleFieldSet fields = reply.getFields(); + int ownIdentityCounter = -1; + Set ownIdentities = new HashSet(); + 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 David ‘Bombe’ Roden + */ + 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 David ‘Bombe’ Roden + */ + 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; + } + + } + +} -- 2.7.4