Author: reto
Date: Fri Apr 29 18:13:58 2011
New Revision: 1097903

URL: http://svn.apache.org/viewvc?rev=1097903&view=rev
Log:
CLEREZZA-503: Keeping weak references to MGraphListeners

Modified:
    
incubator/clerezza/trunk/parent/rdf.core/src/main/java/org/apache/clerezza/rdf/core/TripleCollection.java
    
incubator/clerezza/trunk/parent/rdf.core/src/main/java/org/apache/clerezza/rdf/core/impl/AbstractTripleCollection.java
    
incubator/clerezza/trunk/parent/rdf.core/src/main/java/org/apache/clerezza/rdf/core/impl/DelayedNotificator.java

Modified: 
incubator/clerezza/trunk/parent/rdf.core/src/main/java/org/apache/clerezza/rdf/core/TripleCollection.java
URL: 
http://svn.apache.org/viewvc/incubator/clerezza/trunk/parent/rdf.core/src/main/java/org/apache/clerezza/rdf/core/TripleCollection.java?rev=1097903&r1=1097902&r2=1097903&view=diff
==============================================================================
--- 
incubator/clerezza/trunk/parent/rdf.core/src/main/java/org/apache/clerezza/rdf/core/TripleCollection.java
 (original)
+++ 
incubator/clerezza/trunk/parent/rdf.core/src/main/java/org/apache/clerezza/rdf/core/TripleCollection.java
 Fri Apr 29 18:13:58 2011
@@ -67,12 +67,16 @@ public interface TripleCollection extend
         * only partially propagate their changes to the listener. They should
         * describe the behavior in the documentation of the class.
         *
+        * Implementations should keep weak references the listeners, so that 
the
+        * listener can be garbage collected if its no longer referenced by 
another
+        * object.
+        *
         * If delay is 0 notification will happen synchroneously.
         *
         * @param listener The listener that will be notified
         * @param filter The triple filter with which triples are tested,
         *              that were part of the modification.
-        * @param delay The time period afer which the listener will be 
notified.
+        * @param delay The time period afer which the listener will be 
notified in milliseconds.
         */
        public void addGraphListener(GraphListener listener, FilterTriple 
filter,
                        long delay);

Modified: 
incubator/clerezza/trunk/parent/rdf.core/src/main/java/org/apache/clerezza/rdf/core/impl/AbstractTripleCollection.java
URL: 
http://svn.apache.org/viewvc/incubator/clerezza/trunk/parent/rdf.core/src/main/java/org/apache/clerezza/rdf/core/impl/AbstractTripleCollection.java?rev=1097903&r1=1097902&r2=1097903&view=diff
==============================================================================
--- 
incubator/clerezza/trunk/parent/rdf.core/src/main/java/org/apache/clerezza/rdf/core/impl/AbstractTripleCollection.java
 (original)
+++ 
incubator/clerezza/trunk/parent/rdf.core/src/main/java/org/apache/clerezza/rdf/core/impl/AbstractTripleCollection.java
 Fri Apr 29 18:13:58 2011
@@ -18,6 +18,7 @@
  */
 package org.apache.clerezza.rdf.core.impl;
 
+import java.lang.ref.WeakReference;
 import java.util.AbstractCollection;
 import java.util.Collection;
 import java.util.Collections;
@@ -178,9 +179,16 @@ public abstract class AbstractTripleColl
         */
        protected void dispatchEvent(GraphEvent event) {
                synchronized(listenerConfigs) {
-                       for (ListenerConfiguration config : listenerConfigs) {
+                       Iterator<ListenerConfiguration> iter = 
listenerConfigs.iterator();
+                       while (iter.hasNext()) {
+                               ListenerConfiguration config = iter.next();
+                               GraphListener registeredListener = 
config.getListener();
+                               if (registeredListener == null) {
+                                       iter.remove();
+                                       continue;
+                               }
                                if 
(config.getFilter().match(event.getTriple())) {
-                                       
delayedNotificator.sendEventToListener(config.getListener(), event);
+                                       
delayedNotificator.sendEventToListener(registeredListener, event);
                                }
                        }
                }
@@ -206,7 +214,8 @@ public abstract class AbstractTripleColl
                        Iterator<ListenerConfiguration> iter = 
listenerConfigs.iterator();
                        while (iter.hasNext()) {
                                ListenerConfiguration listenerConfig = 
iter.next();
-                               if 
(listenerConfig.getListener().equals(listener)) {
+                               GraphListener registeredListener = 
listenerConfig.getListener();
+                               if ((registeredListener == null) || 
(registeredListener.equals(listener))) {
                                        iter.remove();
                                }
                        }
@@ -216,11 +225,11 @@ public abstract class AbstractTripleColl
 
        private static class ListenerConfiguration {
 
-               private GraphListener listener;
+               private WeakReference<GraphListener> listenerRef;
                private FilterTriple filter;
 
                private ListenerConfiguration(GraphListener listener, 
FilterTriple filter) {
-                       this.listener = listener;
+                       this.listenerRef = new 
WeakReference<GraphListener>(listener);
                        this.filter = filter;
                }
 
@@ -228,6 +237,7 @@ public abstract class AbstractTripleColl
                 * @return the listener
                 */
                GraphListener getListener() {
+                       GraphListener listener = listenerRef.get();
                        return listener;
                }
 

Modified: 
incubator/clerezza/trunk/parent/rdf.core/src/main/java/org/apache/clerezza/rdf/core/impl/DelayedNotificator.java
URL: 
http://svn.apache.org/viewvc/incubator/clerezza/trunk/parent/rdf.core/src/main/java/org/apache/clerezza/rdf/core/impl/DelayedNotificator.java?rev=1097903&r1=1097902&r2=1097903&view=diff
==============================================================================
--- 
incubator/clerezza/trunk/parent/rdf.core/src/main/java/org/apache/clerezza/rdf/core/impl/DelayedNotificator.java
 (original)
+++ 
incubator/clerezza/trunk/parent/rdf.core/src/main/java/org/apache/clerezza/rdf/core/impl/DelayedNotificator.java
 Fri Apr 29 18:13:58 2011
@@ -18,15 +18,13 @@
  */
 package org.apache.clerezza.rdf.core.impl;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
+import java.lang.ref.WeakReference;
+import java.util.*;
+
 import org.apache.clerezza.rdf.core.event.GraphEvent;
 import org.apache.clerezza.rdf.core.event.GraphListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  *
@@ -34,23 +32,20 @@ import org.apache.clerezza.rdf.core.even
  */
 class DelayedNotificator {
 
+       private static final Logger log = 
LoggerFactory.getLogger(DelayedNotificator.class);
        private static Timer timer = new Timer("Event delivery timer",true);
 
        static class ListenerHolder {
 
                long delay;
                List<GraphEvent> events = null;
-               GraphListener listener;
+               WeakReference<GraphListener> listenerRef;
 
                public ListenerHolder(GraphListener listener, long delay) {
-                       this.listener = listener;
+                       this.listenerRef = new 
WeakReference<GraphListener>(listener);
                        this.delay = delay;
                }
 
-               private ListenerHolder(long delay) {
-                       throw new UnsupportedOperationException("Not yet 
implemented");
-               }
-
                private void registerEvent(GraphEvent event) {
                        synchronized (this) {
                                if (events == null) {
@@ -65,7 +60,16 @@ class DelayedNotificator {
                                                                eventsLocal = 
events;
                                                                events = null;
                                                        }
-                                                       
listener.graphChanged(eventsLocal);
+                                                       GraphListener listener 
= listenerRef.get();
+                                                       if (listener == null) {
+                                                               
log.debug("Ignoring garbage collected listener");
+                                                       } else {
+                                                               try {
+                                                                       
listener.graphChanged(eventsLocal);
+                                                               } catch 
(Exception e) {
+                                                                       
log.warn("Exception delivering graph event", e);
+                                                               }
+                                                       }
                                                }
                                        }, delay);
                                } else {
@@ -74,25 +78,26 @@ class DelayedNotificator {
                        }
                }
        }
-       private Map<GraphListener, ListenerHolder> map = 
Collections.synchronizedMap(
-                       new HashMap<GraphListener, ListenerHolder>());
+       
+       private final Map<GraphListener, ListenerHolder> map = 
Collections.synchronizedMap(
+                       new WeakHashMap<GraphListener, ListenerHolder>());
 
        void addDelayedListener(GraphListener listener, long delay) {
                map.put(listener, new ListenerHolder(listener, delay));
        }
 
        /**
-        * removes a Listener, this doesn't prevent the listener from receiving 
+        * removes a Listener, this doesn't prevent the listenerRef from 
receiving
         * events alreay scheduled.
         *
-        * @param listener
+        * @param listenerRef
         */
        void removeDelayedListener(GraphListener listener) {
                map.remove(listener);
        }
 
        /**
-        * if the listener has not been registered as delayed listener te 
events is
+        * if the listenerRef has not been registered as delayed listenerRef te 
events is
         * forwarded synchroneously
         * @param event
         */


Reply via email to