@@ -0,0 +1,103 @@
package org.bukkit.plugin.messaging;

import org.bukkit.plugin.Plugin;

/**
* Contains information about a {@link Plugin}s registration to a plugin channel.
*/
public final class PluginMessageListenerRegistration {
private final Messenger messenger;
private final Plugin plugin;
private final String channel;
private final PluginMessageListener listener;

public PluginMessageListenerRegistration(Messenger messenger, Plugin plugin, String channel, PluginMessageListener listener) {
if (messenger == null) {
throw new IllegalArgumentException("Messenger cannot be null!");
}
if (plugin == null) {
throw new IllegalArgumentException("Plugin cannot be null!");
}
if (channel == null) {
throw new IllegalArgumentException("Channel cannot be null!");
}
if (listener == null) {
throw new IllegalArgumentException("Listener cannot be null!");
}

this.messenger = messenger;
this.plugin = plugin;
this.channel = channel;
this.listener = listener;
}

/**
* Gets the plugin channel that this registration is about.
*
* @return Plugin channel.
*/
public String getChannel() {
return channel;
}

/**
* Gets the registered listener described by this registration.
*
* @return Registered listener.
*/
public PluginMessageListener getListener() {
return listener;
}

/**
* Gets the plugin that this registration is for.
*
* @return Registered plugin.
*/
public Plugin getPlugin() {
return plugin;
}

/**
* Checks if this registration is still valid.
*
* @return True if this registration is still valid, otherwise false.
*/
public boolean isValid() {
return messenger.isRegistrationValid(this);
}

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final PluginMessageListenerRegistration other = (PluginMessageListenerRegistration) obj;
if (this.messenger != other.messenger && (this.messenger == null || !this.messenger.equals(other.messenger))) {
return false;
}
if (this.plugin != other.plugin && (this.plugin == null || !this.plugin.equals(other.plugin))) {
return false;
}
if ((this.channel == null) ? (other.channel != null) : !this.channel.equals(other.channel)) {
return false;
}
if (this.listener != other.listener && (this.listener == null || !this.listener.equals(other.listener))) {
return false;
}
return true;
}

@Override
public int hashCode() {
int hash = 7;
hash = 53 * hash + (this.messenger != null ? this.messenger.hashCode() : 0);
hash = 53 * hash + (this.plugin != null ? this.plugin.hashCode() : 0);
hash = 53 * hash + (this.channel != null ? this.channel.hashCode() : 0);
hash = 53 * hash + (this.listener != null ? this.listener.hashCode() : 0);
return hash;
}
}
@@ -0,0 +1,32 @@
package org.bukkit.plugin.messaging;

import java.util.Set;
import org.bukkit.plugin.Plugin;

/**
* Represents a possible recipient for a Plugin Message.
*/
public interface PluginMessageRecipient {
/**
* Sends this recipient a Plugin Message on the specified outgoing channel.
* <p>
* The message may not be larger than {@link Messenger#MAX_MESSAGE_SIZE} bytes, and the plugin must be registered to send
* messages on the specified channel.
*
* @param source The plugin that sent this message.
* @param channel The channel to send this message on.
* @param message The raw message to send.
* @throws IllegalArgumentException Thrown if the source plugin is disabled.
* @throws IllegalArgumentException Thrown if source, channel or message is null.
* @throws MessageTooLargeException Thrown if the message is too big.
* @throws ChannelNotRegisteredException Thrown if the channel is not registered for this plugin.
*/
public void sendPluginMessage(Plugin source, String channel, byte[] message);

/**
* Gets a set containing all the Plugin Channels that this client is listening on.
*
* @return Set containing all the channels that this client may accept.
*/
public Set<String> getListeningPluginChannels();
}
@@ -0,0 +1,14 @@
package org.bukkit.plugin.messaging;

/**
* Thrown if a plugin attempts to register for a reserved channel (such as "REGISTER")
*/
public class ReservedChannelException extends RuntimeException {
public ReservedChannelException() {
this("Attempted to register for a reserved channel name.");
}

public ReservedChannelException(String name) {
super("Attempted to register for a reserved channel name ('" + name + "')");
}
}

Large diffs are not rendered by default.

@@ -0,0 +1,288 @@
package org.bukkit.plugin.messaging;

import org.bukkit.plugin.messaging.ReservedChannelException;
import java.util.Collection;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.matchers.JUnitMatchers.*;

public class StandardMessengerTest {
public StandardMessenger getMessenger() {
return new StandardMessenger();
}

public TestPlugin getPlugin() {
return new TestPlugin();
}

@Test
public void testIsReservedChannel() {
Messenger messenger = getMessenger();

assertTrue(messenger.isReservedChannel("REGISTER"));
assertFalse(messenger.isReservedChannel("register"));
assertTrue(messenger.isReservedChannel("UNREGISTER"));
assertFalse(messenger.isReservedChannel("unregister"));
assertFalse(messenger.isReservedChannel("notReserved"));
}

@Test
public void testRegisterAndUnregisterOutgoingPluginChannel() {
Messenger messenger = getMessenger();
TestPlugin plugin = getPlugin();

assertFalse(messenger.isOutgoingChannelRegistered(plugin, "foo"));
messenger.registerOutgoingPluginChannel(plugin, "foo");
assertTrue(messenger.isOutgoingChannelRegistered(plugin, "foo"));
assertFalse(messenger.isOutgoingChannelRegistered(plugin, "bar"));

messenger.unregisterOutgoingPluginChannel(plugin, "foo");
assertFalse(messenger.isOutgoingChannelRegistered(plugin, "foo"));
}

@Test(expected=ReservedChannelException.class)
public void testReservedOutgoingRegistration() {
Messenger messenger = getMessenger();
TestPlugin plugin = getPlugin();

messenger.registerOutgoingPluginChannel(plugin, "REGISTER");
}

@Test
public void testUnregisterOutgoingPluginChannel_Plugin() {
Messenger messenger = getMessenger();
TestPlugin plugin = getPlugin();

assertFalse(messenger.isOutgoingChannelRegistered(plugin, "foo"));
messenger.registerOutgoingPluginChannel(plugin, "foo");
messenger.registerOutgoingPluginChannel(plugin, "bar");
assertTrue(messenger.isOutgoingChannelRegistered(plugin, "foo"));
assertTrue(messenger.isOutgoingChannelRegistered(plugin, "bar"));

messenger.unregisterOutgoingPluginChannel(plugin);
assertFalse(messenger.isOutgoingChannelRegistered(plugin, "foo"));
assertFalse(messenger.isOutgoingChannelRegistered(plugin, "bar"));
}

@Test
public void testRegisterIncomingPluginChannel() {
Messenger messenger = getMessenger();
TestPlugin plugin = getPlugin();
TestMessageListener listener = new TestMessageListener("foo", "bar".getBytes());
TestPlayer player = new TestPlayer();
PluginMessageListenerRegistration registration = messenger.registerIncomingPluginChannel(plugin, "foo", listener);

assertTrue(registration.isValid());
assertTrue(messenger.isIncomingChannelRegistered(plugin, "foo"));
messenger.dispatchIncomingMessage(player, "foo", "bar".getBytes());
assertTrue(listener.hasReceived());

messenger.unregisterIncomingPluginChannel(plugin, "foo", listener);
listener.reset();

assertFalse(registration.isValid());
assertFalse(messenger.isIncomingChannelRegistered(plugin, "foo"));
messenger.dispatchIncomingMessage(player, "foo", "bar".getBytes());
assertFalse(listener.hasReceived());
}

@Test(expected=ReservedChannelException.class)
public void testReservedIncomingRegistration() {
Messenger messenger = getMessenger();
TestPlugin plugin = getPlugin();

messenger.registerIncomingPluginChannel(plugin, "REGISTER", new TestMessageListener("foo", "bar".getBytes()));
}

@Test(expected=IllegalArgumentException.class)
public void testDuplicateIncomingRegistration() {
Messenger messenger = getMessenger();
TestPlugin plugin = getPlugin();
TestMessageListener listener = new TestMessageListener("foo", "bar".getBytes());

messenger.registerIncomingPluginChannel(plugin, "baz", listener);
messenger.registerIncomingPluginChannel(plugin, "baz", listener);
}

@Test
public void testUnregisterIncomingPluginChannel_Plugin_String() {
Messenger messenger = getMessenger();
TestPlugin plugin = getPlugin();
TestMessageListener listener1 = new TestMessageListener("foo", "bar".getBytes());
TestMessageListener listener2 = new TestMessageListener("baz", "qux".getBytes());
TestPlayer player = new TestPlayer();
PluginMessageListenerRegistration registration1 = messenger.registerIncomingPluginChannel(plugin, "foo", listener1);
PluginMessageListenerRegistration registration2 = messenger.registerIncomingPluginChannel(plugin, "baz", listener2);

assertTrue(registration1.isValid());
assertTrue(registration2.isValid());
messenger.dispatchIncomingMessage(player, "foo", "bar".getBytes());
messenger.dispatchIncomingMessage(player, "baz", "qux".getBytes());
assertTrue(listener1.hasReceived());
assertTrue(listener2.hasReceived());

messenger.unregisterIncomingPluginChannel(plugin, "foo");
listener1.reset();
listener2.reset();

assertFalse(registration1.isValid());
assertTrue(registration2.isValid());
messenger.dispatchIncomingMessage(player, "foo", "bar".getBytes());
messenger.dispatchIncomingMessage(player, "baz", "qux".getBytes());
assertFalse(listener1.hasReceived());
assertTrue(listener2.hasReceived());
}

@Test
public void testUnregisterIncomingPluginChannel_Plugin() {
Messenger messenger = getMessenger();
TestPlugin plugin = getPlugin();
TestMessageListener listener1 = new TestMessageListener("foo", "bar".getBytes());
TestMessageListener listener2 = new TestMessageListener("baz", "qux".getBytes());
TestPlayer player = new TestPlayer();
PluginMessageListenerRegistration registration1 = messenger.registerIncomingPluginChannel(plugin, "foo", listener1);
PluginMessageListenerRegistration registration2 = messenger.registerIncomingPluginChannel(plugin, "baz", listener2);

assertTrue(registration1.isValid());
assertTrue(registration2.isValid());
messenger.dispatchIncomingMessage(player, "foo", "bar".getBytes());
messenger.dispatchIncomingMessage(player, "baz", "qux".getBytes());
assertTrue(listener1.hasReceived());
assertTrue(listener2.hasReceived());

messenger.unregisterIncomingPluginChannel(plugin);
listener1.reset();
listener2.reset();

assertFalse(registration1.isValid());
assertFalse(registration2.isValid());
messenger.dispatchIncomingMessage(player, "foo", "bar".getBytes());
messenger.dispatchIncomingMessage(player, "baz", "qux".getBytes());
assertFalse(listener1.hasReceived());
assertFalse(listener2.hasReceived());
}

@Test
public void testGetOutgoingChannels() {
Messenger messenger = getMessenger();
TestPlugin plugin1 = getPlugin();
TestPlugin plugin2 = getPlugin();

assertEquals(messenger.getOutgoingChannels());

messenger.registerOutgoingPluginChannel(plugin1, "foo");
messenger.registerOutgoingPluginChannel(plugin1, "bar");
messenger.registerOutgoingPluginChannel(plugin2, "baz");
messenger.registerOutgoingPluginChannel(plugin2, "baz");

assertEquals(messenger.getOutgoingChannels(), "foo", "bar", "baz");
}

@Test
public void testGetOutgoingChannels_Plugin() {
Messenger messenger = getMessenger();
TestPlugin plugin1 = getPlugin();
TestPlugin plugin2 = getPlugin();
TestPlugin plugin3 = getPlugin();

messenger.registerOutgoingPluginChannel(plugin1, "foo");
messenger.registerOutgoingPluginChannel(plugin1, "bar");
messenger.registerOutgoingPluginChannel(plugin2, "baz");
messenger.registerOutgoingPluginChannel(plugin2, "qux");

assertEquals(messenger.getOutgoingChannels(plugin1), "foo", "bar");
assertEquals(messenger.getOutgoingChannels(plugin2), "baz", "qux");
assertEquals(messenger.getOutgoingChannels(plugin3));
}

@Test
public void testGetIncomingChannels() {
Messenger messenger = getMessenger();
TestPlugin plugin1 = getPlugin();
TestPlugin plugin2 = getPlugin();

assertEquals(messenger.getIncomingChannels());

messenger.registerIncomingPluginChannel(plugin1, "foo", new TestMessageListener("foo", "bar".getBytes()));
messenger.registerIncomingPluginChannel(plugin1, "bar", new TestMessageListener("foo", "bar".getBytes()));
messenger.registerIncomingPluginChannel(plugin2, "baz", new TestMessageListener("foo", "bar".getBytes()));
messenger.registerIncomingPluginChannel(plugin2, "baz", new TestMessageListener("foo", "bar".getBytes()));

assertEquals(messenger.getIncomingChannels(), "foo", "bar", "baz");
}

@Test
public void testGetIncomingChannels_Plugin() {
Messenger messenger = getMessenger();
TestPlugin plugin1 = getPlugin();
TestPlugin plugin2 = getPlugin();
TestPlugin plugin3 = getPlugin();

messenger.registerIncomingPluginChannel(plugin1, "foo", new TestMessageListener("foo", "bar".getBytes()));
messenger.registerIncomingPluginChannel(plugin1, "bar", new TestMessageListener("foo", "bar".getBytes()));
messenger.registerIncomingPluginChannel(plugin2, "baz", new TestMessageListener("foo", "bar".getBytes()));
messenger.registerIncomingPluginChannel(plugin2, "qux", new TestMessageListener("foo", "bar".getBytes()));

assertEquals(messenger.getIncomingChannels(plugin1), "foo", "bar");
assertEquals(messenger.getIncomingChannels(plugin2), "baz", "qux");
assertEquals(messenger.getIncomingChannels(plugin3));
}

@Test
public void testGetIncomingChannelRegistrations_Plugin() {
Messenger messenger = getMessenger();
TestPlugin plugin1 = getPlugin();
TestPlugin plugin2 = getPlugin();
TestPlugin plugin3 = getPlugin();
PluginMessageListenerRegistration registration1 = messenger.registerIncomingPluginChannel(plugin1, "foo", new TestMessageListener("foo", "bar".getBytes()));
PluginMessageListenerRegistration registration2 = messenger.registerIncomingPluginChannel(plugin1, "bar", new TestMessageListener("foo", "bar".getBytes()));
PluginMessageListenerRegistration registration3 = messenger.registerIncomingPluginChannel(plugin2, "baz", new TestMessageListener("foo", "bar".getBytes()));
PluginMessageListenerRegistration registration4 = messenger.registerIncomingPluginChannel(plugin2, "qux", new TestMessageListener("foo", "bar".getBytes()));

assertEquals(messenger.getIncomingChannelRegistrations(plugin1), registration1, registration2);
assertEquals(messenger.getIncomingChannelRegistrations(plugin2), registration3, registration4);
assertEquals(messenger.getIncomingChannels(plugin3));
}

@Test
public void testGetIncomingChannelRegistrations_String() {
Messenger messenger = getMessenger();
TestPlugin plugin1 = getPlugin();
TestPlugin plugin2 = getPlugin();
PluginMessageListenerRegistration registration1 = messenger.registerIncomingPluginChannel(plugin1, "foo", new TestMessageListener("foo", "bar".getBytes()));
PluginMessageListenerRegistration registration2 = messenger.registerIncomingPluginChannel(plugin1, "bar", new TestMessageListener("foo", "bar".getBytes()));
PluginMessageListenerRegistration registration3 = messenger.registerIncomingPluginChannel(plugin2, "foo", new TestMessageListener("foo", "bar".getBytes()));
PluginMessageListenerRegistration registration4 = messenger.registerIncomingPluginChannel(plugin2, "bar", new TestMessageListener("foo", "bar".getBytes()));

assertEquals(messenger.getIncomingChannelRegistrations("foo"), registration1, registration3);
assertEquals(messenger.getIncomingChannelRegistrations("bar"), registration2, registration4);
assertEquals(messenger.getIncomingChannelRegistrations("baz"));
}

@Test
public void testGetIncomingChannelRegistrations_Plugin_String() {
Messenger messenger = getMessenger();
TestPlugin plugin1 = getPlugin();
TestPlugin plugin2 = getPlugin();
TestPlugin plugin3 = getPlugin();
PluginMessageListenerRegistration registration1 = messenger.registerIncomingPluginChannel(plugin1, "foo", new TestMessageListener("foo", "bar".getBytes()));
PluginMessageListenerRegistration registration2 = messenger.registerIncomingPluginChannel(plugin1, "foo", new TestMessageListener("foo", "bar".getBytes()));
PluginMessageListenerRegistration registration3 = messenger.registerIncomingPluginChannel(plugin1, "bar", new TestMessageListener("foo", "bar".getBytes()));
PluginMessageListenerRegistration registration4 = messenger.registerIncomingPluginChannel(plugin2, "bar", new TestMessageListener("foo", "bar".getBytes()));
PluginMessageListenerRegistration registration5 = messenger.registerIncomingPluginChannel(plugin2, "baz", new TestMessageListener("foo", "bar".getBytes()));
PluginMessageListenerRegistration registration6 = messenger.registerIncomingPluginChannel(plugin2, "baz", new TestMessageListener("foo", "bar".getBytes()));

assertEquals(messenger.getIncomingChannelRegistrations(plugin1, "foo"), registration1, registration2);
assertEquals(messenger.getIncomingChannelRegistrations(plugin1, "bar"), registration3);
assertEquals(messenger.getIncomingChannelRegistrations(plugin2, "bar"), registration4);
assertEquals(messenger.getIncomingChannelRegistrations(plugin2, "baz"), registration5, registration6);
assertEquals(messenger.getIncomingChannelRegistrations(plugin1, "baz"));
assertEquals(messenger.getIncomingChannelRegistrations(plugin3, "qux"));
}

private static <T> void assertEquals(Collection<T> actual, T... expected) {
assertThat("Size of the array", actual.size(), is(expected.length));
assertThat(actual, hasItems(expected));
}
}
@@ -0,0 +1,29 @@
package org.bukkit.plugin.messaging;

import org.bukkit.entity.Player;
import static org.junit.Assert.*;

public class TestMessageListener implements PluginMessageListener {
private final String channel;
private final byte[] message;
private boolean received = false;

public TestMessageListener(String channel, byte[] message) {
this.channel = channel;
this.message = message;
}

public void onPluginMessageReceived(String channel, Player player, byte[] message) {
assertEquals(this.channel, channel);
assertArrayEquals(this.message, message);
this.received = true;
}

public boolean hasReceived() {
return received;
}

public void reset() {
received = false;
}
}

Large diffs are not rendered by default.

@@ -0,0 +1,116 @@
package org.bukkit.plugin.messaging;

import com.avaje.ebean.EbeanServer;
import java.io.File;
import java.io.InputStream;
import org.bukkit.Server;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.event.Event.Type;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginLoader;
import org.bukkit.util.config.Configuration;

public class TestPlugin implements Plugin {
private boolean enabled = true;

public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

public File getDataFolder() {
throw new UnsupportedOperationException("Not supported.");
}

public PluginDescriptionFile getDescription() {
throw new UnsupportedOperationException("Not supported.");
}

public Configuration getConfiguration() {
throw new UnsupportedOperationException("Not supported.");
}

public FileConfiguration getConfig() {
throw new UnsupportedOperationException("Not supported.");
}

public InputStream getResource(String filename) {
throw new UnsupportedOperationException("Not supported.");
}

public void saveConfig() {
throw new UnsupportedOperationException("Not supported.");
}

public void saveDefaultConfig() {
throw new UnsupportedOperationException("Not supported.");
}

public void saveResource(String resourcePath, boolean replace) {
throw new UnsupportedOperationException("Not supported.");
}

public void reloadConfig() {
throw new UnsupportedOperationException("Not supported.");
}

public PluginLoader getPluginLoader() {
throw new UnsupportedOperationException("Not supported.");
}

public Server getServer() {
throw new UnsupportedOperationException("Not supported.");
}

public boolean isEnabled() {
return enabled;
}

public void onDisable() {
throw new UnsupportedOperationException("Not supported.");
}

public void onLoad() {
throw new UnsupportedOperationException("Not supported.");
}

public void onEnable() {
throw new UnsupportedOperationException("Not supported.");
}

public boolean isNaggable() {
throw new UnsupportedOperationException("Not supported.");
}

public void setNaggable(boolean canNag) {
throw new UnsupportedOperationException("Not supported.");
}

public EbeanServer getDatabase() {
throw new UnsupportedOperationException("Not supported.");
}

public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) {
throw new UnsupportedOperationException("Not supported.");
}

public long getTiming(Type type) {
throw new UnsupportedOperationException("Not supported.");
}

public void incTiming(Type type, long delta) {
throw new UnsupportedOperationException("Not supported.");
}

public void resetTimings() {
throw new UnsupportedOperationException("Not supported.");
}

public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
throw new UnsupportedOperationException("Not supported.");
}

}