KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > mx > remoting > rmi > ClientNotifier


1 package org.jboss.mx.remoting.rmi;
2
3 import java.util.HashMap JavaDoc;
4 import java.util.Map JavaDoc;
5 import java.util.List JavaDoc;
6 import java.util.ArrayList JavaDoc;
7 import java.util.Set JavaDoc;
8 import java.util.Iterator JavaDoc;
9 import java.util.TimerTask JavaDoc;
10 import java.util.Timer JavaDoc;
11 import java.io.IOException JavaDoc;
12
13 import javax.management.ObjectName JavaDoc;
14 import javax.management.NotificationListener JavaDoc;
15 import javax.management.Notification JavaDoc;
16 import javax.management.NotificationFilter JavaDoc;
17 import javax.management.remote.rmi.RMIConnection JavaDoc;
18 import javax.management.remote.NotificationResult JavaDoc;
19 import javax.management.remote.TargetedNotification JavaDoc;
20
21 import org.jboss.logging.Logger;
22 import org.jboss.util.threadpool.BasicThreadPool;
23 import org.jboss.util.threadpool.BlockingMode;
24
25 import EDU.oswego.cs.dl.util.concurrent.ReaderPreferenceReadWriteLock;
26 import EDU.oswego.cs.dl.util.concurrent.SyncMap;
27
28 /**
29  * @author <a HREF="mailto:telrod@e2technologies.net">Tom Elrod</a>
30  */

31 /*
32  * The ClientNotifier is created within the RMIConnector but only used within the
33  * ClientMBeanServerConnection so that there is only one instance of the ClientNotifier
34  * per JMXConnector. This is because the user could get multiple ClientMBeanServerConnections
35  * (via RMIConnector::getMBeanServerConnection()), so don't want to create ClientNotifier within
36  * ClientMBeanServerConnections because would then multiple of the them to track and close when
37  * the connector itself is closed.
38  */

39 public class ClientNotifier extends TimerTask JavaDoc
40 {
41    private Map JavaDoc clientListeners = null;
42    private Timer JavaDoc fetchTimer = null;
43    private RMIConnection JavaDoc connection = null;
44
45    //TODO: -TME Need to make fetch timeout configurable (JBREM-151)
46
private long fetchTimeout = 1000;
47    private long clientSequenceNumber = -1;
48    private int maxNotifications = 10;
49
50    private BasicThreadPool notifierPool = null;
51    private int maxNumberThreads = 20;
52
53    private static final Logger log = Logger.getLogger(ClientNotifier.class);
54
55
56    public ClientNotifier(RMIConnection JavaDoc rmiConnection)
57    {
58       this.connection = rmiConnection;
59       clientListeners = new SyncMap(new HashMap JavaDoc(), new ReaderPreferenceReadWriteLock());
60       fetchTimer = new Timer JavaDoc(true);
61       //TODO: -TME Need to make the fetch period configurable (JBREM-151)
62
fetchTimer.schedule(this, 1000, 1000);
63
64       notifierPool = new BasicThreadPool("JBoss JMX Remoting client notifier");
65       notifierPool.setMaximumPoolSize(maxNumberThreads);
66       notifierPool.setBlockingMode(BlockingMode.WAIT);
67    }
68
69    /**
70     * The action to be performed by this timer task.
71     */

72    public void run()
73    {
74       try
75       {
76          NotificationResult JavaDoc result = connection.fetchNotifications(clientSequenceNumber, maxNotifications, fetchTimeout);
77          if(result != null)
78          {
79             clientSequenceNumber = result.getNextSequenceNumber();
80             TargetedNotification JavaDoc[] targetedNotifications = result.getTargetedNotifications();
81             if(targetedNotifications != null)
82             {
83                deliverNotifications(targetedNotifications);
84             }
85          }
86          else
87          {
88             log.error("Fetched notifications and result was null.");
89          }
90       }
91       catch(IOException JavaDoc e)
92       {
93          log.error("Error fetching notifications for sequence number " + clientSequenceNumber, e);
94       }
95    }
96
97    private void deliverNotifications(TargetedNotification JavaDoc[] targetedNotifications)
98    {
99       for(int x = 0; x < targetedNotifications.length; x++)
100       {
101          TargetedNotification JavaDoc targetedNotification = targetedNotifications[x];
102          Integer JavaDoc id = targetedNotification.getListenerID();
103          ClientListenerHolder holder = (ClientListenerHolder)clientListeners.get(id);
104          if(holder != null)
105          {
106             final Notification JavaDoc notification = targetedNotification.getNotification();
107             boolean deliverNotification = true;
108             if(holder.getFilterOnClient())
109             {
110                NotificationFilter JavaDoc filter = holder.getFilter();
111                if(!filter.isNotificationEnabled(notification))
112                {
113                   deliverNotification = false;
114                }
115             }
116             if(deliverNotification)
117             {
118                final NotificationListener JavaDoc listener = holder.getListener();
119                final Object JavaDoc handback = holder.getHandback();
120                Runnable JavaDoc notifyRun = new Runnable JavaDoc()
121                {
122                   public void run()
123                   {
124                      try
125                      {
126                         listener.handleNotification(notification, handback);
127                      }
128                      catch(Throwable JavaDoc e)
129                      {
130                         log.error("Error delivering notification to listener: " + listener, e);
131                      }
132                   }
133                };
134                notifierPool.run(notifyRun);
135             }
136          }
137       }
138    }
139
140    public boolean exists(ClientListenerHolder holder)
141    {
142       return clientListeners.containsValue(holder);
143    }
144
145
146    public void addNotificationListener(Integer JavaDoc listenerID, ClientListenerHolder holder)
147    {
148       clientListeners.put(listenerID, holder);
149    }
150
151    public Integer JavaDoc[] getListeners(ObjectName JavaDoc name, NotificationListener JavaDoc listener)
152    {
153       List JavaDoc idList = new ArrayList JavaDoc();
154       Set JavaDoc keys = clientListeners.keySet();
155       Iterator JavaDoc itr = keys.iterator();
156       while(itr.hasNext())
157       {
158          Integer JavaDoc id = (Integer JavaDoc)itr.next();
159          ClientListenerHolder holder = (ClientListenerHolder)clientListeners.get(id);
160          if(holder.getObjectName().equals(name) && holder.getListener().equals(listener))
161          {
162             idList.add(id);
163          }
164       }
165       Integer JavaDoc[] ids = new Integer JavaDoc[idList.size()];
166       ids = (Integer JavaDoc[])idList.toArray(ids);
167       return ids;
168    }
169
170    public void removeListeners(Integer JavaDoc[] ids)
171    {
172       for(int x = 0; x < ids.length; x++)
173       {
174          clientListeners.remove(ids[x]);
175       }
176    }
177
178    public Integer JavaDoc getListener(ClientListenerHolder clientListenerHolder)
179    {
180       Iterator JavaDoc itr = clientListeners.entrySet().iterator();
181       while(itr.hasNext())
182       {
183          Map.Entry JavaDoc value = (Map.Entry JavaDoc)itr.next();
184          if(value.getValue().equals(clientListenerHolder))
185          {
186             return (Integer JavaDoc)value.getKey();
187          }
188       }
189       return null;
190    }
191
192    public void close()
193    {
194       fetchTimer.cancel();
195    }
196 }
197
Popular Tags