X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fnet%2Fpterodactylus%2Ffcp%2Fhighlevel%2FFcpClient.java;h=d33105c8cda87e098c9d5a166ad1c9312c61859b;hb=2f53d9c624a991257f26a7d543a925cfbffd65d8;hp=5a3ec091afb6182cc71c71b9acb94a320fe97b80;hpb=d649abb6cc777878323c0e21ee665e88934d3873;p=jFCPlib.git diff --git a/src/net/pterodactylus/fcp/highlevel/FcpClient.java b/src/net/pterodactylus/fcp/highlevel/FcpClient.java index 5a3ec09..d33105c 100644 --- a/src/net/pterodactylus/fcp/highlevel/FcpClient.java +++ b/src/net/pterodactylus/fcp/highlevel/FcpClient.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.net.InetAddress; import java.net.URL; import java.net.UnknownHostException; +import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.concurrent.CountDownLatch; @@ -30,16 +31,23 @@ import java.util.concurrent.CountDownLatch; import net.pterodactylus.fcp.AddPeer; import net.pterodactylus.fcp.ClientHello; import net.pterodactylus.fcp.CloseConnectionDuplicateClientName; +import net.pterodactylus.fcp.EndListPeerNotes; import net.pterodactylus.fcp.EndListPeers; import net.pterodactylus.fcp.FcpAdapter; import net.pterodactylus.fcp.FcpConnection; import net.pterodactylus.fcp.FcpListener; +import net.pterodactylus.fcp.ListPeerNotes; import net.pterodactylus.fcp.ListPeers; import net.pterodactylus.fcp.ModifyPeer; +import net.pterodactylus.fcp.ModifyPeerNote; import net.pterodactylus.fcp.NodeHello; import net.pterodactylus.fcp.NodeRef; import net.pterodactylus.fcp.Peer; +import net.pterodactylus.fcp.PeerNote; +import net.pterodactylus.fcp.PeerRemoved; import net.pterodactylus.fcp.ProtocolError; +import net.pterodactylus.fcp.RemovePeer; +import net.pterodactylus.util.thread.ObjectWrapper; /** * High-level FCP client that hides the details of the underlying FCP @@ -140,7 +148,18 @@ public class FcpClient { * if an FCP error occurs */ public void connect() throws IOException, FcpException { - ExtendedFcpAdapter fcpListener = new ExtendedFcpAdapter() { + new ExtendedFcpAdapter() { + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("synthetic-access") + public void run() throws IOException { + fcpConnection.connect(); + ClientHello clientHello = new ClientHello(name); + fcpConnection.sendMessage(clientHello); + } /** * {@inheritDoc} @@ -149,26 +168,7 @@ public class FcpClient { public void receivedNodeHello(FcpConnection fcpConnection, NodeHello nodeHello) { completionLatch.countDown(); } - }; - fcpConnection.addFcpListener(fcpListener); - try { - fcpConnection.connect(); - ClientHello clientHello = new ClientHello(name); - fcpConnection.sendMessage(clientHello); - while (true) { - try { - fcpListener.complete(); - break; - } catch (InterruptedException e) { - /* ignore, we’ll loop. */ - } - } - } finally { - fcpConnection.removeFcpListener(fcpListener); - } - if (fcpListener.getFcpException() != null) { - throw fcpListener.getFcpException(); - } + }.execute(); } /** @@ -188,22 +188,40 @@ public class FcpClient { /** * Returns all peers that the node has. * + * @param withMetadata + * true to include peer metadata + * @param withVolatile + * true to include volatile peer data * @return A set containing the node’s peers * @throws IOException * if an I/O error occurs * @throws FcpException * if an FCP error occurs */ - public Set getPeers() throws IOException, FcpException { - final Set peers = new HashSet(); - ExtendedFcpAdapter fcpListener = new ExtendedFcpAdapter() { + public Set getPeers(final boolean withMetadata, final boolean withVolatile) throws IOException, FcpException { + final Set peers = Collections.synchronizedSet(new HashSet()); + new ExtendedFcpAdapter() { + + /** The ID of the “ListPeers” request. */ + private String identifier = "list-peers-" + System.currentTimeMillis(); + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("synthetic-access") + public void run() throws IOException { + fcpConnection.sendMessage(new ListPeers(identifier, withMetadata, withVolatile)); + } /** * {@inheritDoc} */ @Override public void receivedPeer(FcpConnection fcpConnection, Peer peer) { - peers.add(peer); + if (peer.getIdentifier().equals(identifier)) { + peers.add(peer); + } } /** @@ -211,26 +229,11 @@ public class FcpClient { */ @Override public void receivedEndListPeers(FcpConnection fcpConnection, EndListPeers endListPeers) { - completionLatch.countDown(); - } - }; - fcpConnection.addFcpListener(fcpListener); - fcpConnection.sendMessage(new ListPeers("list-peers")); - try { - while (true) { - try { - fcpListener.complete(); - break; - } catch (InterruptedException e) { - /* ignore, we’ll loop. */ + if (endListPeers.getIdentifier().equals(identifier)) { + completionLatch.countDown(); } } - } finally { - fcpConnection.removeFcpListener(fcpListener); - } - if (fcpListener.getFcpException() != null) { - throw fcpListener.getFcpException(); - } + }.execute(); return peers; } @@ -305,8 +308,17 @@ public class FcpClient { * @throws FcpException * if an FCP error occurs */ - private void addPeer(AddPeer addPeer) throws IOException, FcpException { - ExtendedFcpAdapter fcpListener = new ExtendedFcpAdapter() { + private void addPeer(final AddPeer addPeer) throws IOException, FcpException { + new ExtendedFcpAdapter() { + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("synthetic-access") + public void run() throws IOException { + fcpConnection.sendMessage(addPeer); + } /** * {@inheritDoc} @@ -315,24 +327,7 @@ public class FcpClient { public void receivedPeer(FcpConnection fcpConnection, Peer peer) { completionLatch.countDown(); } - }; - fcpConnection.addFcpListener(fcpListener); - try { - fcpConnection.sendMessage(addPeer); - while (true) { - try { - fcpListener.complete(); - break; - } catch (InterruptedException ie1) { - /* ignore, we’ll loop. */ - } - } - } finally { - fcpConnection.removeFcpListener(fcpListener); - } - if (fcpListener.getFcpException() != null) { - throw fcpListener.getFcpException(); - } + }.execute(); } /** @@ -356,8 +351,17 @@ public class FcpClient { * @throws FcpException * if an FCP error occurs */ - public void modifyPeer(Peer peer, Boolean allowLocalAddresses, Boolean disabled, Boolean listenOnly) throws IOException, FcpException { - ExtendedFcpAdapter fcpListener = new ExtendedFcpAdapter() { + public void modifyPeer(final Peer peer, final Boolean allowLocalAddresses, final Boolean disabled, final Boolean listenOnly) throws IOException, FcpException { + new ExtendedFcpAdapter() { + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("synthetic-access") + public void run() throws IOException { + fcpConnection.sendMessage(new ModifyPeer(peer.getIdentity(), allowLocalAddresses, disabled, listenOnly)); + } /** * {@inheritDoc} @@ -366,16 +370,127 @@ public class FcpClient { public void receivedPeer(FcpConnection fcpConnection, Peer peer) { completionLatch.countDown(); } - }; - fcpConnection.addFcpListener(fcpListener); - try { - fcpConnection.sendMessage(new ModifyPeer(peer.getIdentity(), allowLocalAddresses, disabled, listenOnly)); - } finally { - fcpConnection.removeFcpListener(fcpListener); - } - if (fcpListener.getFcpException() != null) { - throw fcpListener.getFcpException(); - } + }.execute(); + } + + /** + * Removes the given peer. + * + * @param peer + * The peer to remove + * @throws IOException + * if an I/O error occurs + * @throws FcpException + * if an FCP error occurs + */ + public void removePeer(final Peer peer) throws IOException, FcpException { + new ExtendedFcpAdapter() { + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("synthetic-access") + public void run() throws IOException { + fcpConnection.sendMessage(new RemovePeer(peer.getIdentity())); + } + + /** + * {@inheritDoc} + */ + @Override + public void receivedPeerRemoved(FcpConnection fcpConnection, PeerRemoved peerRemoved) { + completionLatch.countDown(); + } + }.execute(); + } + + // + // PEER NOTES MANAGEMENT + // + + /** + * Returns the peer note of the given peer. + * + * @param peer + * The peer to get the note for + * @return The peer’s note + * @throws IOException + * if an I/O error occurs + * @throws FcpException + * if an FCP error occurs + */ + public PeerNote getPeerNote(final Peer peer) throws IOException, FcpException { + final ObjectWrapper objectWrapper = new ObjectWrapper(); + new ExtendedFcpAdapter() { + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("synthetic-access") + public void run() throws IOException { + fcpConnection.sendMessage(new ListPeerNotes(peer.getIdentity())); + } + + /** + * {@inheritDoc} + */ + @Override + public void receivedPeerNote(FcpConnection fcpConnection, PeerNote peerNote) { + if (peerNote.getNodeIdentifier().equals(peer.getIdentity())) { + objectWrapper.set(peerNote); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void receivedEndListPeerNotes(FcpConnection fcpConnection, EndListPeerNotes endListPeerNotes) { + completionLatch.countDown(); + } + }.execute(); + return objectWrapper.get(); + } + + /** + * Replaces the peer note for the given peer. + * + * @param peer + * The peer + * @param noteText + * The new base64-encoded note text + * @param noteType + * The type of the note (currently only 1 is + * allowed) + * @throws IOException + * if an I/O error occurs + * @throws FcpException + * if an FCP error occurs + */ + public void modifyPeerNote(final Peer peer, final String noteText, final int noteType) throws IOException, FcpException { + new ExtendedFcpAdapter() { + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("synthetic-access") + public void run() throws IOException { + fcpConnection.sendMessage(new ModifyPeerNote(peer.getIdentity(), noteText, noteType)); + } + + /** + * {@inheritDoc} + */ + @Override + public void receivedPeer(FcpConnection fcpConnection, Peer receivedPeer) { + if (receivedPeer.getIdentity().equals(peer.getIdentity())) { + completionLatch.countDown(); + } + } + }.execute(); } /** @@ -384,7 +499,7 @@ public class FcpClient { * * @author David ‘Bombe’ Roden <bombe@freenetproject.org> */ - private static class ExtendedFcpAdapter extends FcpAdapter { + private abstract class ExtendedFcpAdapter extends FcpAdapter { /** The count down latch used to wait for completion. */ protected final CountDownLatch completionLatch = new CountDownLatch(1); @@ -400,24 +515,42 @@ public class FcpClient { } /** - * Returns the FCP exception that occured. If no FCP exception occured, - * null is returned. + * Executes the FCP commands in {@link #run()}, wrapping the execution + * and catching exceptions. * - * @return The FCP exception that occured, or null + * @throws IOException + * if an I/O error occurs + * @throws FcpException + * if an FCP error occurs */ - public FcpException getFcpException() { - return fcpException; + @SuppressWarnings("synthetic-access") + public void execute() throws IOException, FcpException { + fcpConnection.addFcpListener(this); + try { + run(); + while (true) { + try { + completionLatch.await(); + break; + } catch (InterruptedException ie1) { + /* ignore, we’ll loop. */ + } + } + } finally { + fcpConnection.removeFcpListener(this); + } + if (fcpException != null) { + throw fcpException; + } } /** - * Waits for the completion of the command. + * The FCP commands that actually get executed. * - * @throws InterruptedException - * if {@link CountDownLatch#await()} is interrupted + * @throws IOException + * if an I/O error occurs */ - public void complete() throws InterruptedException { - completionLatch.await(); - } + public abstract void run() throws IOException; /** * {@inheritDoc}