Author: tullyvey
Date: 2007-10-03 13:21:48 +0000 (Wed, 03 Oct 2007)
New Revision: 15428

Added:
   trunk/apps/jfcp/src/org/freenetproject/
   trunk/apps/jfcp/src/org/freenetproject/contrib/
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/FcpConnection.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/FcpMessage.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/FreenetClient.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/NodeAddress.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/NodeInfo.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/AllDataEvent.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/DataFoundEvent.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpConnectEvent.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpDisconnectEvent.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpEvent.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpKeyRequestedEvent.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpPeerListUpdatedEvent.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpPeerNotesUpdatedEvent.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpSimpleProgressEvent.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/GetFailedEvent.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/SSKKeypairEvent.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/URIGeneratedEvent.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/package.html
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/AbstractFcpEventSupport.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpConnectionEventSupport.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpEventSource.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpEventSupportRepository.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpPeerListEventSupport.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpQueueEventSupport.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpSSKKeypairEventSupport.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/package.html
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/FcpConnectionListener.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/FcpPeerListListener.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/FcpQueueListener.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/FcpSSKKeypairListener.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/package.html
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/FcpMessageInputStream.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/FcpMessageOutputStream.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/MessageBuilderException.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/Persistence.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/ReturnType.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/UploadFrom.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientGet.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientHello.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientMessage.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientPut.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientPutDiskDir.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/GenerateSSK.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ListPeerNotes.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ListPeers.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ModifyPeerNote.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ShutDown.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/package.html
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/AllData.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/DataFound.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/EndListPeerNotes.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/EndListPeers.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/GetFailed.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/IdentifierCollision.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/NodeHello.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/NodeMessage.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/Peer.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/PeerNote.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/PersistentPut.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/SSKKeypair.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/SimpleProgress.java
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/URIGenerated.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/package.html
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/package.html
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/package.html
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/
   
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/LastRoutingBackoffReason.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/PeerMetaData.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/PeerVolatileData.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/Status.java
   trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/package.html
Removed:
   trunk/apps/jfcp/src/org/freenet/
Log:
changed package to org.freenetproject...

tweaked FcpMessageInputStream and FcpMessageOutputStream to (hopefully) 
correctly handle UTF-8

Copied: trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/FcpConnection.java 
(from rev 15426, trunk/apps/jfcp/src/org/freenet/contrib/fcp/FcpConnection.java)
===================================================================
--- trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/FcpConnection.java       
                        (rev 0)
+++ trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/FcpConnection.java       
2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,192 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.logging.Logger;
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+import org.freenetproject.contrib.fcp.message.FcpMessageInputStream;
+import org.freenetproject.contrib.fcp.message.FcpMessageOutputStream;
+import org.freenetproject.contrib.fcp.message.MessageBuilderException;
+import org.freenetproject.contrib.fcp.message.client.ClientHello;
+import org.freenetproject.contrib.fcp.message.client.ClientMessage;
+import org.freenetproject.contrib.fcp.message.node.NodeMessage;
+
+
+
+/**
+ * Responsible for sending data to the node.
+ *
+ * @author Ralph Smithen
+ */
+public class FcpConnection {
+    private static Logger logger = 
Logger.getLogger(FcpConnection.class.getName());
+    
+    private String _fcpVersion = "2.0";
+    private String _clientName = "FreenetClient";
+    
+    private Socket                      _socket;
+    private FcpMessageOutputStream      _mos;
+    private FcpMessageInputStream       _mis;
+    private NodeAddress                 _nodeAddress;
+    private ExecutorService             _messageSender;
+    private MessageReaderThread         _messageReaderThread;
+    private FcpEventSupportRepository   _eventSupport;
+    private boolean                     _socketOpen;
+    
+    /** Creates a new instance of FcpConnection */
+    FcpConnection(NodeAddress na, FcpEventSupportRepository eventSupport) {
+        _nodeAddress = na;
+        _eventSupport = eventSupport;
+    }
+    
+    /** Creates a new instance of FcpConnection */
+    FcpConnection(NodeAddress na, FcpEventSupportRepository eventSupport, 
String name) {
+        this(na, eventSupport);
+        _clientName = name;
+    }
+    
+    /**
+     * Opens a socket to the node.
+     * @throws java.net.UnknownHostException if host not found.
+     * @throws java.io.IOException on IO error.
+     */
+    public void open() throws UnknownHostException, IOException{
+        if(_socketOpen)
+            return;
+        logger.fine("opening socket to " + _nodeAddress.getHostName() + ":" + 
_nodeAddress.getPort());
+        _socket = new Socket(_nodeAddress.getHostName(), 
_nodeAddress.getPort());
+        _mis = new FcpMessageInputStream(_socket.getInputStream());
+        _mos = new FcpMessageOutputStream(_socket.getOutputStream());
+        _messageSender = Executors.newSingleThreadExecutor();
+        _messageReaderThread = new MessageReaderThread();
+        _socketOpen = true;
+        _messageReaderThread.start();
+        sendMessage(new ClientHello(_fcpVersion, _clientName));
+    }
+    
+    /**
+     * Closes the connection to the node.
+     */
+    public void close(){
+        _socketOpen = false;
+        if(_messageSender != null){
+            _messageSender.shutdownNow();
+            _messageSender = null;
+        }
+        _messageReaderThread = null;
+        if(_socket != null){
+            try {
+                _socket.close();
+            } catch (Exception ex) {
+                logger.warning("error closing socket: " + ex.getMessage());
+            }
+            _socket = null;
+        }
+        if(_mis != null){
+            try {
+                _mis.close();
+            } catch (Exception ex) {
+                logger.warning("error closing input stream: " + 
ex.getMessage());
+            }
+            _mis = null;
+        }
+        if(_mos != null){
+            try {
+                _mos.close();
+            } catch (Exception ex) {
+                logger.warning("error closing output stream: " + 
ex.getMessage());
+            }
+            _mos = null;
+        }
+        _eventSupport.getConnectionEventSupport().fireFcpDisconnected();
+    }
+    
+    /**
+     * Sends a message to the node.  This method returns immediately,
+     * the message is put in a queue to be sent.
+     * @param message The message to be sent.
+     */
+    public void sendMessage(ClientMessage message){
+        if(_socketOpen)
+            _messageSender.execute(new MessageHolder(message));
+    }
+    
+    private class MessageHolder implements Runnable{
+        private final ClientMessage _message;
+        
+        MessageHolder(ClientMessage message){
+            _message = message;
+        }
+        
+        public void run() {
+            if(_mos == null)
+                return;
+            try {
+                _mos.writeMessage(_message);
+                _mos.flush();
+                _message.fireEvents(_eventSupport);
+            } catch (IOException ex) {
+                logger.warning("IO error sending message: " + 
_message.getHeaderString());
+                close();
+            } catch (MessageBuilderException ex) {
+                logger.warning("invalid message:\n\n" + 
_message.getHeaderString() + "\n\n");
+            }
+        }
+    }
+    
+    
+    
+    /**
+     * Determine whether the connection is up.
+     * @return boolean reflecting the connection's upness.
+     */
+    public boolean isSocketOpen() {
+        return _socketOpen;
+    }
+    
+    /**
+     * get the node address for this connection
+     * @return the {@link NodeAddress NodeAddress}
+     */
+    public NodeAddress getNodeAddress() {
+        return _nodeAddress;
+    }
+    
+    /**
+     * Setter for NodeAddress.  Doesn't trigger a reconnection.
+     * @param nodeAddress the new {@link NodeAddress NodeAddress}
+     */
+    public void setNodeAddress(NodeAddress nodeAddress) {
+        _nodeAddress = nodeAddress;
+    }
+    
+    
+    private class MessageReaderThread extends Thread{        
+        public void run(){
+            try {
+                while(_socketOpen){
+                    try {
+                        NodeMessage message = _mis.readMessage();
+                        message.fireEvents(_eventSupport);
+                    } catch (MessageBuilderException ex) {
+                            logger.warning("error building node message: " + 
ex.getMessage());
+                    }
+                }
+            } catch (IOException ex) {
+                if(_socketOpen)
+                    logger.warning("error reading stream: " + ex.getMessage());
+            }
+            if(_socketOpen)
+                close();
+        }
+        
+    }
+    
+}

Copied: trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/FcpMessage.java 
(from rev 15426, trunk/apps/jfcp/src/org/freenet/contrib/fcp/FcpMessage.java)
===================================================================
--- trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/FcpMessage.java          
                (rev 0)
+++ trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/FcpMessage.java  
2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,121 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+import org.freenetproject.contrib.fcp.message.MessageBuilderException;
+
+/**
+ * The superclass of all FCP messages.
+ * @author Ralph Smithen
+ */
+public abstract class FcpMessage{
+    /**
+     * the name=value pairs of the message
+     */
+    protected Map<String, String>   _fields = new HashMap();
+    /**
+     * the name of the message
+     */
+    protected String                _headerString;
+    
+    /**
+     * the payload data of the message
+     */
+    protected byte[]                  _data;
+    
+    /**
+     * Creates new instance, assigns {@link #_headerString _headerString}.
+     */
+    public FcpMessage(){
+        _headerString = this.getClass().getSimpleName();
+    }
+    
+    /**
+     * Accessor for message's fields.
+     * @return the message fields
+     */
+    public Map<String, String> getFields() {
+        return _fields;
+    }
+    
+    /**
+     * Get the name of the message.
+     * @return the name
+     */
+    public String getHeaderString(){
+        return _headerString;
+    }
+    
+    /**
+     * Trigger the events upon receipt or transmission of a message.
+     * @param eventSupport the object to be notified of message events
+     */
+    protected abstract void fireEvents(FcpEventSupportRepository eventSupport);
+    
+    /**
+     * Get the fields that must be non-null in a valid message.
+     * @return an array of <code>String</code>s, the names of the mandatory 
fields
+     */
+    public String[] getMandatoryFields() {
+        return new String[] {};
+    }
+    
+    /**
+     * Checks mandatory fields.
+     * @throws org.freenet.contrib.fcp.message.MessageBuilderException if 
required field absent
+     */
+    public void validate() throws MessageBuilderException{
+        
+        for(String field : getMandatoryFields()){
+            if(_fields.get(field) == null)
+                throw new MessageBuilderException("mandatory field " + field + 
" not found in message " + _headerString);
+        }
+    }    
+    
+    /**
+     * Gets the value of the "DataLength" field.
+     * @return the length in <code>byte</code>s of payload data
+     */
+    public int getDataLength() {
+        return Integer.parseInt(_fields.get("DataLength"));
+    }
+    
+    /**
+     * Sets the value of the "DataLength" field.
+     * @param dataLength the new length in <code>byte</code>s of payload data 
to be set
+     */
+    void setDataLength(int dataLength) {
+        _fields.put("DataLength", String.valueOf(dataLength));
+    }
+    
+    /**
+     * Get the message's data.
+     * @return the payload data
+     */
+    public byte[] getData() {
+        return _data;
+    }
+    
+    /**
+     * Sets the payload data, also invokes the {@link #setDataLength(int) 
setDataLength} 
+     * method with the new length.
+     * @param data the payload data for the message
+     */
+    public void setData(byte[] data) {
+        _data = data;
+        setDataLength(data.length);
+    }
+    
+    /**
+     * Has the message data?
+     * @return true if {@link #_data _data} is not <code>null</code>
+     */
+    public boolean isData(){
+        return _data != null;
+    }
+}

Copied: trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/FreenetClient.java 
(from rev 15426, trunk/apps/jfcp/src/org/freenet/contrib/fcp/FreenetClient.java)
===================================================================
--- trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/FreenetClient.java       
                        (rev 0)
+++ trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/FreenetClient.java       
2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,122 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp;
+
+import java.io.IOException;
+import java.net.UnknownHostException;
+import org.freenetproject.contrib.fcp.event.support.FcpEventSource;
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+import org.freenetproject.contrib.fcp.message.client.ClientGet;
+import org.freenetproject.contrib.fcp.message.client.ClientMessage;
+import org.freenetproject.contrib.fcp.message.client.ClientPut;
+import org.freenetproject.contrib.fcp.message.client.GenerateSSK;
+import org.freenetproject.contrib.fcp.message.client.ListPeerNotes;
+import org.freenetproject.contrib.fcp.message.client.ListPeers;
+
+/**
+ * The main class of the library, start here!
+ * Note that the api may be subject to change.
+ * @author Ralph Smithen
+ */
+public class FreenetClient{
+    private static String DEFAULT_CLIENT_NAME = "FreenetClient";
+    
+    private FcpEventSupportRepository   _eventSupport;
+    private FcpEventSource              _eventSource;
+    private FcpConnection               _conn;
+    
+    /**
+     * Creates a new client called "FreenetClient" that will attempt to 
connect 
+     * to 127.0.0.1:9481.
+     */
+    public FreenetClient(){
+        this(new NodeAddress(), DEFAULT_CLIENT_NAME);
+    }
+    
+    /**
+     * Creates a named client that attempts to connect to 127.0.0.1:9481.
+     * @param name the name of the client
+     */
+    public FreenetClient(String name){
+        this(new NodeAddress(), name);
+    }
+    
+    /**
+     * Creates a new instance of FreenetClient
+     * @param na where to connect
+     * @param name how the client's identified by the node
+     */
+    public FreenetClient(NodeAddress na, String name) {
+        _eventSupport = new FcpEventSupportRepository();
+        _eventSource = new FcpEventSource(_eventSupport);
+        _conn = new FcpConnection(na, _eventSupport, name);
+    }
+    
+    /**
+     * Returns an object by which interested classes can register to listen 
+     * for incoming message events.
+     * @return the event source
+     */
+    public FcpEventSource getEventSource(){
+        return _eventSource;
+    }
+
+    
+    /**
+     * Get the client's connection to manipulate.
+     * @return the conn
+     */
+    public FcpConnection getConnection() {
+        return _conn;
+    }
+
+    /**
+     * Request the peer data from node.
+     */
+    public void refreshPeerList(){
+        _conn.sendMessage(new ListPeers(true, true));
+    }
+    
+    /**
+     * Request peer notes from node.
+     */
+    public void listPeerNotes(String peer){
+        _conn.sendMessage(new ListPeerNotes(peer));
+    }
+    
+    /**
+     * Request data from node.
+     * @param uri the key, e.g. CHK at blah
+     * @param id an identifier for use in your app
+     */
+    public void get(String uri, String id, int priority){
+        ClientGet cg = new ClientGet(uri, id);
+        cg.setVerbosity(1);
+        cg.setPriority(priority);
+        _conn.sendMessage(cg);
+    }
+    
+    
+    /**
+     * Inserts data to node.
+     * @param uri 
+     * @param id 
+     * @param data 
+     */
+    public void put(String uri, String id, int priority, byte[] data){
+        ClientPut cp = new ClientPut(uri, id, data);
+        cp.setVerbosity(1);
+        cp.setPriority(2);
+        _conn.sendMessage(cp);
+    }
+    
+    /**
+     * Will probably change
+     * @param id an id for your convenience
+     */
+    public void generateSSK(String id){
+        _conn.sendMessage(new GenerateSSK(id));
+    }
+}

Copied: trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/NodeAddress.java 
(from rev 15426, trunk/apps/jfcp/src/org/freenet/contrib/fcp/NodeAddress.java)
===================================================================
--- trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/NodeAddress.java         
                (rev 0)
+++ trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/NodeAddress.java 
2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,32 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp;
+
+import java.net.InetSocketAddress;
+
+/**
+ * Connection properties of friend.
+ * @author Ralph Smithen
+ */
+public class NodeAddress extends InetSocketAddress{
+    public static int DEFAULT_PORT = 9481;
+    public static String DEFAULT_HOST = "127.0.0.1";
+    
+    /** Creates a new instance of NodeAddress. */
+    public NodeAddress() {
+        super(DEFAULT_HOST, DEFAULT_PORT);
+    }
+    
+    /** Creates a new instance of NodeAddress specifying a non-standard port. 
*/
+    public NodeAddress(int port){
+        super(DEFAULT_HOST, port);
+    }
+    
+    /** Creates a new instance of NodeAddress specifying the host and port. */
+    public NodeAddress(String host, int port){
+        super(host, port);
+    }
+    
+}

Copied: trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/NodeInfo.java (from 
rev 15426, trunk/apps/jfcp/src/org/freenet/contrib/fcp/NodeInfo.java)
===================================================================
--- trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/NodeInfo.java            
                (rev 0)
+++ trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/NodeInfo.java    
2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,237 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp;
+
+import org.freenetproject.contrib.fcp.message.node.Peer;
+
+/**
+ * Holds data associated with a node or peer.
+ * @author Ralph Smithen
+ */
+public class NodeInfo {
+    private String _fcpVersion;
+    private String _node;
+    private String _build;
+    private String _extRevision;
+    private boolean _testNet;
+    private String _extBuild;
+    private String _compressionCodecs;
+    private String _revision;
+    
+    private String _lastGoodVersion;
+    private String _physicalUdp;
+    private String _id;
+    private String _dsaGroupG;
+    private String _name;
+    private String _dsaPubKeyY;
+    private String _dsaGroupQ;
+    private String _arkNumber;
+    private String _version;
+    private String _arkPubUri;
+    private String _dsaGroupP;
+    private double _location;
+    private boolean _testnet;
+    
+    /** Creates a new instance of NodeInfo */
+    public NodeInfo() {
+    }
+    
+    /**
+     * Instantiates NodeInfo from Peer.
+     * @param p the peer
+     */
+    public NodeInfo(Peer p){
+        _lastGoodVersion=p.getLastGoodVersion();
+        _physicalUdp=p.getPhysicalUdp();
+        _id=p.getId();
+        _dsaGroupG=p.getDsaGroupG();
+        _name=p.getName();
+        _dsaPubKeyY=p.getDsaPubKeyY();
+        _dsaGroupQ=p.getDsaGroupQ();
+        _arkNumber=p.getArkNumber();
+        _version=p.getVersion();
+        _arkPubUri=p.getArkPubUri();
+        _dsaGroupP=p.getDsaGroupP();
+        _location=p.getLocation();
+        _testNet=p.isTestnet();
+    }
+    
+    /**
+     * Get the version of FCP for this node.
+     * @return the FCP version
+     */
+    public String getFcpVersion() {
+        return _fcpVersion;
+    }
+    
+    /**
+     * Sets teh FCP version
+     * @param fcpVersion the FCP version, e.g. "2.0"
+     */
+    public void setFcpVersion(String fcpVersion) {
+        this._fcpVersion = fcpVersion;
+    }
+    
+    /**
+     * Get Fred version
+     * @return the version of Fred
+     */
+    public String getVersion() {
+        return _version;
+    }
+    
+    public void setVersion(String version) {
+        this._version = version;
+    }
+    
+    public String getBuild() {
+        return _build;
+    }
+    
+    public void setBuild(String build) {
+        this._build = build;
+    }
+    
+    public String getExtRevision() {
+        return _extRevision;
+    }
+    
+    public void setExtRevision(String extRevision) {
+        this._extRevision = extRevision;
+    }
+    
+    public boolean isTestNet() {
+        return _testNet;
+    }
+    
+    public void setTestNet(boolean testNet) {
+        this._testNet = testNet;
+    }
+    
+    public String getExtBuild() {
+        return _extBuild;
+    }
+    
+    public void setExtBuild(String extBuild) {
+        this._extBuild = extBuild;
+    }
+    
+    public String getCompressionCodecs() {
+        return _compressionCodecs;
+    }
+    
+    public void setCompressionCodecs(String compressionCodecs) {
+        this._compressionCodecs = compressionCodecs;
+    }
+    
+    public String getRevision() {
+        return _revision;
+    }
+    
+    public void setRevision(String revision) {
+        this._revision = revision;
+    }
+    
+    public String getPhysicalUdp() {
+        return _physicalUdp;
+    }
+    
+    public void setPhysicalUdp(String physicalUdp) {
+        this._physicalUdp = physicalUdp;
+    }
+    
+    public String getLastGoodVersion() {
+        return _lastGoodVersion;
+    }
+    
+    public void setLastGoodVersion(String lastGoodVersion) {
+        this._lastGoodVersion = lastGoodVersion;
+    }
+    
+    public String getArkPubUri() {
+        return _arkPubUri;
+    }
+    
+    public void setArkPubUri(String arkPubUri) {
+        this._arkPubUri = arkPubUri;
+    }
+    
+    public String getArkNumber() {
+        return _arkNumber;
+    }
+    
+    public void setArkNumber(String arkNumber) {
+        this._arkNumber = arkNumber;
+    }
+    
+    public String getId() {
+        return _id;
+    }
+    
+    public void setId(String id) {
+        this._id = id;
+    }
+    
+    public String getName() {
+        return _name;
+    }
+    
+    public void setName(String name) {
+        this._name = name;
+    }
+    
+    public double getLocation() {
+        return _location;
+    }
+    
+    public void setLocation(double location) {
+        this._location = location;
+    }
+    
+    public String getDsaGroupG() {
+        return _dsaGroupG;
+    }
+    
+    public void setDsaGroupG(String dsaGroupG) {
+        this._dsaGroupG = dsaGroupG;
+    }
+    
+    public String getDsaPubKeyY() {
+        return _dsaPubKeyY;
+    }
+    
+    public void setDsaPubKeyY(String dsaPubKeyY) {
+        this._dsaPubKeyY = dsaPubKeyY;
+    }
+    
+    public String getDsaGroupQ() {
+        return _dsaGroupQ;
+    }
+    
+    public void setDsaGroupQ(String dsaGroupQ) {
+        this._dsaGroupQ = dsaGroupQ;
+    }
+    
+    public String getDsaGroupP() {
+        return _dsaGroupP;
+    }
+    
+    public void setDsaGroupP(String dsaGroupP) {
+        this._dsaGroupP = dsaGroupP;
+    }
+    
+    public boolean isTestnet() {
+        return _testnet;
+    }
+    
+    public void setTestnet(boolean testnet) {
+        this._testnet = testnet;
+    }
+    
+    public String toString(){
+        return getName();
+    }
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/AllDataEvent.java 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/AllDataEvent.java)
===================================================================
--- trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/AllDataEvent.java  
                        (rev 0)
+++ trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/AllDataEvent.java  
2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,22 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event;
+
+import java.util.Map;
+import org.freenetproject.contrib.fcp.NodeInfo;
+import org.freenetproject.contrib.fcp.message.node.AllData;
+import org.freenetproject.contrib.fcp.message.node.DataFound;
+
+/**
+ *
+ * @author res
+ */
+public class AllDataEvent extends FcpEvent<AllData>{
+
+    public AllDataEvent(AllData ad){
+        super(ad);
+    }
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/DataFoundEvent.java 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/DataFoundEvent.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/DataFoundEvent.java    
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/DataFoundEvent.java    
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,21 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event;
+
+import java.util.Map;
+import org.freenetproject.contrib.fcp.NodeInfo;
+import org.freenetproject.contrib.fcp.message.node.DataFound;
+
+/**
+ *
+ * @author res
+ */
+public class DataFoundEvent extends FcpEvent<DataFound>{
+
+    public DataFoundEvent(DataFound df){
+        super(df);
+    }
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpConnectEvent.java 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/FcpConnectEvent.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpConnectEvent.java   
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpConnectEvent.java   
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,20 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event;
+
+import org.freenetproject.contrib.fcp.message.node.NodeMessage;
+
+/**
+ *
+ * @author res
+ */
+public class FcpConnectEvent<NodeHello> extends FcpEvent{
+    
+    /** Creates a new instance of FcpConnectEvent */
+    public FcpConnectEvent(NodeHello message) {
+        super(message);
+    }
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpDisconnectEvent.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/FcpDisconnectEvent.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpDisconnectEvent.java
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpDisconnectEvent.java
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,17 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event;
+
+/**
+ *
+ * @author res
+ */
+public class FcpDisconnectEvent extends FcpEvent{
+    
+    /** Creates a new instance of FcpDisconnectEvent */
+    public FcpDisconnectEvent() {
+    }
+    
+}

Copied: trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpEvent.java 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/FcpEvent.java)
===================================================================
--- trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpEvent.java      
                        (rev 0)
+++ trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpEvent.java      
2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,33 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event;
+
+import java.util.Date;
+
+/**
+ *
+ * @author Ralph Smithen
+ */
+abstract class FcpEvent<MessageType> {
+    protected Date timeStamp = new Date();
+    private MessageType _message;
+    
+    /** Creates a new instance of FcpEvent */
+    public FcpEvent() {
+    }
+    
+    /** Creates a new instance of FcpNodeMessageEvent */
+    public FcpEvent(MessageType message) {
+        _message = message;
+    }
+    
+    public MessageType getMessage() {
+        return _message;
+    }
+
+    public Date getTimeStamp() {
+        return timeStamp;
+    }
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpKeyRequestedEvent.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/FcpKeyRequestedEvent.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpKeyRequestedEvent.java
                          (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpKeyRequestedEvent.java
  2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,26 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event;
+
+import java.util.Map;
+import org.freenetproject.contrib.fcp.NodeInfo;
+import org.freenetproject.contrib.fcp.message.client.ClientGet;
+
+/**
+ *
+ * @author res
+ */
+public class FcpKeyRequestedEvent extends FcpEvent<ClientGet>{
+    
+    /**
+     * Creates a new instance of FcpPeerListUpdatedEvent
+     */
+    public FcpKeyRequestedEvent(ClientGet cg) {
+        super(cg);
+    }
+    
+    
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpPeerListUpdatedEvent.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/FcpPeerListUpdatedEvent.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpPeerListUpdatedEvent.java
                               (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpPeerListUpdatedEvent.java
       2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,29 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event;
+
+import java.util.Map;
+import org.freenetproject.contrib.fcp.NodeInfo;
+import org.freenetproject.contrib.fcp.message.node.Peer;
+import org.freenetproject.contrib.fcp.peer.PeerMetaData;
+
+/**
+ *
+ * @author res
+ */
+public class FcpPeerListUpdatedEvent {
+    private Map<String, Peer> _peers;
+    /**
+     * Creates a new instance of FcpPeerListUpdatedEvent
+     */
+    public FcpPeerListUpdatedEvent(Map<String, Peer> peers) {
+        _peers = peers;
+    }
+
+    public Map<String, Peer> getPeers() {
+        return _peers;
+    }
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpPeerNotesUpdatedEvent.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/FcpPeerNotesUpdatedEvent.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpPeerNotesUpdatedEvent.java
                              (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpPeerNotesUpdatedEvent.java
      2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,29 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event;
+
+import java.util.Vector;
+import org.freenetproject.contrib.fcp.message.node.EndListPeerNotes;
+import org.freenetproject.contrib.fcp.message.node.PeerNote;
+
+/**
+ *
+ * @author Ralph Smithen
+ */
+public class FcpPeerNotesUpdatedEvent extends FcpEvent<EndListPeerNotes>{
+    Vector<PeerNote> _peerNotes;
+    /**
+     * Creates a new instance of FcpPeerNotesUpdatedEvent
+     */
+    public FcpPeerNotesUpdatedEvent(EndListPeerNotes elpn, Vector<PeerNote> 
peerNotes) {
+        super(elpn);
+        _peerNotes = peerNotes;
+    }
+    
+    public Vector<PeerNote> getPeerNotes(){
+        return _peerNotes;
+    }
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpSimpleProgressEvent.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/FcpSimpleProgressEvent.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpSimpleProgressEvent.java
                                (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/FcpSimpleProgressEvent.java
        2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,21 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event;
+
+import java.util.Map;
+import org.freenetproject.contrib.fcp.NodeInfo;
+import org.freenetproject.contrib.fcp.message.node.SimpleProgress;
+
+/**
+ *
+ * @author res
+ */
+public class FcpSimpleProgressEvent extends FcpEvent<SimpleProgress>{
+
+    public FcpSimpleProgressEvent(SimpleProgress sp){
+        super(sp);
+    }
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/GetFailedEvent.java 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/GetFailedEvent.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/GetFailedEvent.java    
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/GetFailedEvent.java    
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,20 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event;
+
+import org.freenetproject.contrib.fcp.message.node.GetFailed;
+
+/**
+ *
+ * @author res
+ */
+public class GetFailedEvent extends FcpEvent<GetFailed> {
+    
+    /** Creates a new instance of GetFailedEvent */
+    public GetFailedEvent(GetFailed gf) {
+        super(gf);
+    }
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/SSKKeypairEvent.java 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/SSKKeypairEvent.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/SSKKeypairEvent.java   
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/SSKKeypairEvent.java   
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,20 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event;
+
+import org.freenetproject.contrib.fcp.message.node.SSKKeypair;
+
+/**
+ *
+ * @author Ralph Smithen
+ */
+public class SSKKeypairEvent extends FcpEvent<SSKKeypair>{
+    
+    /** Creates a new instance of SSKKeypairEvent */
+    public SSKKeypairEvent(SSKKeypair kp) {
+        super(kp);
+    }
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/URIGeneratedEvent.java 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/URIGeneratedEvent.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/URIGeneratedEvent.java 
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/URIGeneratedEvent.java 
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,21 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event;
+
+import org.freenetproject.contrib.fcp.message.node.SSKKeypair;
+import org.freenetproject.contrib.fcp.message.node.URIGenerated;
+
+/**
+ *
+ * @author Ralph Smithen
+ */
+public class URIGeneratedEvent extends FcpEvent<URIGenerated>{
+    
+    /** Creates a new instance of URIGeneratedEvent */
+    public URIGeneratedEvent(URIGenerated ug) {
+        super(ug);
+    }
+    
+}

Copied: trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/package.html 
(from rev 15426, trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/package.html)
===================================================================
--- trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/package.html       
                        (rev 0)
+++ trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/package.html       
2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+  <head>
+  </head>
+  <body>
+      <h1>FCP event classes</h1>
+      <p>
+          The events that are generated upon receipt and transmission of 
messages
+          and such.
+      </p>
+  </body>
+</html>

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/AbstractFcpEventSupport.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/support/AbstractFcpEventSupport.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/AbstractFcpEventSupport.java
                               (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/AbstractFcpEventSupport.java
       2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,39 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event.support;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Support class to allow event support to be achieved more tersely.
+ * @author Ralph Smithen
+ */
+class AbstractFcpEventSupport<ListenerType> {
+    Set<ListenerType> _listeners = Collections.synchronizedSet(new HashSet());
+    
+    public void addListener(ListenerType l){
+        if(l != null)
+            _listeners.add(l);
+    }
+    
+    public void removeListener(ListenerType l){
+        if(l != null)
+            _listeners.remove(l);
+    }
+    
+    protected abstract class NotifyHelper<EventType>{
+        void notifyListeners(EventType e){
+            synchronized(_listeners){
+                for(ListenerType l : (Set<ListenerType>) _listeners){
+                    notifyListener(l, e);
+                }
+            }
+        }
+        abstract void notifyListener(ListenerType l, EventType e);
+    }
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpConnectionEventSupport.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/support/FcpConnectionEventSupport.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpConnectionEventSupport.java
                             (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpConnectionEventSupport.java
     2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,34 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event.support;
+
+import org.freenetproject.contrib.fcp.event.FcpConnectEvent;
+import org.freenetproject.contrib.fcp.event.FcpDisconnectEvent;
+import 
org.freenetproject.contrib.fcp.event.support.AbstractFcpEventSupport.NotifyHelper;
+import org.freenetproject.contrib.fcp.listener.FcpConnectionListener;
+import org.freenetproject.contrib.fcp.message.node.NodeHello;
+
+/**
+ *
+ * @author res
+ */
+public class FcpConnectionEventSupport extends 
AbstractFcpEventSupport<FcpConnectionListener>{
+    NotifyHelper _connectNotifier = new NotifyHelper<FcpConnectEvent>() {
+        void notifyListener(FcpConnectionListener l, FcpConnectEvent e) 
{l.nodeConnected(e);}
+    };
+    
+    NotifyHelper _disconnectNotifier = new NotifyHelper<FcpDisconnectEvent>() {
+        void notifyListener(FcpConnectionListener l, FcpDisconnectEvent e) 
{l.nodeDisconnected(e);}
+    };
+    
+    
+    public void fireFcpConnected(NodeHello nh){
+        _connectNotifier.notifyListeners(new FcpConnectEvent(nh));
+    }
+    
+    public void fireFcpDisconnected(){
+        _disconnectNotifier.notifyListeners(new FcpDisconnectEvent());
+    }
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpEventSource.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/support/FcpEventSource.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpEventSource.java
                                (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpEventSource.java
        2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,55 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event.support;
+
+import org.freenetproject.contrib.fcp.listener.FcpConnectionListener;
+import org.freenetproject.contrib.fcp.listener.FcpPeerListListener;
+import org.freenetproject.contrib.fcp.listener.FcpQueueListener;
+import org.freenetproject.contrib.fcp.listener.FcpSSKKeypairListener;
+
+/**
+ * Serves to hide the event-firing functionality.
+ * @author Ralph Smithen
+ */
+public class FcpEventSource {
+    private FcpEventSupportRepository _repository;
+    /** Creates a new instance of FcpEventSource */
+    public FcpEventSource(FcpEventSupportRepository repository) {
+        _repository = repository;
+    }
+    
+    public void addConnectionListener(FcpConnectionListener l){
+        _repository.getConnectionEventSupport().addListener(l);
+    }
+    
+    public void removeConnectionListener(FcpConnectionListener l){
+        _repository.getConnectionEventSupport().removeListener(l);
+    }
+    
+    public void addPeerListListener(FcpPeerListListener l){
+        _repository.getPeerListEventSupport().addListener(l);
+    }
+    
+    public void removePeerListListener(FcpPeerListListener l){
+        _repository.getPeerListEventSupport().removeListener(l);
+    }
+    
+    public void addQueueListener(FcpQueueListener l){
+        _repository.getQueueEventSupport().addListener(l);
+    }
+    
+    public void removeQueueListener(FcpQueueListener l){
+        _repository.getQueueEventSupport().removeListener(l);
+    }
+    
+    public void addKeypairListener(FcpSSKKeypairListener l){
+        _repository.getSSKKeypairEventSupport().addListener(l);
+    }
+    
+    public void removeKeypairListener(FcpSSKKeypairListener l){
+        _repository.getSSKKeypairEventSupport().removeListener(l);
+    }
+
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpEventSupportRepository.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/support/FcpEventSupportRepository.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpEventSupportRepository.java
                             (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpEventSupportRepository.java
     2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,34 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event.support;
+
+/**
+ * Holds references to all the client's event sources.
+ * @author Ralph Smithen
+ */
+public class FcpEventSupportRepository {
+    
+   private FcpConnectionEventSupport _connectionEventSupport = new 
FcpConnectionEventSupport();
+   private FcpPeerListEventSupport _peerListEventSupport = new 
FcpPeerListEventSupport();
+   private FcpQueueEventSupport _queueEventSupport = new 
FcpQueueEventSupport();
+   private FcpSSKKeypairEventSupport _keypairEventSupport = new 
FcpSSKKeypairEventSupport();
+
+    public FcpConnectionEventSupport getConnectionEventSupport() {
+        return _connectionEventSupport;
+    }
+
+    public FcpPeerListEventSupport getPeerListEventSupport() {
+        return _peerListEventSupport;
+    }
+
+    public FcpQueueEventSupport getQueueEventSupport() {
+        return _queueEventSupport;
+    }
+
+    public FcpSSKKeypairEventSupport getSSKKeypairEventSupport() {
+        return _keypairEventSupport;
+    }
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpPeerListEventSupport.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/support/FcpPeerListEventSupport.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpPeerListEventSupport.java
                               (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpPeerListEventSupport.java
       2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,66 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event.support;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+import org.freenetproject.contrib.fcp.NodeInfo;
+import org.freenetproject.contrib.fcp.event.FcpPeerListUpdatedEvent;
+import org.freenetproject.contrib.fcp.event.FcpPeerNotesUpdatedEvent;
+import 
org.freenetproject.contrib.fcp.event.support.AbstractFcpEventSupport.NotifyHelper;
+import org.freenetproject.contrib.fcp.listener.FcpPeerListListener;
+import org.freenetproject.contrib.fcp.message.client.ListPeerNotes;
+import org.freenetproject.contrib.fcp.message.node.EndListPeerNotes;
+import org.freenetproject.contrib.fcp.message.node.Peer;
+import org.freenetproject.contrib.fcp.message.node.PeerNote;
+
+/**
+ *
+ * @author Ralph Smithen
+ */
+public class FcpPeerListEventSupport extends 
AbstractFcpEventSupport<FcpPeerListListener>{
+    private Map<String, Peer> _peers;
+    private Map<String, Vector<PeerNote>> _peerNotes = 
Collections.synchronizedMap(new HashMap());
+    
+    NotifyHelper _peerListUpdatedNotifier = new 
NotifyHelper<FcpPeerListUpdatedEvent>() {
+        void notifyListener(FcpPeerListListener l, FcpPeerListUpdatedEvent e) 
{l.peerListUpdated(e);}
+    };
+    
+    NotifyHelper _peerNotesUpdatedNotifier = new 
NotifyHelper<FcpPeerNotesUpdatedEvent>() {
+        void notifyListener(FcpPeerListListener l, FcpPeerNotesUpdatedEvent e) 
{l.peerNotesUpdated(e);}
+    };
+
+    
+    public void firePeerListRequested(){
+        _peers = new HashMap();
+    }
+    
+    public void firePeerUpdated(Peer peer){
+        _peers.put(peer.getId(), peer);
+    }
+    
+    public void firePeerListUpdated(){
+        _peerListUpdatedNotifier.notifyListeners(new 
FcpPeerListUpdatedEvent(_peers));
+    }
+    
+    public void firePeerNote(PeerNote pn){
+        synchronized(_peerNotes){
+            _peerNotes.get(pn.getNodeId()).add(pn);
+        }
+    }
+    
+    public void firePeerNotesRequested(ListPeerNotes lpn){
+        _peerNotes.put(lpn.getNodeId(), new Vector());
+    }
+    
+    public void firePeerNotesUpdated(EndListPeerNotes elpn){
+         _peerNotesUpdatedNotifier.notifyListeners(
+                 new FcpPeerNotesUpdatedEvent(elpn, 
_peerNotes.get(elpn.getNodeId())));
+    }
+    
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpQueueEventSupport.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/support/FcpQueueEventSupport.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpQueueEventSupport.java
                          (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpQueueEventSupport.java
  2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,77 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event.support;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Logger;
+import org.freenetproject.contrib.fcp.event.AllDataEvent;
+import org.freenetproject.contrib.fcp.event.DataFoundEvent;
+import org.freenetproject.contrib.fcp.event.FcpKeyRequestedEvent;
+import org.freenetproject.contrib.fcp.event.FcpSimpleProgressEvent;
+import org.freenetproject.contrib.fcp.event.GetFailedEvent;
+import 
org.freenetproject.contrib.fcp.event.support.AbstractFcpEventSupport.NotifyHelper;
+import org.freenetproject.contrib.fcp.listener.FcpQueueListener;
+import org.freenetproject.contrib.fcp.message.client.ClientGet;
+import org.freenetproject.contrib.fcp.message.node.AllData;
+import org.freenetproject.contrib.fcp.message.node.DataFound;
+import org.freenetproject.contrib.fcp.message.node.GetFailed;
+import org.freenetproject.contrib.fcp.message.node.SimpleProgress;
+
+/**
+ *
+ * @author res
+ */
+public class FcpQueueEventSupport extends 
AbstractFcpEventSupport<FcpQueueListener>{
+    private static Logger logger = 
Logger.getLogger(FcpQueueEventSupport.class.getName());
+    
+    private Map<String, ClientGet> _items = Collections.synchronizedMap(new 
HashMap());
+    
+    
+    NotifyHelper _keyRequestedNotifier = new 
NotifyHelper<FcpKeyRequestedEvent>() {
+        void notifyListener(FcpQueueListener l, FcpKeyRequestedEvent e) 
{l.keyRequested(e);}
+    };   
+    
+    NotifyHelper _simpleProgressNotifier = new 
NotifyHelper<FcpSimpleProgressEvent>() {
+        void notifyListener(FcpQueueListener l, FcpSimpleProgressEvent e) 
{l.simpleProgressUpdate(e);}
+    }; 
+    
+    NotifyHelper _dataFoundNotifier = new NotifyHelper<DataFoundEvent>() {
+        void notifyListener(FcpQueueListener l, DataFoundEvent e) 
{l.dataFound(e);}
+    };
+    
+    NotifyHelper _allDataNotifier = new NotifyHelper<AllDataEvent>() {
+        void notifyListener(FcpQueueListener l, AllDataEvent e) {l.allData(e);}
+    };
+    
+    NotifyHelper _getFailedNotifier = new NotifyHelper<GetFailedEvent>() {
+        void notifyListener(FcpQueueListener l, GetFailedEvent e) 
{l.getFailed(e);}
+    };
+    
+    
+    public void fireKeyRequested(ClientGet cg){
+        if(_items.get(cg.getId()) != null)
+            logger.info("duplicate request id: " + cg.getId());
+        _items.put(cg.getId(), cg);
+        _keyRequestedNotifier.notifyListeners(new FcpKeyRequestedEvent(cg));
+    }
+    
+    public void fireSimpleProgressUpdate(SimpleProgress sp){
+        _simpleProgressNotifier.notifyListeners(new 
FcpSimpleProgressEvent(sp));
+    }
+    
+    public void fireDataFound(DataFound df){
+        _dataFoundNotifier.notifyListeners(new DataFoundEvent(df));
+    }
+    
+    public void fireAllData(AllData ad){
+        _allDataNotifier.notifyListeners(new AllDataEvent(ad));
+    }
+    
+    public void fireGetFailed(GetFailed gf){
+        _getFailedNotifier.notifyListeners(new GetFailedEvent(gf));
+    }
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpSSKKeypairEventSupport.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/support/FcpSSKKeypairEventSupport.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpSSKKeypairEventSupport.java
                             (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/FcpSSKKeypairEventSupport.java
     2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,40 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.event.support;
+
+import java.util.logging.Logger;
+import org.freenetproject.contrib.fcp.event.SSKKeypairEvent;
+import org.freenetproject.contrib.fcp.event.URIGeneratedEvent;
+import 
org.freenetproject.contrib.fcp.event.support.AbstractFcpEventSupport.NotifyHelper;
+import org.freenetproject.contrib.fcp.listener.FcpSSKKeypairListener;
+import org.freenetproject.contrib.fcp.message.node.SSKKeypair;
+import org.freenetproject.contrib.fcp.message.node.URIGenerated;
+
+/**
+ *
+ * @author Ralph Smithen
+ */
+public class FcpSSKKeypairEventSupport extends 
AbstractFcpEventSupport<FcpSSKKeypairListener>{
+    private static Logger logger = 
Logger.getLogger(FcpSSKKeypairEventSupport.class.getName());
+    
+    NotifyHelper _keypairReceivedNotifier = new 
NotifyHelper<SSKKeypairEvent>() {
+        void notifyListener(FcpSSKKeypairListener l, SSKKeypairEvent e) 
{l.keypairReceived(e);}
+    };  
+    
+    NotifyHelper _uriGeneratedNotifier = new NotifyHelper<URIGeneratedEvent>() 
{
+        void notifyListener(FcpSSKKeypairListener l, URIGeneratedEvent e) 
{l.uriGenerated(e);}
+    };  
+    
+    
+    
+    public void fireKeypairReceived(SSKKeypair kp){
+        _keypairReceivedNotifier.notifyListeners(new SSKKeypairEvent(kp));
+    }
+    
+    public void fireURIGenerated(URIGenerated ug){
+        _uriGeneratedNotifier.notifyListeners(new URIGeneratedEvent(ug));
+    }
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/package.html 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/event/support/package.html)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/package.html   
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/event/support/package.html   
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+  <head>
+  </head>
+  <body>
+      <h1>Event support</h1>
+      <p>
+          Provide support for events.
+      </p>
+  </body>
+</html>

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/FcpConnectionListener.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/listener/FcpConnectionListener.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/FcpConnectionListener.java
                              (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/FcpConnectionListener.java
      2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,17 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.listener;
+
+import org.freenetproject.contrib.fcp.event.FcpConnectEvent;
+import org.freenetproject.contrib.fcp.event.FcpDisconnectEvent;
+
+/**
+ *
+ * @author res
+ */
+public interface FcpConnectionListener {
+    public void nodeConnected(FcpConnectEvent e);
+    public void nodeDisconnected(FcpDisconnectEvent e);
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/FcpPeerListListener.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/listener/FcpPeerListListener.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/FcpPeerListListener.java
                                (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/FcpPeerListListener.java
        2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,19 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.listener;
+
+import org.freenetproject.contrib.fcp.event.FcpPeerListUpdatedEvent;
+import org.freenetproject.contrib.fcp.event.FcpPeerNotesUpdatedEvent;
+
+/**
+ *
+ * @author Ralph Smithen
+ */
+public interface FcpPeerListListener {
+
+    public void peerListUpdated(FcpPeerListUpdatedEvent e);
+    
+    public void peerNotesUpdated(FcpPeerNotesUpdatedEvent e);
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/FcpQueueListener.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/listener/FcpQueueListener.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/FcpQueueListener.java
                           (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/FcpQueueListener.java
   2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,23 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.listener;
+
+import org.freenetproject.contrib.fcp.event.AllDataEvent;
+import org.freenetproject.contrib.fcp.event.DataFoundEvent;
+import org.freenetproject.contrib.fcp.event.FcpKeyRequestedEvent;
+import org.freenetproject.contrib.fcp.event.FcpSimpleProgressEvent;
+import org.freenetproject.contrib.fcp.event.GetFailedEvent;
+
+/**
+ *
+ * @author res
+ */
+public interface FcpQueueListener {
+    public void simpleProgressUpdate(FcpSimpleProgressEvent e);
+    public void keyRequested(FcpKeyRequestedEvent e);
+    public void dataFound(DataFoundEvent e);
+    public void allData(AllDataEvent e);
+    public void getFailed(GetFailedEvent e);
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/FcpSSKKeypairListener.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/listener/FcpSSKKeypairListener.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/FcpSSKKeypairListener.java
                              (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/FcpSSKKeypairListener.java
      2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,17 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.listener;
+
+import org.freenetproject.contrib.fcp.event.SSKKeypairEvent;
+import org.freenetproject.contrib.fcp.event.URIGeneratedEvent;
+
+/**
+ *
+ * @author res
+ */
+public interface FcpSSKKeypairListener {
+    public void keypairReceived(SSKKeypairEvent kpe);
+    public void uriGenerated(URIGeneratedEvent uge);
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/package.html (from 
rev 15426, trunk/apps/jfcp/src/org/freenet/contrib/fcp/listener/package.html)
===================================================================
--- trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/package.html    
                        (rev 0)
+++ trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/listener/package.html    
2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+  <head>
+  </head>
+  <body>
+      <h1>FCP event listener interfaces</h1>
+      <p>
+          Interfaces by which interested applications can register to listen 
for
+          FCP events.
+      </p>
+  </body>
+</html>

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/FcpMessageInputStream.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/FcpMessageInputStream.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/FcpMessageInputStream.java
                               (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/FcpMessageInputStream.java
       2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,133 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import org.freenetproject.contrib.fcp.message.node.NodeMessage;
+
+/**
+ * Reads FCP node messages from a given stream.
+ * @author Ralph Smithen
+ */
+public class FcpMessageInputStream {
+    private static final    String          MESSAGE_PACKAGE = 
NodeMessage.class.getPackage().getName();
+    private                 DataInputStream _dis;
+    private                 String          _encoding = "UTF-8";
+    
+    /**
+     * Creates a new instance of FcpMessageStream, wraps a buffer around the 
<code>InputStream</code>.
+     * @param in the stream from which to read FCP data
+     */
+    public FcpMessageInputStream(InputStream in) {
+        _dis = new DataInputStream(new BufferedInputStream(in));
+    }
+    
+    String readLine() throws IOException{
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        byte b;
+        
+        while(true){
+            b = _dis.readByte();
+            
+            if(b == '\n'){ //REDFLAG:  is this safe with other encodings? - 
why is encoding not in FCP specifications?
+                if(bos.size() == 0){ // blank line
+                    continue;
+                }else{ // end of line
+                    break;
+                }
+            }
+            bos.write(b);
+        }
+        
+        String line = bos.toString(_encoding).trim(); 
+        return line.length() == 0 ? readLine() : line; // blank lines allowed 
for debugging - if so, read on
+    }
+    
+    /**
+     * Reads and returns the next message.
+     * @return the next message
+     * @throws java.io.IOException if thrown on underlying stream
+     * @throws org.freenet.contrib.fcp.message.MessageBuilderException if the 
data seems garbled
+     */
+    public NodeMessage readMessage() throws IOException, 
MessageBuilderException{
+        NodeMessage m;
+        String line = readLine();
+        
+        try {
+            m = (NodeMessage) Class.forName(MESSAGE_PACKAGE + "." + 
line).newInstance();
+        } catch (Exception ex) {
+            throw new MessageBuilderException("unknown message header (" + 
line + ")");
+        }
+        while(readField(m))
+            ; // read all message fields, append data if present
+        
+        m.validate();
+        
+        return m;
+    }
+    
+    boolean readField(NodeMessage m) throws IOException, 
MessageBuilderException{
+        String line = readLine();
+        
+        int pos = line.indexOf('=');
+        
+        if(pos > 0){ //set field value
+            m.getFields().put(line.substring(0, pos), line.substring(pos + 1));
+            return true;
+        }
+        
+        if(line.equals("EndMessage"))
+            return false;
+        
+        if(!line.equals("Data")){
+            throw new MessageBuilderException(
+                    "unknown tag (" + line + ") in message " + 
m.getHeaderString());
+        }
+        
+        byte[] data = new byte[m.getDataLength()];
+        int toRead = data.length, read;
+        while(toRead > 0){
+            read = _dis.read(data, data.length - toRead, toRead > 4096 ? 4096 
: toRead);
+            toRead -= read;
+        }
+        m.setData(data);
+        return false;
+    }
+    
+    /**
+     * Closes the delegate stream.
+     * @throws java.io.IOException if thrown on underlying stream
+     */
+    public void close() throws IOException {
+        _dis.close();
+    }
+
+    /**
+     * Gets the encoding, default=UTF-8
+     * @return the encoding
+     */
+    public String getEncoding() {
+        return _encoding;
+    }
+
+    /**
+     * Sets the encoding
+     * @param encoding new encoding
+     */
+    public void setEncoding(String encoding) {
+        _encoding = encoding;
+    }
+    
+}
+
+
+
+

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/FcpMessageOutputStream.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/FcpMessageOutputStream.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/FcpMessageOutputStream.java
                              (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/FcpMessageOutputStream.java
      2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,84 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedWriter;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.Map;
+import org.freenetproject.contrib.fcp.message.client.ClientMessage;
+
+/**
+ * Writes FCP messages to provided stream.
+ * @author Ralph Smithen
+ */
+public class FcpMessageOutputStream {
+    private DataOutputStream _dos;
+    private Writer _out;
+    /**
+     * Creates a new instance of FcpMessageOutputStream
+     * @param out the stream to write messages to
+     */
+    public FcpMessageOutputStream(OutputStream out) {
+        _dos = new DataOutputStream(new BufferedOutputStream(out));
+        _out = new BufferedWriter(new OutputStreamWriter(_dos));
+    }
+    
+    /**
+     * Writes a message to the output stream.
+     * @param m the message to be written
+     * @throws org.freenet.contrib.fcp.message.MessageBuilderException if data 
seems incomplete or otherwise garbled
+     * @throws java.io.IOException if thrown by underlying stream
+     */
+    public void writeMessage(ClientMessage m) throws MessageBuilderException, 
IOException{
+        m.validate();
+        
+        writeLine(m.getHeaderString());
+        
+        for(Map.Entry<String, String> field : m.getFields().entrySet()){
+            writeField(field.getKey(), field.getValue());
+        }
+        if(m.isData()){
+            writeLine("Data");
+            _out.flush();
+            _dos.write(m.getData());
+        }else{
+            writeLine("EndMessage");
+        }
+        
+    }
+    
+    void writeField(String name, String value) throws IOException{
+        _out.write(name);
+        _out.write('=');
+        _out.write(value);
+        _out.write('\n');
+    }
+    
+    void writeLine(String line) throws IOException{
+        _out.write(line);
+        _out.write('\n');
+    }
+    
+    /**
+     * Flushes data to stream.
+     * @throws java.io.IOException if thrown on delegate stream
+     */
+    public void flush() throws IOException{
+        _out.flush();
+    }
+    
+    /**
+     * Closes the connection.
+     * @throws java.io.IOException if thrown on delegate stream
+     */
+    public void close() throws IOException{
+        _out.close();
+    }
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/MessageBuilderException.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/MessageBuilderException.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/MessageBuilderException.java
                             (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/MessageBuilderException.java
     2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,18 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message;
+
+/**
+ * Thrown when reading or writing {@link org.freenet.contrib.fcp.FcpMessage 
FcpMessage}s.
+ * @author Ralph Smithen
+ */
+public class MessageBuilderException extends Exception{
+    
+    /** Creates a new instance of MessageBuilderException */
+    public MessageBuilderException(String message) {
+        super(message);
+    }
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/Persistence.java 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/Persistence.java)
===================================================================
--- trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/Persistence.java 
                        (rev 0)
+++ trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/Persistence.java 
2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,15 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message;
+
+/**
+ *
+ * @author Ralph Smithen
+ */
+public enum Persistence{
+    connection,
+    reboot,
+    forever
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/ReturnType.java 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/ReturnType.java)
===================================================================
--- trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/ReturnType.java  
                        (rev 0)
+++ trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/ReturnType.java  
2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,15 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message;
+
+/**
+ *
+ * @author Ralph Smithen
+ */
+public enum ReturnType{
+    direct,
+    disk,
+    none
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/UploadFrom.java 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/UploadFrom.java)
===================================================================
--- trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/UploadFrom.java  
                        (rev 0)
+++ trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/UploadFrom.java  
2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,15 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message;
+
+/**
+ *
+ * @author Ralph Smithen
+ */
+public enum UploadFrom{
+    direct,
+    disk,
+    redirect
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientGet.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/client/ClientGet.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientGet.java
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientGet.java
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,161 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.client;
+
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+import org.freenetproject.contrib.fcp.message.Persistence;
+import org.freenetproject.contrib.fcp.message.ReturnType;
+
+/**
+ *This is sent from a client program to the Freenet node and is used to 
specify a file to download from Freenet.
+ *
+ * @author Ralph Smithen
+ */
+public class ClientGet extends ClientMessage{
+    
+    public ClientGet(String uri, String identifier){
+        setUri(uri);
+        setId(identifier);
+    }
+    
+    public String[] getMandatoryFields() {
+        return new String[] { "URI", "Identifier" };
+    }
+
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+        eventSupport.getQueueEventSupport().fireKeyRequested(this);
+    }
+    
+    
+    public boolean isIgnoreDs() {
+        return Boolean.parseBoolean(_fields.get("IgnoreDS"));
+    }
+    
+    public void setIgnoreDs(boolean ignoreDs) {
+        _fields.put("IgnoreDS", String.valueOf(ignoreDs));
+    }
+    
+    public boolean isDsOnly() {
+        return Boolean.parseBoolean(_fields.get("DSonly"));
+    }
+    
+    public void setDsOnly(boolean dsOnly) {
+        _fields.put("DSonly", String.valueOf(dsOnly));
+    }
+    
+    public String getUri() {
+        return _fields.get("URI");
+    }
+    
+    public void setUri(String uri) {
+        _fields.put("URI", uri);
+    }
+    
+    public String getId() {
+        return _fields.get("Identifier");
+    }
+    
+    public void setId(String id) {
+        _fields.put("Identifier", id);
+    }
+    
+    public int getVerbosity() {
+        return Integer.parseInt(_fields.get("Verbosity"));
+    }
+    
+    public void setVerbosity(int verbosity) {
+        _fields.put("Verbosity", String.valueOf(verbosity));
+    }
+    
+    public int getMaxSize() {
+        return Integer.parseInt(_fields.get("MaxSize"));
+    }
+    
+    public void setMaxSize(int maxSize) {
+        _fields.put("MaxSize", String.valueOf(maxSize));
+    }
+    
+    public int getMaxTempSize() {
+        return Integer.parseInt(_fields.get("MaxTempSize"));
+    }
+    
+    public void setMaxTempSize(int maxTempSize) {
+        _fields.put("MaxTempSize", String.valueOf(maxTempSize));
+    }
+    
+    public int getMaxRetries() {
+        return Integer.parseInt(_fields.get("MaxRetries"));
+    }
+    
+    public void setMaxRetries(int maxRetries) {
+        _fields.put("MaxRetries", String.valueOf(maxRetries));
+    }
+    
+    public int getPriority() {
+        return Integer.parseInt(_fields.get("PriorityClass"));
+    }
+    
+    public void setPriority(int priority) {
+        _fields.put("PriorityClass", String.valueOf(priority));
+    }
+    
+    public Persistence getPersistence() {
+        return Persistence.valueOf(_fields.get("Persistence"));
+    }
+    
+    public void setPersistence(Persistence persistence) {
+        _fields.put("Persistence", persistence.toString());
+    }
+    
+    public String getClientToken() {
+        return _fields.get("ClientToken");
+    }
+    
+    public void setClientToken(String clientToken) {
+        _fields.put("ClientToken", clientToken);
+    }
+    
+    public boolean isGlobal() {
+        return Boolean.parseBoolean(_fields.get("Global"));
+    }
+    
+    public void setGlobal(boolean global) {
+        _fields.put("Global", String.valueOf(global));
+    }
+    
+    public boolean isBlob() {
+        return Boolean.parseBoolean(_fields.get("BinaryBlob"));
+    }
+    
+    public void setBlob(boolean blob) {
+        _fields.put("BinaryBlob", String.valueOf(blob));
+    }
+    
+    public ReturnType getReturnType() {
+        return ReturnType.valueOf(_fields.get("ReturnType"));
+    }
+    
+    public void setReturnType(ReturnType returnType) {
+        _fields.put("ReturnType", returnType.toString());
+    }
+    
+    // Only valid if ReturnType is disk
+    
+    public String getFileName() {
+        return _fields.get("FileName");
+    }
+    
+    public void setFileName(String fileName) {
+        _fields.put("FileName", fileName);
+    }
+    
+    public String getTempFileName() {
+        return _fields.get("TempFilename");
+    }
+    
+    public void setTempFileName(String tempFileName) {
+        _fields.put("TempFilename", tempFileName);
+    }
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientHello.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/client/ClientHello.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientHello.java
                          (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientHello.java
  2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,46 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.client;
+
+import java.io.PrintStream;
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+
+/**
+ *This must be the first message from the client on any given connection. 
+ * The node will respond with a {@link 
org.freenet.contrib.fcp.message.node.NodeHello NodeHello} message.
+ *
+ * @author Ralph Smithen
+ */
+public class ClientHello extends ClientMessage{
+    
+    public ClientHello(String expectedVersion, String clientName){
+        setExpectedVersion(expectedVersion);
+        setName(clientName);
+    }
+
+    public String[] getMandatoryFields() {
+        return new String[] { "Name", "ExpectedVersion" };
+    }
+
+    public String getName() {
+        return _fields.get("Name");
+    }
+
+    public void setName(String name) {
+        _fields.put("Name", name);
+    }
+
+    public String getExpectedVersion() {
+        return _fields.get("ExpectedVersion");
+    }
+
+    public void setExpectedVersion(String expectedVersion) {
+        _fields.put("ExpectedVersion", expectedVersion);
+    }
+
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+    }
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientMessage.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/client/ClientMessage.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientMessage.java
                                (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientMessage.java
        2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,16 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.client;
+
+import org.freenetproject.contrib.fcp.FcpMessage;
+
+/**
+ *All client messages inherit from this.
+ *
+ * @author Ralph Smithen
+ */
+public abstract class ClientMessage extends FcpMessage{
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientPut.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/client/ClientPut.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientPut.java
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientPut.java
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,250 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.client;
+
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+import org.freenetproject.contrib.fcp.message.Persistence;
+import org.freenetproject.contrib.fcp.message.UploadFrom;
+
+/**
+ * <p>This is used to specify an insert into Freenet of a single file. 
+ * The insert may be provided by referring to a file on disk, including the 
data directly, 
+ * or redirecting to another key.</p>
+ * <p>A filename may be specified using the TargetFilename option. This is 
mostly useful 
+ * with CHKs. The effect is to create a single file manifest which contains 
only the filename 
+ * given, and points to the data just inserted. Thus the provided filename 
becomes the last 
+ * part of the URI, and must be provided when fetching the data.</p>
+ *
+ * @author Ralph Smithen
+ */
+public class ClientPut extends ClientMessage{
+    private static String[] _mandatoryFields;
+       
+    
+    /**
+     * Creates a ClientPut for direct data sending.
+     * @param uri 
+     * @param id 
+     * @param data 
+     */
+    public ClientPut(String uri, String id, byte[] data){
+        setUri(uri);
+        setId(id);
+        setData(data);
+        setUploadFrom(UploadFrom.direct);
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    public String[] getMandatoryFields() {
+        return _mandatoryFields;
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+    }
+
+    
+    public String getUri() {
+        return _fields.get("URI");
+    }
+    
+    /**
+     * The type of key to insert. When inserting an SSK key, you explicitly 
specifiy the version 
+     * number. For a USK key, use a zero and it should automatically use the 
correct version number.
+     * @param uri 
+     */
+    public void setUri(String uri) {
+        _fields.put("URI", uri);
+    }
+    
+    public String getId() {
+        return _fields.get("Identifier");
+    }
+    
+    /**
+     * This is just for client to be able to identify files that have been 
inserted.
+     * @param id 
+     */
+    public void setId(String id) {
+        _fields.put("Identifier", id);
+    }
+    
+    public String getContentType() {
+        return _fields.get("Metadata.ContentType");
+    }
+    
+    /**
+     * The MIME type of the data being inserted. For text, if charset is not 
specified, node should 
+     * auto-detect it and force the auto-detected version
+     * @param contentType 
+     */
+    public void setContentType(String contentType) {
+        _fields.put("Metadata.ContentType", contentType);
+    }
+    
+    public int getVerbosity() {
+        return Integer.parseInt(_fields.get("Verbosity"));
+    }
+    
+    /**
+     * <pre>
+     *   0: report when complete, 
+     *   1: SimpleProgress messages,
+     * 512: send StartedCompression and FinishedCompression messages
+     * </pre>
+     * @param verbosity 
+     */
+    public void setVerbosity(int verbosity) {
+        _fields.put("Verbosity", String.valueOf(verbosity));
+    }
+    
+    public int getMaxRetries() {
+        return Integer.parseInt(_fields.get("MaxRetries"));
+    }
+    
+    /**
+     * Number of times to retry if the first time doesn't work. -1 means retry 
forever.
+     * @param maxRetries 
+     */
+    public void setMaxRetries(int maxRetries) {
+        _fields.put("MaxRetries", String.valueOf(maxRetries));
+    }
+    
+    public int getPriority() {
+        return Integer.parseInt(_fields.get("PriorityClass"));
+    }
+    
+    public void setPriority(int priority) {
+        _fields.put("PriorityClass", String.valueOf(priority));
+    }
+    
+    public boolean isCHKOnly() {
+        return Boolean.parseBoolean(_fields.get("GetCHKOnly"));
+    }
+    
+    /**
+     * <p>
+     *    If set to true, it won't actually insert the data, 
+     *    just return the key it would generate.
+     * </p>
+     * 
+     * <p>
+     *    If the key is USK, you may want to transform it into a SSK, to 
prevent the node 
+     *    spending time searching for an unused index.
+     * </p>
+     * @param chk 
+     */
+    public void setCHKOnly(boolean chk) {
+        _fields.put("GetCHKOnly", String.valueOf(chk));
+    }
+    
+    public Persistence getPersistence() {
+        return Persistence.valueOf(_fields.get("Persistence"));
+    }
+    
+    public void setPersistence(Persistence persistence) {
+        _fields.put("Persistence", persistence.toString());
+    }
+    
+    public String getClientToken() {
+        return _fields.get("ClientToken");
+    }
+    
+    /**
+     * Sent back to client on the PersistentPut if this is a persistent request
+     * @param clientToken 
+     */
+    public void setClientToken(String clientToken) {
+        _fields.put("ClientToken", clientToken);
+    }
+    
+    public boolean isGlobal() {
+        return Boolean.parseBoolean(_fields.get("Global"));
+    }
+    
+    /**
+     * Whether the insert is visible on the global queue or not.
+     * @param global 
+     */
+    public void setGlobal(boolean global) {
+        _fields.put("Global", String.valueOf(global));
+    }
+    
+    public boolean isDontCompress() {
+        return Boolean.parseBoolean(_fields.get("DontCompress"));
+    }
+    
+    /**
+     * Hint to node: don't try to compress the data, it's already compressed
+     * @param dontCompress 
+     */
+    public void setDontCompress(boolean dontCompress) {
+        _fields.put("DontCompress", String.valueOf(dontCompress));
+    }
+    
+    public boolean isBlob() {
+        return Boolean.parseBoolean(_fields.get("BinaryBlob"));
+    }
+    
+    public void setBlob(boolean blob) {
+        _fields.put("BinaryBlob", String.valueOf(blob));
+    }
+    
+    public boolean isEarlyEncode() {
+        return Boolean.parseBoolean(_fields.get("EarlyEncode"));
+    }
+    
+    public void setEarlyEncode(boolean earlyEncode) {
+        _fields.put("EarlyEncode", String.valueOf(earlyEncode));
+    }
+    
+    public UploadFrom getUploadFrom() {
+        return UploadFrom.valueOf(_fields.get("UploadFrom"));
+    }
+    
+    public void setUploadFrom(UploadFrom uploadFrom) {
+        _fields.put("UploadFrom", uploadFrom.toString());
+        switch(uploadFrom){
+            case direct:
+                _mandatoryFields = new String[] {"URI", "Identifier", 
"DataLength"};
+                break;
+                
+            case disk: 
+                _mandatoryFields = new String[] {"URI", "Identifier", 
"Filename"};
+                break;
+                
+            case redirect:
+                _mandatoryFields = new String[] {"URI", "Identifier", 
"TargetURI"};
+        }
+    }
+
+    public String getFileName() {
+        return _fields.get("FileName");
+    }
+    
+    public void setFileName(String fileName) {
+        _fields.put("FileName", fileName);
+    }
+    
+    public String getTargetFilename() {
+        return _fields.get("TargetFilename");
+    }
+    
+    public void setTargetFilename(String targetFilename) {
+        _fields.put("TargetFilename", targetFilename);
+    }
+    
+    public String getTargetURI() {
+        return _fields.get("TargetURI");
+    }
+    
+    public void setTargetURI(String targetURI) {
+        _fields.put("TargetURI", targetURI);
+    }
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientPutDiskDir.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/client/ClientPutDiskDir.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientPutDiskDir.java
                             (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ClientPutDiskDir.java
     2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,217 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.client;
+
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+import org.freenetproject.contrib.fcp.message.Persistence;
+import org.freenetproject.contrib.fcp.message.UploadFrom;
+
+/**
+ * <p>This inserts an entire on-disk directory (including subdirectories) 
under a single key (technically, 
+ * as a manifest file).  Each of the inserted files is located using the same 
key like this:</p>
+ *<pre>
+ *CHK at NOSdw7FF88S....4BgOPxSPqv~bNg7YsgM,AAEC--8/file1.txt
+ *CHK at NOSdw7FF88S....4BgOPxSPqv~bNg7YsgM,AAEC--8/file2.jpg
+ *CHK at NOSdw7FF88S....4BgOPxSPqv~bNg7YsgM,AAEC--8/subdir/file3.html
+ *CHK at NOSdw7FF88S....4BgOPxSPqv~bNg7YsgM,AAEC--8/subdir/file4.ogg
+ *CHK at NOSdw7FF88S....4BgOPxSPqv~bNg7YsgM,AAEC--8/foo/bar/file5.pdf
+ *</pre>
+ *
+ *
+ *<p>Most of the fields have the same usage as in {@link ClientPut 
ClientPut}.</p>
+ *
+ * @author Ralph Smithen
+ */
+public class ClientPutDiskDir extends ClientMessage{
+    private byte[] _data;
+    private static String[] _mandatoryFields;
+       
+    
+    /**
+     * Creates a ClientPut for direct data sending.
+     * @param uri 
+     * @param id 
+     * @param data 
+     */
+    public ClientPutDiskDir(String uri, String id, byte[] data){
+        setUri(uri);
+        setId(id);
+    }
+    
+    /**
+     * 
+     * @inheritDoc 
+     */
+    public String[] getMandatoryFields() {
+        return _mandatoryFields;
+    }
+
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+    }
+
+    
+    public String getUri() {
+        return _fields.get("URI");
+    }
+    
+    /**
+     * The type of key to insert. When inserting an SSK key, you explicitly 
specifiy the version 
+     * number. For a USK key, use a zero and it should automatically use the 
correct version number.
+     * @param uri 
+     */
+    public void setUri(String uri) {
+        _fields.put("URI", uri);
+    }
+    
+    public String getId() {
+        return _fields.get("Identifier");
+    }
+    
+    /**
+     * This is just for client to be able to identify files that have been 
inserted.
+     * @param id 
+     */
+    public void setId(String id) {
+        _fields.put("Identifier", id);
+    }
+    
+    public String getContentType() {
+        return _fields.get("Metadata.ContentType");
+    }
+    
+    /**
+     * The MIME type of the data being inserted. For text, if charset is not 
specified, node should 
+     * auto-detect it and force the auto-detected version
+     * @param contentType 
+     */
+    public void setContentType(String contentType) {
+        _fields.put("Metadata.ContentType", contentType);
+    }
+    
+    public int getVerbosity() {
+        return Integer.parseInt(_fields.get("Verbosity"));
+    }
+    
+    /**
+     * <pre>
+     *  0: report when complete, 
+     *  1: SimpleProgress messages,
+     * 512: send StartedCompression and FinishedCompression messages
+     * </pre>
+     * @param verbosity 
+     */
+    public void setVerbosity(int verbosity) {
+        _fields.put("Verbosity", String.valueOf(verbosity));
+    }
+    
+    public int getMaxRetries() {
+        return Integer.parseInt(_fields.get("MaxRetries"));
+    }
+    
+    /**
+     * Number of times to retry if the first time doesn't work. -1 means retry 
forever.
+     * @param maxRetries 
+     */
+    public void setMaxRetries(int maxRetries) {
+        _fields.put("MaxRetries", String.valueOf(maxRetries));
+    }
+    
+    public int getPriority() {
+        return Integer.parseInt(_fields.get("PriorityClass"));
+    }
+    
+    public void setPriority(int priority) {
+        _fields.put("PriorityClass", String.valueOf(priority));
+    }
+    
+    public boolean isCHKOnly() {
+        return Boolean.parseBoolean(_fields.get("GetCHKOnly"));
+    }
+    
+    /**
+     * <p>
+     *    If set to true, it won't actually insert the data, 
+     *    just return the key it would generate.
+     * </p>
+     * 
+     * <p>
+     *    If the key is USK, you may want to transform it into a SSK, to 
prevent the node 
+     *    spending time searching for an unused index.
+     * </p>
+     * @param chk 
+     */
+    public void setCHKOnly(boolean chk) {
+        _fields.put("GetCHKOnly", String.valueOf(chk));
+    }
+    
+    public Persistence getPersistence() {
+        return Persistence.valueOf(_fields.get("Persistence"));
+    }
+    
+    public void setPersistence(Persistence persistence) {
+        _fields.put("Persistence", persistence.toString());
+    }
+    
+    public String getClientToken() {
+        return _fields.get("ClientToken");
+    }
+    
+    /**
+     * Sent back to client on the PersistentPut if this is a persistent request
+     * @param clientToken 
+     */
+    public void setClientToken(String clientToken) {
+        _fields.put("ClientToken", clientToken);
+    }
+    
+    public boolean isGlobal() {
+        return Boolean.parseBoolean(_fields.get("Global"));
+    }
+    
+    /**
+     * Whether the insert is visible on the global queue or not.
+     * @param global 
+     */
+    public void setGlobal(boolean global) {
+        _fields.put("Global", String.valueOf(global));
+    }
+    
+    public boolean isDontCompress() {
+        return Boolean.parseBoolean(_fields.get("DontCompress"));
+    }
+    
+    /**
+     * Hint to node: don't try to compress the data, it's already compressed
+     * @param dontCompress 
+     */
+    public void setDontCompress(boolean dontCompress) {
+        _fields.put("DontCompress", String.valueOf(dontCompress));
+    }
+
+    public String getFileName() {
+        return _fields.get("FileName");
+    }
+    
+    public void setFileName(String fileName) {
+        _fields.put("FileName", fileName);
+    }
+    
+    public String getDefaultName() {
+        return _fields.get("DefaultName");
+    }
+    
+    public void setDefaultName(String defaultName) {
+        _fields.put("DefaultName", defaultName);
+    }
+    
+
+    public void setAllowUnreadableFiles(boolean b) {
+        _fields.put("AllowUnreadableFiles", String.valueOf(b));
+    }
+    
+    public boolean isAllowUnreadableFiles() {
+        return Boolean.parseBoolean(_fields.get("AllowUnreadableFiles"));
+    }
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/GenerateSSK.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/client/GenerateSSK.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/GenerateSSK.java
                          (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/GenerateSSK.java
  2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,31 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.client;
+
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+
+/**
+ * This asks the node to generate us an SSK keypair. 
+ * The response will come back in a {@link 
org.freenet.contrib.fcp.message.node.SSKKeypair SSKKeypair} message.
+ *
+ * @author Ralph Smithen
+ */
+public class GenerateSSK extends ClientMessage{
+    
+    public GenerateSSK(String id){
+        setId(id);
+    }
+    
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+    }
+    
+    public String getId() {
+        return _fields.get("Identifier");
+    }
+    
+    public void setId(String id) {
+        _fields.put("Identifier", id);
+    }
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ListPeerNotes.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/client/ListPeerNotes.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ListPeerNotes.java
                                (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ListPeerNotes.java
        2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,33 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.client;
+
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+
+/**
+ *This message lists the peer notes for a given peer of your Freenet node.
+ *
+ * @author Ralph Smithen
+ */
+public class ListPeerNotes extends ClientMessage{
+    
+    /** Creates a new instance of ListPeers */
+    public ListPeerNotes(String nodeId) {
+        setNodeId(nodeId);
+    }
+    
+    public void setNodeId(String nodeId) {
+        _fields.put("NodeIdentifier", nodeId);
+    }
+
+    public String getNodeId() {
+        return _fields.get("NodeIdentifier");
+    }
+
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+        eventSupport.getPeerListEventSupport().firePeerNotesRequested(this);
+    }
+ 
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ListPeers.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/client/ListPeers.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ListPeers.java
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ListPeers.java
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,45 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.client;
+
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+
+/**
+ *This message asks the Freenet node for a list of other Freenet nodes 
connected directly to you (peers).
+ *
+ * @author Ralph Smithen
+ */
+public class ListPeers extends ClientMessage{
+    
+    /** Creates a new instance of ListPeers */
+    public ListPeers() {
+    }
+    
+    /** Creates a new instance of ListPeers */
+    public ListPeers(boolean withMetadata, boolean withVolatile) {
+        setWithMetadata(withMetadata);
+        setWithVolatile(withVolatile);
+    }
+
+    public boolean isWithMetadata() {
+        return Boolean.parseBoolean(_fields.get("WithMetadata"));
+    }
+
+    public void setWithMetadata(boolean withMetadata) {
+        _fields.put("WithMetadata", String.valueOf(withMetadata));
+    }
+
+    public boolean isWithVolatile() {
+        return Boolean.parseBoolean(_fields.get("WithVolatile"));
+    }
+
+    public void setWithVolatile(boolean withVolatile) {
+        _fields.put("WithVolatile", String.valueOf(withVolatile));
+    }     
+    
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+        eventSupport.getPeerListEventSupport().firePeerListRequested();
+    }   
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ModifyPeerNote.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/client/ModifyPeerNote.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ModifyPeerNote.java
                               (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ModifyPeerNote.java
       2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,49 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.client;
+
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+
+/**
+ *This message modifies a peer note for a given peer of your Freenet node.
+ *
+ * @author Ralph Smithen
+ */
+public class ModifyPeerNote extends ClientMessage{
+    
+    /** Creates a new instance of ModifyPeerNote */
+    public ModifyPeerNote(String nodeId) {
+        setNodeId(nodeId);
+    }
+
+
+    public void setNodeId(String nodeId) {
+        _fields.put("NodeIdentifier", nodeId);
+    }
+
+    public String getNodeId() {
+        return _fields.get("NodeIdentifier");
+    }
+    
+    public void setNoteType(int type){
+        _fields.put("PeerNoteType", String.valueOf(type));
+    }
+    
+    public int getNoteType(){
+        return Integer.parseInt(_fields.get("PeerNoteType"));
+    }
+    
+    public void setNoteText(String s) {
+        _fields.put("NoteText", s);
+    }
+
+    public String getNoteText() {
+        return _fields.get("NoteText");
+    }
+
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+    }
+ 
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ShutDown.java 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/client/ShutDown.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ShutDown.java 
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/ShutDown.java 
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,23 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.client;
+
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+
+/**
+ * This command allows an client program to remotely shut down a Freenet node. 
+ * A confirmation message will be sent (ProtocolError code 18: Shutting down)
+ * @author Ralph Smithen
+ */
+public class ShutDown extends ClientMessage{
+    
+    /** Creates a new instance of ShutDown */
+    public ShutDown() {
+    }
+
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+    }
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/package.html 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/client/package.html)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/package.html  
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/client/package.html  
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+  <head>
+  </head>
+  <body>
+      <h1>Client messages</h1>
+      <p>
+          Messages sent from the client to the node.
+      </p>
+  </body>
+</html>

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/AllData.java 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/node/AllData.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/AllData.java    
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/AllData.java    
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,62 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.node;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+
+/**
+ * For a {@link org.freenet.contrib.fcp.message.client.ClientGet ClientGet} 
with 
+ * {@link org.freenet.contrib.fcp.message.ReturnType 
ReturnType}=<code>direct</code>, 
+ * the data is returned directly to the client, 
+ * all at once, using the <code>AllData</code> message. Obviously in many 
situations this 
+ * will not be desirable, hence the other <code>ReturnType</code> options. 
+ * Persistent direct requests will not send this immediately on completion of 
the request; 
+ * see {@link GetRequestStatus GetRequestStatus}.
+ *
+ * @author Ralph Smithen
+ */
+public class AllData extends NodeMessage{
+    private String _uri;
+    private byte[] _data;
+    
+    /**
+     * Creates a new instance of AllData
+     */
+    public AllData() {
+    }
+    
+
+    /**
+     * @inheritDoc 
+     */
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+        eventSupport.getQueueEventSupport().fireAllData(this);
+    }
+    
+    public String getId() {
+        return _fields.get("Identifier");
+    }
+    
+    public void setId(String id) {
+        _fields.put("Identifier", id);
+    }
+
+    public String getUri() {
+        return _uri;
+    }
+
+    public void setUri(String uri) {
+        _uri = uri;
+    }
+    
+    public String toString(){
+        try {
+            return URLEncoder.encode(_uri, "utf-8");
+        } catch (UnsupportedEncodingException ignore) { }
+        return _uri;
+    }
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/DataFound.java 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/node/DataFound.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/DataFound.java  
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/DataFound.java  
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,53 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.node;
+
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+
+/**
+ *This indicates a successful fetch of the key, but does not actually include 
the data.
+ * @author Ralph Smithen
+ */
+public class DataFound extends NodeMessage{
+
+    /** Creates a new instance of DataFound */
+    public DataFound() {
+    }
+    
+    /**
+     * @inheritDoc 
+     */
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+        eventSupport.getQueueEventSupport().fireDataFound(this);
+    }
+
+    public String getId() {
+        return _fields.get("Identifier");
+    }
+
+    public void setId(String id) {
+        _fields.put("Identifier", id);
+    }
+
+    public String getContentType() {
+        return _fields.get("Metadata.ContentType");
+    }
+
+    public void setContentType(String contentType) {
+        _fields.put("Metadata.ContentType", contentType);
+    }
+
+    public int getDataLength() {
+        return Integer.parseInt(_fields.get("DataLength"));
+    }
+
+    public void setDataLength(int dataLength) {
+        _fields.put("ContentType", String.valueOf(dataLength));
+    }
+    
+    public boolean isGlobal() {
+        return Boolean.parseBoolean(_fields.get("Global"));
+    }
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/EndListPeerNotes.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/node/EndListPeerNotes.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/EndListPeerNotes.java
                               (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/EndListPeerNotes.java
       2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,31 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.node;
+
+import org.freenetproject.contrib.fcp.NodeInfo;
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+
+/**
+ *This indicates the end of a list of {@link PeerNote PeerNote} messages that 
have been sent
+ * in response to a {@link 
org.freenet.contrib.fcp.message.client.ListPeerNotes ListPeerNotes} message.
+ * @author Ralph Smithen
+ */
+public class EndListPeerNotes extends NodeMessage{
+    
+    public EndListPeerNotes(){
+    }
+    
+    public void fireEvents(FcpEventSupportRepository eventSupport) {
+        eventSupport.getPeerListEventSupport().firePeerNotesUpdated(this);
+    }
+    
+    public void setNodeId(String nodeId) {
+        _fields.put("NodeIdentifier", nodeId);
+    }
+    
+    public String getNodeId() {
+        return _fields.get("NodeIdentifier");
+    }
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/EndListPeers.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/node/EndListPeers.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/EndListPeers.java
                           (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/EndListPeers.java
   2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,23 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.node;
+
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+
+/**
+ *This indicates the end of a list of {@link Peer Peer} messages that have 
been sent in response to a 
+ * {@link org.freenet.contrib.fcp.message.client.ListPeers ListPeers} message.
+ * @author Ralph Smithen
+ */
+public class EndListPeers extends NodeMessage{
+
+    /**
+     * @inheritDoc 
+     */
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+        eventSupport.getPeerListEventSupport().firePeerListUpdated();
+    }
+
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/GetFailed.java 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/node/GetFailed.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/GetFailed.java  
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/GetFailed.java  
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,64 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.node;
+
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+
+/**
+ *
+ * <p>It indicates a freenet retrieval has failed.</p>
+ * <p>Complex <code>GetFailed</code>s are also possible; the format is 
identical to that of a 
+ * {@link PutFailed PutFailed}.</p>
+ * @author Ralph Smithen
+ */
+public class GetFailed extends NodeMessage{
+
+    /**
+     * @inheritDoc 
+     */
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+        eventSupport.getQueueEventSupport().fireGetFailed(this);
+    }
+
+    public String getId() {
+        return _fields.get("Identifier");
+    }
+
+    public void setId(String id) {
+        _fields.put("Identifier", id);
+    }
+    
+    public String getCode(){
+        return _fields.get("Code");
+    }
+    
+    public String getCodeDescription(){
+        return _fields.get("CodeDescription");
+    }
+    
+    public String getExtraDescription(){
+        return _fields.get("ExtraDescription");
+    }
+    
+    public boolean getFatal(){
+        return Boolean.parseBoolean(_fields.get("Fatal"));
+    }
+    
+    public long getExpectedDataLength(){
+        return Long.parseLong(_fields.get("ExpectedDataLength"));
+    }
+    
+    public String getExpectedContentType(){
+        return _fields.get("ExpectedMetadata.ContentType");
+    }
+    
+    public boolean getFinalizedExpected(){
+        return Boolean.parseBoolean(_fields.get("FinalizedExpected"));
+    }
+    
+    public String getRedirectURI(){
+        return _fields.get("RedirectURI");
+    }
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/IdentifierCollision.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/node/IdentifierCollision.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/IdentifierCollision.java
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/IdentifierCollision.java
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,30 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.node;
+
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+
+/**
+ * This happens when a client tries to reuse an Identifier. Identifiers are 
unique to the specific request. 
+ * They can be reused after that request has completed and removed from the 
queue.
+ * @author Ralph Smithen
+ */
+public class IdentifierCollision extends NodeMessage{
+
+    /**
+     * @inheritDoc 
+     */
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+        // @todo: notify who?
+    }
+
+    public String getId() {
+        return _fields.get("Identifier");
+    }
+
+    public void setId(String id) {
+        _fields.put("Identifier", id);
+    }
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/NodeHello.java 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/node/NodeHello.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/NodeHello.java  
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/NodeHello.java  
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,71 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.node;
+
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+
+/**
+ *Sent from the Freenet node in response to a 
+ * {@link org.freenet.contrib.fcp.message.client.ClientHello ClientHello} 
message. The node tells us 
+ * what version it is, what protocol version it's using, whether testnet mode 
is enabled, and how many 
+ * compression codecs are currently supported (this is important with the 
StartedCompression message).
+ *
+ * @author Ralph Smithen
+ */
+public class NodeHello extends NodeMessage{
+
+    /**
+     * 
+     * @inheritDoc 
+     */
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+        eventSupport.getConnectionEventSupport().fireFcpConnected(this);
+    }
+    
+    public int getCompressionCodecs(){
+        return Integer.parseInt(_fields.get("CompressionCodecs"));
+    }
+    
+    public boolean isTestNet(){
+        return Boolean.parseBoolean(_fields.get("TestNet"));
+    }
+    
+    public String getNodeLanguage(){
+        return _fields.get("NodeLanguage");
+    }
+    
+    public String getExtRevision(){
+        return _fields.get("ExtRevision");
+    }
+    
+    public String getNode(){
+        return _fields.get("Node");
+    }
+    
+    public String getBuild(){
+        return _fields.get("Build");
+    }
+    
+    public String getFCPVersion(){
+        return _fields.get("FCPVersion");
+    }
+    
+    public String getConnectionIdentifier(){
+        return _fields.get("ConnectionIdentifier");
+    }
+    
+    public String getRevision(){
+        return _fields.get("Revision");
+    }
+    
+    public String getVersion(){
+        return _fields.get("Version");
+    }
+    
+    public String getExtBuild(){
+        return _fields.get("ExtBuild");
+    }
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/NodeMessage.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/node/NodeMessage.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/NodeMessage.java
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/NodeMessage.java
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,17 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.node;
+
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+import org.freenetproject.contrib.fcp.FcpMessage;
+
+/**
+ *All node messages are a subclass of this.
+ *
+ * @author Ralph Smithen
+ */
+public abstract class NodeMessage extends FcpMessage{
+
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/Peer.java (from 
rev 15426, trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/node/Peer.java)
===================================================================
--- trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/Peer.java   
                        (rev 0)
+++ trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/Peer.java   
2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,148 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.node;
+
+import org.freenetproject.contrib.fcp.NodeInfo;
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+import org.freenetproject.contrib.fcp.peer.PeerMetaData;
+import org.freenetproject.contrib.fcp.peer.PeerVolatileData;
+
+/**
+ *This gives the details of a Freenet node that is directly connected to your 
node (a peer or friend).
+ * @author Ralph Smithen
+ */
+public class Peer extends NodeMessage{
+    private PeerMetaData peerMetaData;
+    private PeerVolatileData peerVolatileData;
+    
+    public Peer(){
+        peerMetaData = new PeerMetaData(this);
+        peerVolatileData = new PeerVolatileData(this);
+    }
+    
+    /**
+     * @inheritDoc 
+     */
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+        eventSupport.getPeerListEventSupport().firePeerUpdated(this);
+    }
+
+    public String getLastGoodVersion() {
+        return _fields.get("lastGoodVersion");
+    }
+
+    public void setLastGoodVersion(String lastGoodVersion) {
+        _fields.put("lastGoodVersion", lastGoodVersion);
+    }
+
+    public String getPhysicalUdp() {
+        return _fields.get("physical.udp");
+    }
+
+    public void setPhysicalUdp(String physicalUdp) {
+        _fields.put("physical.udp", physicalUdp);
+    }
+
+    public String getId() {
+        return _fields.get("identity");
+    }
+
+    public void setId(String identity) {
+        _fields.put("identity", identity);
+    }
+
+    public String getDsaGroupG() {
+        return _fields.get("dsaGroup.g");
+    }
+
+    public void setDsaGroupG(String dsaGroupG) {
+        _fields.put("dsaGroup.g", dsaGroupG);
+    }
+
+    public String getName() {
+        return _fields.get("myName");
+    }
+
+    public void setName(String name) {
+        _fields.put("myName", name);
+    }
+
+    public String getDsaPubKeyY() {
+        return _fields.get("dsaPubKey.y");
+    }
+
+    public void setDsaPubKeyY(String dsaPubKeyY) {
+        _fields.put("dsaPubKey.y", dsaPubKeyY);
+    }
+
+    public String getDsaGroupQ() {
+        return _fields.get("dsaGroup.q");
+    }
+
+    public void setDsaGroupQ(String dsaGroupQ) {
+        _fields.put("dsaGroup.q", dsaGroupQ);
+    }
+
+    public String getArkNumber() {
+        return _fields.get("ark.number");
+    }
+
+    public void setArkNumber(String arkNumber) {
+        _fields.put("ark.number", arkNumber);
+    }
+
+    public String getVersion() {
+        return _fields.get("version");
+    }
+
+    public void setVersion(String version) {
+        _fields.put("version", version);
+    }
+
+    public String getArkPubUri() {
+        return _fields.get("ark.pubURI");
+    }
+
+    public void setArkPubUri(String arkPubUri) {
+        _fields.put("ark.pubURI", arkPubUri);
+    }
+
+    public String getDsaGroupP() {
+        return _fields.get("dsaGroup.p");
+    }
+
+    public void setDsaGroupP(String dsaGroupP) {
+        _fields.put("dsaGroup.p", dsaGroupP);
+    }
+
+    public double getLocation() {
+        return Double.parseDouble(_fields.get("location"));
+    }
+
+    public void setLocation(double location) {
+        _fields.put("location", String.valueOf(location));
+    }
+
+    public boolean isTestnet() {
+        return Boolean.parseBoolean(_fields.get("testnet"));
+    }
+
+    public void setTestnet(boolean testnet) {
+        _fields.put("_testnet", String.valueOf(testnet));
+    }
+
+    public PeerMetaData getPeerMetaData() {
+        return peerMetaData;
+    }
+
+    public PeerVolatileData getPeerVolatileData() {
+        return peerVolatileData;
+    }
+
+    
+    public String toString(){
+        return getName();
+    }
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/PeerNote.java 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/node/PeerNote.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/PeerNote.java   
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/PeerNote.java   
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,49 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.node;
+
+import org.freenetproject.contrib.fcp.NodeInfo;
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+
+/**
+ *This provides a peer note of a peer of the node.
+ * @author Ralph Smithen
+ */
+public class PeerNote extends NodeMessage{
+    
+    public PeerNote(){
+    }
+    
+    /**
+     * @inheritDoc 
+     */
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+        eventSupport.getPeerListEventSupport().firePeerNote(this);
+    }
+
+    public void setNodeId(String nodeId) {
+        _fields.put("NodeIdentifier", nodeId);
+    }
+
+    public String getNodeId() {
+        return _fields.get("NodeIdentifier");
+    }
+    
+    public void setNoteType(int type){
+        _fields.put("PeerNoteType", String.valueOf(type));
+    }
+    
+    public int getNoteType(){
+        return Integer.parseInt(_fields.get("PeerNoteType"));
+    }
+    
+    public void setNoteText(String s) {
+        _fields.put("NoteText", s);
+    }
+
+    public String getNoteText() {
+        return _fields.get("NoteText");
+    }
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/PersistentPut.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/node/PersistentPut.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/PersistentPut.java
                          (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/PersistentPut.java
  2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,66 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.node;
+
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+import org.freenetproject.contrib.fcp.message.UploadFrom;
+
+/**
+ *This is the node replying to a {@link 
org.freenet.contrib.fcp.message.client.ClientPut ClientPut} 
+ * and confirming the details or the request 
+ * (possibly for clients other than the one that issued the ClientPut, if it 
is on the global queue)
+ *
+ * @author Ralph Smithen
+ */
+public class PersistentPut extends NodeMessage{
+    
+    /**
+     * @inheritDoc 
+     */
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+        
+    }
+
+    public String getId() {
+        return _fields.get("Identifier");
+    }
+    
+    public String getUri() {
+        return _fields.get("URI");
+    }   
+    
+    public int getVerbosity() {
+        return Integer.parseInt(_fields.get("Verbosity"));
+    }
+    
+    public UploadFrom getUploadFrom() {
+        return UploadFrom.valueOf(_fields.get("UploadFrom"));
+    }
+
+    public String getFileName() {
+        return _fields.get("FileName");
+    }
+    
+    public String getTargetFilename() {
+        return _fields.get("TargetFilename");
+    }
+    
+    public String getContentType() {
+        return _fields.get("Metadata.ContentType");
+    }
+    
+    public boolean isGlobal() {
+        return Boolean.parseBoolean(_fields.get("Global"));
+    }
+    
+    public int getDataLength() {
+        return Integer.parseInt(_fields.get("DataLength"));
+    }
+    
+    public int getMaxRetries() {
+        return Integer.parseInt(_fields.get("MaxRetries"));
+    }
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/SSKKeypair.java 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/node/SSKKeypair.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/SSKKeypair.java 
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/SSKKeypair.java 
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,54 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.node;
+
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+
+/**
+ * This is sent from the Freenet node to a client program in response to the 
client 
+ * issuing a {@link org.freenet.contrib.fcp.message.client.GenerateSSK 
GenerateSSK} command.
+ *
+ * @author Ralph Smithen
+ */
+public class SSKKeypair extends NodeMessage{
+    
+    /** Creates a new instance of SSKKeypair */
+    public SSKKeypair() {
+    }
+
+    /**
+     * 
+     * @inheritDoc 
+     */
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+        eventSupport.getSSKKeypairEventSupport().fireKeypairReceived(this);
+    }
+
+    public String getId() {
+        return _fields.get("Identifier");
+    }
+
+    public void setId(String id) {
+        _fields.put("Identifier", id);
+    }
+    
+    public String getInsertURI() {
+        return _fields.get("InsertURI");
+    }
+
+    public void setInsertURI(String uri) {
+        _fields.put("InsertURI", uri);
+    }
+    
+    public String getRequestURI() {
+        return _fields.get("RequestURI");
+    }
+
+    public void setRequestURI(String uri) {
+        _fields.put("RequestURI", uri);
+    }
+    
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/SimpleProgress.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/node/SimpleProgress.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/SimpleProgress.java
                         (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/SimpleProgress.java
 2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,91 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.node;
+
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+
+/**
+ * <p>This indicates the progress of a large request 
+ * (usually a splitfile, a big file which is split across a large number of 
blocks).</p>
+ * 
+ * <p>
+ * Note that before FinalizedTotal=true, Total may vary wildly on a 
+ * {@link org.freenet.contrib.fcp.message.client.ClientGet ClientGet}, 
+ * because we may follow redirects, have to fetch multi-level splitfiles and 
so on. 
+ * However, once we are fetching the final splitfile, FinalizedTotal will be 
set to 
+ * true. Whereas on a {@link org.freenet.contrib.fcp.message.client.ClientPut 
ClientPut}, 
+ * we can't generate the metadata until quite late on, so it takes a long time 
to set 
+ * FinalizedTotal=true, but this doesn't matter as the Total will not increase 
very much 
+ * (since the majority of the insert is the actual data and check blocks).
+ * </p>
+ * @author Ralph Smithen
+ */
+public class SimpleProgress extends NodeMessage{
+    
+    /**
+     * 
+     * @inheritDoc 
+     */
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+        eventSupport.getQueueEventSupport().fireSimpleProgressUpdate(this);
+    }
+
+    public int getTotal() {
+        return Integer.parseInt(_fields.get("Total"));
+    }
+
+    public void setTotal(int total) {
+        _fields.put("Total", String.valueOf(total));
+    }
+
+    public int getRequired() {
+        return Integer.parseInt(_fields.get("Required"));
+    }
+
+    public void setRequired(int required) {
+        _fields.put("Required", String.valueOf(required));
+    }
+
+    public int getFailed() {
+        return Integer.parseInt(_fields.get("Failed"));
+    }
+
+    public void setFailed(int failed) {
+        _fields.put("Failed", String.valueOf(failed));
+    }
+
+    public int getFatallyFailed() {
+        return Integer.parseInt(_fields.get("FatallyFailed"));
+    }
+
+    public void setFatallyFailed(int fatallyFailed) {
+        _fields.put("FatallyFailed", String.valueOf(fatallyFailed));
+    }
+
+    public int getSucceeded() {
+        return Integer.parseInt(_fields.get("Succeeded"));
+    }
+
+    public void setSucceeded(int succeeded) {
+        _fields.put("Succeeded", String.valueOf(succeeded));
+    }
+
+    public boolean isFinalizedTotal() {
+        return Boolean.parseBoolean(_fields.get("FinalizedTotal"));
+    }
+
+    public void setFinalizedTotal(boolean finalizedTotal) {
+         _fields.put("FinalizedTotal", String.valueOf(finalizedTotal));
+    }
+
+    public String getId() {
+        return _fields.get("Identifier");
+    }
+
+    public void setId(String id) {
+        _fields.put("Identifier", id);
+    }
+
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/URIGenerated.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/node/URIGenerated.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/URIGenerated.java
                           (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/URIGenerated.java
   2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,50 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.message.node;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import org.freenetproject.contrib.fcp.event.support.FcpEventSupportRepository;
+
+/**
+ *This indicates the final URI of the data inserted; this may not be the same 
as the original URI, 
+ * which could have been CHK@ ("insert this as a CHK and tell me what its CHK 
is"), 
+ * or an Signed Subspace Key (SSK) using a private key.
+ *
+ * @author Ralph Smithen
+ */
+public class URIGenerated extends NodeMessage{
+    private String _uri;
+    private byte[] _data;
+    
+    /**
+     * Creates a new instance of URIGenerated
+     */
+    public URIGenerated() {
+    }
+    
+    /**
+     * @inheritDoc 
+     */
+    protected void fireEvents(FcpEventSupportRepository eventSupport) {
+        eventSupport.getSSKKeypairEventSupport().fireURIGenerated(this);
+    }
+    
+    public String getId() {
+        return _fields.get("Identifier");
+    }
+    
+    public void setId(String id) {
+        _fields.put("Identifier", id);
+    }
+    
+    public String getUri() {
+        return _fields.get("URI");
+    }
+
+    public void setUri(String uri) {
+        _fields.put("URI", uri);
+    }
+ }

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/package.html 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/node/package.html)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/package.html    
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/node/package.html    
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+  <head>
+  </head>
+  <body>
+      <h1>Node messages</h1>
+      <p>
+          Messages sent from the node to the client.
+      </p>
+  </body>
+</html>

Copied: trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/package.html 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/message/package.html)
===================================================================
--- trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/package.html     
                        (rev 0)
+++ trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/message/package.html     
2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+  <head>
+  </head>
+  <body>
+      <h1>Message utility classes</h1>
+      <p>
+          Core classes for handling FCP messages.
+      </p>
+  </body>
+</html>

Copied: trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/package.html (from 
rev 15426, trunk/apps/jfcp/src/org/freenet/contrib/fcp/package.html)
===================================================================
--- trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/package.html             
                (rev 0)
+++ trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/package.html     
2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+  <head>
+    <title>FCP overview?</title>
+  </head>
+  <body>
+      <h1>Main classes</h1>
+      <p>
+          The main classes of the FCP client library.  You should start 
+          with <code>FreenetClient</code>, which provides a facade for the 
library.
+          Register listeners with the object returned by 
<code>getEventSource</code>.
+      </p>
+  </body>
+</html>

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/LastRoutingBackoffReason.java
 (from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/peer/LastRoutingBackoffReason.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/LastRoutingBackoffReason.java
                               (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/LastRoutingBackoffReason.java
       2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,16 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.peer;
+
+/**
+ *
+ * @author Ralph Smithen
+ */
+public enum LastRoutingBackoffReason {
+        AcceptedTimeout,
+        FatalTimeout,
+        ForwardRejectedOverload,
+        ForwardRejectedOverload2    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/PeerMetaData.java (from 
rev 15426, trunk/apps/jfcp/src/org/freenet/contrib/fcp/peer/PeerMetaData.java)
===================================================================
--- trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/PeerMetaData.java   
                        (rev 0)
+++ trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/PeerMetaData.java   
2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,76 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.peer;
+
+import java.util.Map;
+import org.freenetproject.contrib.fcp.message.node.Peer;
+
+/**
+ * Helper class for {@link org.freenet.contrib.fcp.message.node.Peer Peer}.
+ * @author Ralph Smithen
+ */
+public class PeerMetaData {
+    private Map<String, String> _fields;
+    
+//            metadata.routableConnectionCheckCount=118630
+//            metadata.hadRoutableConnectionCount=20859
+//            metadata.timeLastConnected=1173191216637
+//            metadata.timeLastRoutable=1173191216637
+//            metadata.timeLastReceivedPacket=1173191156574
+//            metadata.detected.udp=130.89.162.43:50591
+    
+    public PeerMetaData(Peer p){
+        _fields = p.getFields();
+    }
+
+    public int getRoutableConnectionCheckCount() {
+        return 
Integer.parseInt(_fields.get("metadata.routableConnectionCheckCount"));
+    }
+
+    public void setRoutableConnectionCheckCount(int 
routableConnectionCheckCount) {
+        _fields.put("metadata.routableConnectionCheckCount", 
String.valueOf(routableConnectionCheckCount));
+    }
+
+    public int getHadRoutableConnectionCount() {
+        return 
Integer.parseInt(_fields.get("metadata.hadRoutableConnectionCount"));
+    }
+
+    public void setHadRoutableConnectionCount(int hadRoutableConnectionCount) {
+        _fields.put("metadata.hadRoutableConnectionCount", 
String.valueOf(hadRoutableConnectionCount));
+    }
+
+    public int getTimeLastConnected() {
+        return Integer.parseInt(_fields.get("metadata.timeLastConnected"));
+    }
+
+    public void setTimeLastConnected(int timeLastConnected) {
+        _fields.put("metadata.timeLastConnected", 
String.valueOf(timeLastConnected));
+    }
+
+    public int getTimeLastRoutable() {
+        return Integer.parseInt(_fields.get("metadata.timeLastRoutable"));
+    }
+
+    public void setTimeLastRoutable(int timeLastRoutable) {
+        _fields.put("metadata.timeLastRoutable", 
String.valueOf(timeLastRoutable));
+    }
+
+    public int getTimeLastReceivedPacket() {
+        return 
Integer.parseInt(_fields.get("metadata.timeLastReceivedPacket"));
+    }
+
+    public void setTimeLastReceivedPacket(int timeLastReceivedPacket) {
+        _fields.put("metadata.timeLastReceivedPacket", 
String.valueOf(timeLastReceivedPacket));
+    }
+
+    public String getDetectedUdp() {
+        return _fields.get("metadata.detected.udp");
+    }
+
+    public void setDetectedUdp(String detectedUdp) {
+        _fields.put("metadata.detected.udp", detectedUdp);
+    }
+    
+}

Copied: 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/PeerVolatileData.java 
(from rev 15426, 
trunk/apps/jfcp/src/org/freenet/contrib/fcp/peer/PeerVolatileData.java)
===================================================================
--- 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/PeerVolatileData.java   
                            (rev 0)
+++ 
trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/PeerVolatileData.java   
    2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,148 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.peer;
+
+import java.util.Map;
+import org.freenetproject.contrib.fcp.message.node.Peer;
+
+/**
+ * Helper class for {@link org.freenet.contrib.fcp.message.node.Peer Peer}.
+ * @author Ralph Smithen
+ */
+public class PeerVolatileData {
+    private Map<String, String> _fields;
+
+    
+//        volatile.averagePingTime=1.0
+//        volatile.overloadProbability=0.0
+//        volatile.idle=791670007
+//        volatile.percentTimeRoutableConnection=17.58324201298154
+//        volatile.routingBackoffPercent=0.0
+//        volatile.status=DISCONNECTED
+//        volatile.totalBytesIn=0
+//        volatile.routingBackoffLength=1000
+//        volatile.routingBackoff=0
+//        volatile.totalBytesOut=8532482
+    
+    
+//            volatile.averagePingTime=375.7280706108754
+//            volatile.overloadProbability=0.262501082516091
+//            volatile.percentTimeRoutableConnection=73.87877919472704
+//            volatile.routingBackoffPercent=0.4766362445492835
+//            volatile.status=CONNECTED
+//            volatile.totalBytesIn=185355902
+//            volatile.routingBackoffLength=1000
+//            volatile.lastRoutingBackoffReason=FatalTimeout
+//            volatile.routingBackoff=0
+//            volatile.totalBytesOut=197757028
+    
+    
+//                volatile.averagePingTime=5869.929339951476
+//                volatile.overloadProbability=21.63939255794491
+//                volatile.idle=89079368
+//                volatile.percentTimeRoutableConnection=49.16023336672756
+//                volatile.routingBackoffPercent=50.18356974749365
+//                volatile.status=DISCONNECTED
+//                volatile.totalBytesIn=30081871
+//                volatile.routingBackoffLength=256000
+//                volatile.lastRoutingBackoffReason=AcceptedTimeout
+//                volatile.routingBackoff=0
+//                volatile.totalBytesOut=72200884
+    
+    
+    
+    /** Creates a new instance of PeerVolatileData */
+    public PeerVolatileData(Peer p) {
+        _fields = p.getFields();
+    }
+
+    public float getAveragePingTime() {
+        return Float.parseFloat(_fields.get("volatile.averagePingTime"));
+    }
+
+    public void setAveragePingTime(float averagePingTime) {
+         _fields.put("volatile.averagePingTime", 
String.valueOf(averagePingTime));
+    }
+
+    public float getOverloadProbability() {
+        return Float.parseFloat(_fields.get("volatile.overloadProbability"));
+    }
+
+    public void setOverloadProbability(float overloadProbability) {
+         _fields.put("volatile.overloadProbability", 
String.valueOf(overloadProbability));
+    }
+
+    public int getIdle() {
+        return Integer.parseInt(_fields.get("volatile.idle"));
+    }
+
+    public void setIdle(int idle) {
+         _fields.put("volatile.idle", String.valueOf(idle));
+    }
+
+    public float getPercentTimeRoutableConnection() {
+        return 
Float.parseFloat(_fields.get("volatile.percentTimeRoutableConnection"));
+    }
+
+    public void setPercentTimeRoutableConnection(float 
percentTimeRoutableConnection) {
+         _fields.put("volatile.percentTimeRoutableConnection", 
String.valueOf(percentTimeRoutableConnection));
+    }
+
+    public float getRoutingBackoffPercent() {
+        return Float.parseFloat(_fields.get("volatile.routingBackoffPercent"));
+    }
+
+    public void setRoutingBackoffPercent(float routingBackoffPercent) {
+         _fields.put("volatile.routingBackoffPercent", 
String.valueOf(routingBackoffPercent));
+    }
+
+    public Status getStatus() {
+        return Status.valueOf(_fields.get("volatile.status").replace(' ', 
'_'));
+    }
+
+    public void setStatus(Status status) {
+        _fields.put("volatile.status", status.toString().replace('_', ' '));
+    }
+
+    public long getTotalBytesIn() {
+        return Long.parseLong(_fields.get("volatile.totalBytesIn"));
+    }
+
+    public void setTotalBytesIn(long totalBytesIn) {
+        _fields.put("volatile.totalBytesIn", String.valueOf(totalBytesIn));
+    }
+
+    public long getRoutingBackoffLength() {
+        return Long.parseLong(_fields.get("volatile.routingBackoffLength"));
+    }
+
+    public void setRoutingBackoffLength(long routingBackoffLength) {
+        _fields.put("volatile.routingBackoffLength", 
String.valueOf(routingBackoffLength));
+    }
+
+    public LastRoutingBackoffReason getLastRoutingBackoffReason() {
+        return 
LastRoutingBackoffReason.valueOf(_fields.get("volatile.lastRoutingBackoffReason"));
+    }
+
+    public void setLastRoutingBackoffReason(LastRoutingBackoffReason 
lastRoutingBackoffReason) {
+        _fields.put("volatile.lastRoutingBackoffReason", 
lastRoutingBackoffReason.toString());
+    }
+
+    public long getRoutingBackoff() {
+        return Long.parseLong(_fields.get("volatile.routingBackoff"));
+    }
+
+    public void setRoutingBackoff(long routingBackoff) {
+        _fields.put("volatile.routingBackoff", String.valueOf(routingBackoff));
+    }
+
+    public long getTotalBytesOut() {
+        return Long.parseLong(_fields.get("volatile.totalBytesOut"));
+    }
+
+    public void setTotalBytesOut(long totalBytesOut) {
+        _fields.put("volatile.totalBytesOut", String.valueOf(totalBytesOut));
+    }
+}

Copied: trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/Status.java 
(from rev 15426, trunk/apps/jfcp/src/org/freenet/contrib/fcp/peer/Status.java)
===================================================================
--- trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/Status.java         
                (rev 0)
+++ trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/Status.java 
2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,19 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package org.freenetproject.contrib.fcp.peer;
+
+/**
+ * Connection status of peer.
+ * @author Ralph Smithen
+ */
+public enum Status {
+        CONNECTED,
+        DISCONNECTING,
+        DISCONNECTED,
+        BACKED_OFF,
+        TOO_NEW,
+        TOO_OLD,
+        NEVER_CONNECTED
+}

Copied: trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/package.html 
(from rev 15426, trunk/apps/jfcp/src/org/freenet/contrib/fcp/peer/package.html)
===================================================================
--- trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/package.html        
                        (rev 0)
+++ trunk/apps/jfcp/src/org/freenetproject/contrib/fcp/peer/package.html        
2007-10-03 13:21:48 UTC (rev 15428)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+  <head>
+  </head>
+  <body>
+      <h1>Peer helper classes</h1>
+      <p>
+          These classes help simplify the <code>Peer</code> message.
+      </p>
+  </body>
+</html>


Reply via email to