mx4j/src/core/mx4j/server/interceptor NotificationListenerMBeanServerInterceptor.java,1.11,1.12

Simone Bordet <[email protected]> Tue, 15 Feb 2005 10:22:46 +0000
Newsgroups gmane.comp.java.mx4j.cvs
Message-ID <[email protected]>
Update of /cvsroot/mx4j/mx4j/src/core/mx4j/server/interceptor
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24445/src/core/mx4j/server/interceptor

Modified Files:
	NotificationListenerMBeanServerInterceptor.java 
Log Message:
Fix and tests for NotificationListener wrapping.
Now MX4J passed to removeNL() the same (identical) listener that was passed to addNL(), for the same emitter

Index: NotificationListenerMBeanServerInterceptor.java
===================================================================
RCS file: /cvsroot/mx4j/mx4j/src/core/mx4j/server/interceptor/NotificationListenerMBeanServerInterceptor.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** NotificationListenerMBeanServerInterceptor.java	13 Nov 2004 16:38:40 -0000	1.11
--- NotificationListenerMBeanServerInterceptor.java	15 Feb 2005 10:22:44 -0000	1.12
***************
*** 9,12 ****
--- 9,15 ----
  package mx4j.server.interceptor;
  
+ import java.util.HashMap;
+ import java.util.Map;
+ 
  import javax.management.ListenerNotFoundException;
  import javax.management.Notification;
***************
*** 25,28 ****
--- 28,106 ----
  public class NotificationListenerMBeanServerInterceptor extends DefaultMBeanServerInterceptor
  {
+    private Map wrappers = new HashMap();
+ 
+    public String getType()
+    {
+       return "notificationlistener";
+    }
+ 
+    /**
+     * The goal of this machinery is to make sure that, for a given emitter,
+     * when a listener is removed the listener can be identity compared
+     * (using ==) with a listener that has been previously added to the same emitter.
+     * This is the reason why {@link ListenerWrapperKey#equals} has been implemented
+     * using identity (==) and not equality (equals()).
+     * The listener instance passed by the MBeanServer to the emitter when removing
+     * the listener itself should be the same passed when the listener was added.
+     * If for any reason the listener is not found, it will be wrapped with a new
+     * wrapper that will allow the emitter to compare listener by equality
+     * (what normally happens using Collection data structures) and behave correctly
+     * most of the times (certainly MX4J's NotificationBroadcasterSupport will do).
+     */
+    private ListenerWrapper getListenerWrapper(MBeanMetaData metadata, NotificationListener listener)
+    {
+       ListenerWrapperKey key = new ListenerWrapperKey(listener, metadata.getMBean());
+       ListenerWrapper wrapper = null;
+       synchronized (wrappers)
+       {
+          wrapper = (ListenerWrapper)wrappers.get(key);
+          if (wrapper == null)
+          {
+             wrapper = new ListenerWrapper(listener, metadata.getObjectName());
+             wrappers.put(key, wrapper);
+          }
+       }
+       return wrapper;
+    }
+ 
+    public void addNotificationListener(MBeanMetaData metadata, NotificationListener listener, NotificationFilter filter, Object handback)
+    {
+       if (isEnabled())
+       {
+          ListenerWrapper wrapper = getListenerWrapper(metadata, listener);
+          super.addNotificationListener(metadata, wrapper, filter, handback);
+       }
+       else
+       {
+          super.addNotificationListener(metadata, listener, filter, handback);
+       }
+    }
+ 
+    public void removeNotificationListener(MBeanMetaData metadata, NotificationListener listener) throws ListenerNotFoundException
+    {
+       if (isEnabled())
+       {
+          ListenerWrapper wrapper = getListenerWrapper(metadata, listener);
+          super.removeNotificationListener(metadata, wrapper);
+       }
+       else
+       {
+          super.removeNotificationListener(metadata, listener);
+       }
+    }
+ 
+    public void removeNotificationListener(MBeanMetaData metadata, NotificationListener listener, NotificationFilter filter, Object handback) throws ListenerNotFoundException
+    {
+       if (isEnabled())
+       {
+          ListenerWrapper wrapper = getListenerWrapper(metadata, listener);
+          super.removeNotificationListener(metadata, wrapper, filter, handback);
+       }
+       else
+       {
+          super.removeNotificationListener(metadata, listener, filter, handback);
+       }
+    }
+ 
     private static class ListenerWrapper implements NotificationListener
     {
***************
*** 89,133 ****
     }
  
!    public String getType()
     {
!       return "notificationlistener";
!    }
  
!    public void addNotificationListener(MBeanMetaData metadata, NotificationListener listener, NotificationFilter filter, Object handback)
!    {
!       if (isEnabled())
!       {
!          ListenerWrapper wrapper = new ListenerWrapper(listener, metadata.getObjectName());
!          super.addNotificationListener(metadata, wrapper, filter, handback);
!       }
!       else
        {
!          super.addNotificationListener(metadata, listener, filter, handback);
        }
-    }
  
!    public void removeNotificationListener(MBeanMetaData metadata, NotificationListener listener) throws ListenerNotFoundException
!    {
!       if (isEnabled())
!       {
!          ListenerWrapper wrapper = new ListenerWrapper(listener, metadata.getObjectName());
!          super.removeNotificationListener(metadata, wrapper);
!       }
!       else
        {
!          super.removeNotificationListener(metadata, listener);
!       }
!    }
  
!    public void removeNotificationListener(MBeanMetaData metadata, NotificationListener listener, NotificationFilter filter, Object handback) throws ListenerNotFoundException
!    {
!       if (isEnabled())
!       {
!          ListenerWrapper wrapper = new ListenerWrapper(listener, metadata.getObjectName());
!          super.removeNotificationListener(metadata, wrapper, filter, handback);
        }
!       else
        {
!          super.removeNotificationListener(metadata, listener, filter, handback);
        }
     }
--- 167,199 ----
     }
  
!    private static class ListenerWrapperKey
     {
!       private final NotificationListener listener;
!       private final Object mbean;
  
!       private ListenerWrapperKey(NotificationListener listener, Object mbean)
        {
!          this.listener = listener;
!          this.mbean = mbean;
        }
  
!       public boolean equals(Object obj)
        {
!          if (this == obj) return true;
!          if (!(obj instanceof ListenerWrapperKey)) return false;
  
!          ListenerWrapperKey other = (ListenerWrapperKey)obj;
! 
!          if (listener != other.listener) return false;
!          if (mbean != other.mbean) return false;
! 
!          return true;
        }
! 
!       public int hashCode()
        {
!          int result = listener.hashCode();
!          result = 29 * result + mbean.hashCode();
!          return result;
        }
     }



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click