libs.net: complete network functionality
[WeStealzYourDataz.git] / src / uk / ac / ntu / n0521366 / wsyd / libs / net / NetworkServerAbstract.java
index b8eaae5..3a866df 100644 (file)
@@ -65,7 +65,7 @@ import javax.swing.SwingWorker;
  * 
  * @author TJ <hacker@iam.tj>
  */
-public abstract class NetworkServerAbstract extends SwingWorker<Integer, NetworkMessage> implements NetworkMessageEventGenerator {
+public abstract class NetworkServerAbstract extends SwingWorker<Integer, NetworkMessage> {
 
     /**
      * Single Logger for the class used by all object instances.
@@ -100,28 +100,8 @@ public abstract class NetworkServerAbstract extends SwingWorker<Integer, Network
     WSYD_SocketAddress _socketAddress;
 
     protected ServiceAddressMap _serviceToHostMap;
-    /**
-     * Thread safe First In, First Out Queue of NetworkMessage objects waiting to be sent.
-     * 
-     * Allows the Owner Thread to submit new messages for sending that the Worker Thread
-     * can safely access.
-     */
-    protected ConcurrentLinkedQueue<NetworkMessage> _sendMessageQueue = new ConcurrentLinkedQueue<>();
-
-    /**
-     * Wrapper for filtering NetworkMessageEvents based on the message intent
-     */
-    public class NetworkMessageEventListenerWithIntent {
-        String _intent;
-        NetworkMessageEventListener _listener;
-        
-        public NetworkMessageEventListenerWithIntent(NetworkMessageEventListener listener, String intent) {
-            _intent = intent;
-            _listener = listener;
-        }
-    }
-    protected ArrayList<NetworkMessageEventListenerWithIntent> _NetworkMessageEventListeners = new ArrayList<>();
 
+    private final NetworkMessageEventListenerManager _eventManager;
     /**
      * 
      * @param level message importance
@@ -171,6 +151,7 @@ public abstract class NetworkServerAbstract extends SwingWorker<Integer, Network
         this._title = null;
         this._socketAddress = null;
         this._serviceToHostMap = null;
+        this._eventManager = null;
     }
     
     /**
@@ -188,6 +169,7 @@ public abstract class NetworkServerAbstract extends SwingWorker<Integer, Network
         this._title = title;
         this._socketAddress = socketAddress;
         this._serviceToHostMap = serviceToHostMap;
+        this._eventManager = new NetworkMessageEventListenerManager();
         if (LOGGER == null) // do not replace existing logger reference
             LOGGER = logger;
     }
@@ -268,7 +250,7 @@ public abstract class NetworkServerAbstract extends SwingWorker<Integer, Network
                 this._connectionCount++;
 
             // send a queued message
-            NetworkMessage temp =  this.dequeueMessage();
+            NetworkMessage temp =  this.sendMessage();
             if (temp != null) {
                 if (!this.serverSend(temp)) {
                     logMessages.clear();
@@ -296,7 +278,16 @@ public abstract class NetworkServerAbstract extends SwingWorker<Integer, Network
         return this._connectionCount;
     }
 
-
+    /**
+     * Removes a message from a queue of pending messages.
+     *
+     * This method is called on the Worker Thread by the doInBackground() main loop.
+     * 
+     * Sub-classes that have the ability to transmit messages should implement this fully.
+     *
+     * @return a message to be sent
+     */
+    protected abstract NetworkMessage sendMessage();
     /**
      * Open the socket ready for accepting data or connections.
      * 
@@ -340,20 +331,13 @@ public abstract class NetworkServerAbstract extends SwingWorker<Integer, Network
      */
     public abstract boolean serverListen();
 
-    /**
-     * Removes a message from the queue of pending messages.
-     *
-     * This method is called on the Worker Thread by the doInBackground() main loop.
-     *
-     * @return a message to be sent
-     */
-    protected NetworkMessage dequeueMessage() {
-        return this._sendMessageQueue.poll();
-    }
-    
     /* XXX: Methods below here all execute on the GUI Event Dispatch Thread */
 
 
+    public NetworkMessageEventListenerManager getEventManager() {
+        return this._eventManager;
+    }
+    
     /**
      * Fetch messages received by the server.
      * 
@@ -365,7 +349,7 @@ public abstract class NetworkServerAbstract extends SwingWorker<Integer, Network
     @Override
     protected void process(List<NetworkMessage> list) {
         for (NetworkMessage message: list) {
-            fireNetworkMessageEvent(message);
+            this._eventManager.fireNetworkMessageEvent(message);
         }
     }
 
@@ -376,86 +360,4 @@ public abstract class NetworkServerAbstract extends SwingWorker<Integer, Network
      */
     @Override
     protected abstract void done();
-
-    /**
-     * Adds a message to the queue of pending messages.
-     * 
-     * This method will usually be called from the Owner Thread.
-     * 
-     * @param message to be sent
-     * @return true if the message was added to the queue
-     * @throws IllegalArgumentException if the target does not exist in the serviceToHost mapping
-     */
-    public boolean queueMessage(NetworkMessage message) throws IllegalArgumentException {
-        boolean result = false;
-        if (message != null) {
-            // ensure the target is set and is a valid service
-            String target = message.getTarget();
-            if (target == null)
-                throw new IllegalArgumentException("target cannot be null");
-            if(!_serviceToHostMap.isServiceValid(target))
-                throw new IllegalArgumentException("target service does not exist: " + target);
-            
-            NetworkMessage temp;
-            try { // make a deep clone of the message
-                temp = NetworkMessage.clone(message);
-                result = this._sendMessageQueue.add(temp);
-            } catch (CloneNotSupportedException e) {
-                // TODO: queueMessage() log CloneNotSupportedException
-                e.printStackTrace();
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Add a NetworkMessageEvent listener.
-     * 
-     * Listens to all intents.
-     * 
-     * @param listener 
-     */
-    @Override
-    public synchronized void addNetworkMessageEventListener(NetworkMessageEventListener listener) {
-        _NetworkMessageEventListeners.add(new NetworkMessageEventListenerWithIntent(listener, null));
-    }
-
-    /**
-     * Add a filtered NetworkMessageEvent listener.
-     * 
-     * Filters on the intent of the NetworkMessage.
-     * @param listener
-     * @param intent null to listen to all intents, otherwise the intent to listen for
-     */
-    @Override
-    public synchronized void addNetworkMessageEventListener(NetworkMessageEventListener listener, String intent) {
-        _NetworkMessageEventListeners.add(new NetworkMessageEventListenerWithIntent(listener, intent));        
-    }
-
-    /**
-     * Remove a NetworkMessageEvent listener.
-     * 
-     * @param listener 
-     */
-    @Override
-    public synchronized void removeNetworkMessageEventListener(NetworkMessageEventListener listener) {
-        for (NetworkMessageEventListenerWithIntent intentListener : _NetworkMessageEventListeners)
-            if (intentListener._listener == listener)
-                _NetworkMessageEventListeners.remove(intentListener);
-    }
-    
-    /**
-     * Send a NetworkMessageEvent to all listeners.
-     * 
-     * Only sends the message to listeners registered for the same intent, or for all messages.
-     * 
-     * @param message the NetworkMessage to send
-     */
-    private synchronized void fireNetworkMessageEvent(NetworkMessage message) {
-        NetworkMessageEvent event = new NetworkMessageEvent(this, message);
-        for (NetworkMessageEventListenerWithIntent intentListener : _NetworkMessageEventListeners) {
-            if (intentListener._intent.equals(message._intent) || intentListener._intent == null)
-                intentListener._listener.NetworkMessageReceived(event);
-        }
-    }
 }