Author: mes
Date: 2011-06-20 17:07:29 -0700 (Mon, 20 Jun 2011)
New Revision: 25825

Modified:
   
core3/event-api/branches/nagling-events/src/main/java/org/cytoscape/event/AbstractCyEvent.java
   
core3/event-api/branches/nagling-events/src/main/java/org/cytoscape/event/AbstractCyPayloadEvent.java
   
core3/event-api/branches/nagling-events/src/main/java/org/cytoscape/event/CyEventHelper.java
   
core3/event-api/branches/nagling-events/src/main/java/org/cytoscape/event/CyPayloadEvent.java
   
core3/event-api/branches/nagling-events/src/test/java/org/cytoscape/event/AbstractCyEventHelperTest.java
   
core3/event-api/branches/nagling-events/src/test/java/org/cytoscape/event/AbstractCyPayloadEventTest.java
   
core3/event-api/branches/nagling-events/src/test/java/org/cytoscape/event/StubCyPayloadListenerImpl.java
   
core3/event-impl/branches/nagling-events/impl/src/main/java/org/cytoscape/event/internal/CyEventHelperImpl.java
   
core3/event-impl/branches/nagling-events/impl/src/main/java/org/cytoscape/event/internal/CyListenerAdapter.java
Log:
Lots of cleanup

Modified: 
core3/event-api/branches/nagling-events/src/main/java/org/cytoscape/event/AbstractCyEvent.java
===================================================================
--- 
core3/event-api/branches/nagling-events/src/main/java/org/cytoscape/event/AbstractCyEvent.java
      2011-06-20 23:15:01 UTC (rev 25824)
+++ 
core3/event-api/branches/nagling-events/src/main/java/org/cytoscape/event/AbstractCyEvent.java
      2011-06-21 00:07:29 UTC (rev 25825)
@@ -47,7 +47,6 @@
         * Constructor.
         * @param source The source object that fires the event. May NOT be 
null.
         * @param listenerClass The Class that defines the listener interface. 
May NOT be null.
-        * @param synchronousOnly Whether the event may only be fired 
synchronously.
         */
        public AbstractCyEvent(final T source, Class<?> listenerClass) {
                if ( source == null )

Modified: 
core3/event-api/branches/nagling-events/src/main/java/org/cytoscape/event/AbstractCyPayloadEvent.java
===================================================================
--- 
core3/event-api/branches/nagling-events/src/main/java/org/cytoscape/event/AbstractCyPayloadEvent.java
       2011-06-20 23:15:01 UTC (rev 25824)
+++ 
core3/event-api/branches/nagling-events/src/main/java/org/cytoscape/event/AbstractCyPayloadEvent.java
       2011-06-21 00:07:29 UTC (rev 25825)
@@ -35,6 +35,7 @@
 package org.cytoscape.event;
 
 import java.util.Collection;
+import java.util.Collections;
 
 /**
  * A base implementation of CyPayloadEvent that can be used by events.
@@ -43,17 +44,24 @@
 
        private final Collection<P> payload;
 
+       /**
+        * Constructor.
+        * @param source The event source object.
+        * @param listenerClass The listener class for this event.
+        * @param payload A collection of payload objects. May be empty, but 
not null!
+        */
        public AbstractCyPayloadEvent(final T source, Class<?> listenerClass, 
Collection<P> payload) {
                super(source, listenerClass);
 
                if ( payload == null )
                        throw new NullPointerException("Payload is null");
 
-               this.payload = payload;
+               this.payload = Collections.unmodifiableCollection(payload);
        }
 
        /**
-        * {@inheritDoc}
+        * Returns an unmodifiable collection of payload objects.
+        * @return an unmodifiable collection of payload objects.
         */
        @Override
        public Collection<P> getPayloadCollection() {

Modified: 
core3/event-api/branches/nagling-events/src/main/java/org/cytoscape/event/CyEventHelper.java
===================================================================
--- 
core3/event-api/branches/nagling-events/src/main/java/org/cytoscape/event/CyEventHelper.java
        2011-06-20 23:15:01 UTC (rev 25824)
+++ 
core3/event-api/branches/nagling-events/src/main/java/org/cytoscape/event/CyEventHelper.java
        2011-06-21 00:07:29 UTC (rev 25825)
@@ -38,7 +38,7 @@
         * The default number of milliseconds to wait before the next
         * time that we will check for payload events to fire. 
         */
-       int DEFAULT_PAYLOAD_WAIT_TIME_MILLIS = 100;
+       int DEFAULT_PAYLOAD_INTERVAL_MILLIS = 100;
        
        /**
         * Calls each listener found in the Service Registry identified by the 
listenerClass
@@ -50,11 +50,12 @@
        <E extends CyEvent<?>> void fireEvent(final E event);
 
        /**
-        * Adds a payload object to be accumulated in an event. The event is 
guaranteed
+        * Adds a payload object to be accumulated in a CyPayloadEvent. The 
event is guaranteed
         * to be fired after a certain duration where the single event contains 
all payload
         * objects added to the event within that window of time.  Payload 
objects added
         * after an event has fired simply trigger a new event to fire at the 
next time
-        * point.
+        * point. All accumulated CyPayloadEvents are guaranteed to be fired 
before any
+        * normal CyEvents are fired.
         * @param source The object firing the event.
         * @param payload The data payload to be added to the event that will
         * eventually be fired.

Modified: 
core3/event-api/branches/nagling-events/src/main/java/org/cytoscape/event/CyPayloadEvent.java
===================================================================
--- 
core3/event-api/branches/nagling-events/src/main/java/org/cytoscape/event/CyPayloadEvent.java
       2011-06-20 23:15:01 UTC (rev 25824)
+++ 
core3/event-api/branches/nagling-events/src/main/java/org/cytoscape/event/CyPayloadEvent.java
       2011-06-21 00:07:29 UTC (rev 25825)
@@ -37,7 +37,16 @@
 
 import java.util.Collection;
 
-public interface CyPayloadEvent<T,P> extends CyEvent<T> {
+/**
+ * An extension of CyEvent specifically for payload events.
+ * @param <S> The event source type.
+ * @param <P> The payload type.
+ */
+public interface CyPayloadEvent<S,P> extends CyEvent<S> {
        
+       /**
+        * Returns a collection of payload objects.
+        * @return a collection of payload objects.
+        */
        Collection<P> getPayloadCollection();
 }

Modified: 
core3/event-api/branches/nagling-events/src/test/java/org/cytoscape/event/AbstractCyEventHelperTest.java
===================================================================
--- 
core3/event-api/branches/nagling-events/src/test/java/org/cytoscape/event/AbstractCyEventHelperTest.java
    2011-06-20 23:15:01 UTC (rev 25824)
+++ 
core3/event-api/branches/nagling-events/src/test/java/org/cytoscape/event/AbstractCyEventHelperTest.java
    2011-06-21 00:07:29 UTC (rev 25825)
@@ -68,7 +68,7 @@
        // We verify that the payload approach is at least 3 times faster than 
the
        // event/listener combo. 
        @Test
-       public void testLD1second() {
+       public void testLD1fifthsecond() {
                final long duration = 200000000;
 
                long end = System.nanoTime() + duration;
@@ -212,4 +212,15 @@
                assertTrue( payloadService.getNumCalls() > 1 );
                } catch ( InterruptedException ie ) { throw new 
RuntimeException(ie); }
        }
+       
+       @Test
+       public void testPayloadBeforeNormal() {
+               
helper.addEventPayload("source","homer",StubCyPayloadEvent.class);
+               
helper.addEventPayload("source","marge",StubCyPayloadEvent.class);
+               helper.fireEvent(new StubCyEvent("lisa"));
+               // This tests that any accumulated payload events get fired 
before
+               // normal events.
+               assertTrue(payloadService.getNumCalls() == 1);
+               assertTrue(service.getNumCalls() == 1);
+       }
 }

Modified: 
core3/event-api/branches/nagling-events/src/test/java/org/cytoscape/event/AbstractCyPayloadEventTest.java
===================================================================
--- 
core3/event-api/branches/nagling-events/src/test/java/org/cytoscape/event/AbstractCyPayloadEventTest.java
   2011-06-20 23:15:01 UTC (rev 25824)
+++ 
core3/event-api/branches/nagling-events/src/test/java/org/cytoscape/event/AbstractCyPayloadEventTest.java
   2011-06-21 00:07:29 UTC (rev 25825)
@@ -85,4 +85,15 @@
                assertEquals(0,payload.size());
                assertFalse(payload.contains("bart"));
        }
+       
+       @Test(expected=UnsupportedOperationException.class)
+       public void testCantModifyPayload() {
+               List<String> l = new ArrayList<String>();
+               l.add("homer");
+               l.add("marge");
+               Object source = new Object(); 
+               TestEvent<Object,String> e = new 
TestEvent<Object,String>(source,Object.class,l);
+               Collection<String> payload = e.getPayloadCollection();
+               payload.add("something");
+       }
 }

Modified: 
core3/event-api/branches/nagling-events/src/test/java/org/cytoscape/event/StubCyPayloadListenerImpl.java
===================================================================
--- 
core3/event-api/branches/nagling-events/src/test/java/org/cytoscape/event/StubCyPayloadListenerImpl.java
    2011-06-20 23:15:01 UTC (rev 25824)
+++ 
core3/event-api/branches/nagling-events/src/test/java/org/cytoscape/event/StubCyPayloadListenerImpl.java
    2011-06-21 00:07:29 UTC (rev 25825)
@@ -49,15 +49,9 @@
         * @param e DOCUMENT ME!
         */
        public void handleEvent(StubCyPayloadEvent e) {
-//             System.out.println("begin handle payload in thread " + 
Thread.currentThread());
-//             for (String payload : e.getPayloadCollection()) {
-//                     System.out.print(payload + "  ");
-//             }
-//             System.out.println("");
                called++;
                if ( eh != null ) {
                        for ( int i = 0; i < 5; i++ ) {
-//                             System.out.println("adding additional event 
payloads..." + i);
                                try { Thread.sleep(100); } catch (Exception ex) 
{}
                                
eh.addEventPayload("listener","payload"+i,StubCyPayloadEvent.class);
                        }

Modified: 
core3/event-impl/branches/nagling-events/impl/src/main/java/org/cytoscape/event/internal/CyEventHelperImpl.java
===================================================================
--- 
core3/event-impl/branches/nagling-events/impl/src/main/java/org/cytoscape/event/internal/CyEventHelperImpl.java
     2011-06-20 23:15:01 UTC (rev 25824)
+++ 
core3/event-impl/branches/nagling-events/impl/src/main/java/org/cytoscape/event/internal/CyEventHelperImpl.java
     2011-06-21 00:07:29 UTC (rev 25825)
@@ -67,35 +67,33 @@
        private boolean havePayload;
 
        public CyEventHelperImpl(final CyListenerAdapter normal) {
-               
//System.out.println("\n\n===================================================================================\n\n");
                this.normal = normal;
-
                sourceAccMap = new 
HashMap<Object,Map<Class<?>,PayloadAccumulator<?,?,?>>>();
-
                payloadEventMonitor = 
Executors.newSingleThreadScheduledExecutor();
-               
                silencedSources = new HashSet<Object>();
-               
                havePayload = false;
 
-        final Runnable firingAgent = new Runnable() {
+               // This thread just flushes any accumulated payload events.
+               // It is scheduled to run repeatedly at a fixed interval.
+        final Runnable payloadChecker = new Runnable() {
             public void run() {
-               final int x = new Random().nextInt();
-               //System.out.println("*************** begin firing check 
*************  " + x + "    " + Thread.currentThread() + "  " + havePayload + " 
 " + System.currentTimeMillis() + "   " + CyEventHelperImpl.this.hashCode() + " 
 " + this.hashCode());
                 flushPayloadEvents();
-               //System.out.println("*************** end firing check 
***************  " + x + "    " + Thread.currentThread());
             }
         };
-        payloadEventMonitor.scheduleAtFixedRate(firingAgent, 
CyEventHelper.DEFAULT_PAYLOAD_WAIT_TIME_MILLIS, 
CyEventHelper.DEFAULT_PAYLOAD_WAIT_TIME_MILLIS, TimeUnit.MILLISECONDS);
+        payloadEventMonitor.scheduleAtFixedRate(payloadChecker, 
CyEventHelper.DEFAULT_PAYLOAD_INTERVAL_MILLIS, 
CyEventHelper.DEFAULT_PAYLOAD_INTERVAL_MILLIS, TimeUnit.MILLISECONDS);
        }       
 
        @Override 
        public <E extends CyEvent<?>> void fireEvent(final E event) {
-               //System.out.println("firing event: " + event);
+               // Before any external event is fired, flush any accumulated
+               // payload events.  Because addEventPayload() in synchronous,
+               // all payloads should be added by the time fireEvent() is
+               // called in the client code.  
+               flushPayloadEvents();
+               
                normal.fireEvent(event);
        }
 
-
        @Override 
        public void silenceEventSource(Object eventSource) {
                if ( eventSource == null )
@@ -147,8 +145,6 @@
                        
                        acc.addPayload(payload);
                        havePayload = true;
-                       
-                       //System.out.println("addEventPayload: " + source + "  
" + payload + "  " + eventType + "  " + Thread.currentThread() + "  " + 
havePayload + "  " + System.currentTimeMillis());
                }               
        }
 
@@ -156,22 +152,18 @@
                List<CyPayloadEvent<?,?>> flushList;
                
                synchronized (this) {
-                       //System.out.println("trying forceFirePayloadEvents in 
thread: " + Thread.currentThread() + "   " + havePayload);
+
                        if ( !havePayload )
                                return;
                        
                        flushList = new ArrayList<CyPayloadEvent<?,?>>();
                        havePayload = false;
                        
-                       //System.out.println("forceFirePayloadEvents in thread: 
" + Thread.currentThread());
                        for ( Object source : sourceAccMap.keySet() ) {
-                               //System.out.println("   examining source: " + 
source);
                                for ( PayloadAccumulator<?,?,?> acc : 
sourceAccMap.get(source).values() ) {
-                                       //System.out.println("      found 
accumulator: " + acc);
                                        try {
                                                CyPayloadEvent<?,?> event = 
acc.newEventInstance( source );
                                                if ( event != null ) {
-                                                       
//System.out.println("adding event to flush list " + event);
                                                        flushList.add(event);
                                                }
                                        } catch (Exception ie) {
@@ -180,15 +172,16 @@
                                }
                        }
                        
-                       //System.out.println("forceFirePayloadEvents finished 
collecting events: " + Thread.currentThread() + "    " + havePayload);
                }
                
+               // Actually fire the events outside of the synchronized block.
                for (CyPayloadEvent<?,?> event : flushList) {
-                       //System.out.println("-----------force firing event: " 
+ event);
-                       fireEvent(event);
+                       normal.fireEvent(event);
                }       
        }
        
+       // Used only for unit testing to prevent the confusion of multiple 
+       // threads running at once.
        public void cleanup() {
                payloadEventMonitor.shutdown();
        }

Modified: 
core3/event-impl/branches/nagling-events/impl/src/main/java/org/cytoscape/event/internal/CyListenerAdapter.java
===================================================================
--- 
core3/event-impl/branches/nagling-events/impl/src/main/java/org/cytoscape/event/internal/CyListenerAdapter.java
     2011-06-20 23:15:01 UTC (rev 25824)
+++ 
core3/event-impl/branches/nagling-events/impl/src/main/java/org/cytoscape/event/internal/CyListenerAdapter.java
     2011-06-21 00:07:29 UTC (rev 25825)
@@ -50,7 +50,6 @@
  */
 public class CyListenerAdapter {
        private static final Logger logger = 
LoggerFactory.getLogger(CyListenerAdapter.class);
-       private static final Executor EXEC = Executors.newCachedThreadPool();
        private static final ServiceComparator serviceComparator = new 
ServiceComparator(); 
 
        private final Map<Class<?>,ServiceTracker> serviceTrackers; 
@@ -85,21 +84,11 @@
                final Class<?> listenerClass = event.getListenerClass();
                
                final Object[] listeners = getListeners(listenerClass);
-               if ( listeners == null ) {
+               if ( listeners == null ) 
                        return;
-               } 
-
-       //      if ( event.synchronousOnly() )
-                       fireSynchronousEvent(event,listenerClass,listeners);
-       //      else
-       //              fireAsynchronousEvent(event,listenerClass,listeners);
-       }
-
-
-
-       private <E extends CyEvent<?>> void fireSynchronousEvent(final E event, 
Class<?> listenerClass, Object[] listeners) {
-
+               
                Object lastListener = null;
+               
                try {
                        final Method method = 
listenerClass.getMethod("handleEvent", event.getClass());
 
@@ -121,30 +110,6 @@
                }
        }
 
-       /**
-        * Calls each listener found in the Service Registry identified by the 
listenerClass
-        * and filter with the supplied event in a new thread.<p>This method 
should <b>ONLY</b>
-        * ever be called with a thread safe event object!</p>
-        *
-        * @param <E> The type of event. 
-        * @param event  The event object. 
-        */
-       private <E extends CyEvent> void fireAsynchronousEvent(final E event, 
Class<?> listenerClass, Object[] listeners) {
-
-
-               try {
-                       final Method method = 
listenerClass.getMethod("handleEvent", event.getClass());
-
-                       for (final Object listener : listeners) {
-                               EXEC.execute(new Runner(method, listener, 
event, listenerClass));
-                       }
-               } catch (NoSuchMethodException e) {
-                       // TODO should probably rethrow
-                       logger.error("Listener doesn't implement 
\"handleEvent\" method: "
-                                          + listenerClass.getName(), e);
-               }
-       }
-
        private Object[] getListeners(Class<?> listenerClass) {
                if ( !serviceTrackers.containsKey( listenerClass ) ) {
                        //logger.debug("added new service tracker for " + 
listenerClass);
@@ -170,30 +135,4 @@
                silencedSources.remove(eventSource);
        }
 
-
-       private static class Runner implements Runnable {
-               private final Method method;
-               private final Object listener;
-               private final Object event;
-               private final Class clazz;
-
-               public Runner(final Method method, final Object listener, final 
Object event, Class clazz) {
-                       this.method = method;
-                       this.listener = listener;
-                       this.event = event;
-                       this.clazz = clazz;
-               }
-
-               public void run() {
-                       try {
-                               method.invoke(clazz.cast(listener), event);
-                       } catch (IllegalAccessException e) {
-                               // TODO should rethrow as something
-                               logger.error("Listener can't execute 
\"handleEvent\" method: " + clazz.getName(), e);
-                       } catch (InvocationTargetException e) {
-                               // TODO should rethrow as something
-                               logger.error("Listener threw exception as part 
of \"handleEvent\" invocation: " + listener.toString(), e);
-                       }
-               }
-       }
 }

-- 
You received this message because you are subscribed to the Google Groups 
"cytoscape-cvs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/cytoscape-cvs?hl=en.

Reply via email to