Source for javax.management.MBeanServerDelegate

   1: /* MBeanServerDelegate.java -- The management server delegate.
   2:    Copyright (C) 2006 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: package javax.management;
  39: 
  40: import gnu.javax.management.ListenerData;
  41: import gnu.classpath.SystemProperties;
  42: 
  43: import java.net.InetAddress;
  44: import java.net.UnknownHostException;
  45: 
  46: import java.util.ArrayList;
  47: import java.util.Date;
  48: import java.util.Iterator;
  49: import java.util.List;
  50: 
  51: /**
  52:  * Provides an implementation of a delegate bean, which is associated
  53:  * with a management server.  The delegate bean is responsible
  54:  * for providing metadata about the server and handling the
  55:  * registration and deregistration notifications.
  56:  *
  57:  * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
  58:  * @since 1.5
  59:  */
  60: public class MBeanServerDelegate
  61:   implements MBeanServerDelegateMBean, NotificationEmitter
  62: {
  63: 
  64:   /**
  65:    * The identifier of the server associated with this delegate.
  66:    */
  67:   private String id;
  68: 
  69:   /**
  70:    * The listeners registered with the delegate.
  71:    */
  72:   private final List<ListenerData> listeners =
  73:     new ArrayList<ListenerData>();
  74: 
  75:   /**
  76:    * The sequence identifier used by the delegate.
  77:    */
  78:   private long seqNo;
  79: 
  80:   /**
  81:    * Default constructor which generates the id.
  82:    */
  83:   public MBeanServerDelegate()
  84:   {
  85:     String hostName;
  86:     try
  87:       {
  88:         hostName = InetAddress.getLocalHost().getHostName();
  89:       }
  90:     catch (UnknownHostException e)
  91:       {
  92:         hostName = "Unknown host";
  93:       }
  94:     id = hostName + "_" + new Date().getTime();
  95:   }
  96: 
  97:   /**
  98:    * Registers the specified listener as a new recipient of
  99:    * notifications from the delegate.  If non-null, the filter
 100:    * argument will be used to select which notifications are
 101:    * delivered.  The supplied object will also be passed to
 102:    * the recipient with each notification.  This should not
 103:    * be modified by the broadcaster, but instead should be
 104:    * passed unmodified to the listener.
 105:    *
 106:    * @param listener the new listener, who will receive
 107:    *                 notifications from this broadcasting bean.
 108:    * @param filter a filter to determine which notifications are
 109:    *               delivered to the listener, or <code>null</code>
 110:    *               if no filtering is required.
 111:    * @param passback an object to be passed to the listener with
 112:    *                 each notification.
 113:    * @throws IllegalArgumentException if <code>listener</code> is
 114:    *                                  <code>null</code>.
 115:    * @see #removeNotificationListener(NotificationListener)
 116:    */
 117:   public void addNotificationListener(NotificationListener listener,
 118:                                       NotificationFilter filter,
 119:                                       Object passback)
 120:     throws IllegalArgumentException
 121:   {
 122:     if (listener == null)
 123:       throw new IllegalArgumentException("A null listener was supplied.");
 124:     listeners.add(new ListenerData(listener, filter, passback));
 125:   }
 126: 
 127:   /**
 128:    * Returns the name of this Java Management eXtensions (JMX) implementation.
 129:    *
 130:    * @return the implementation name.
 131:    */
 132:   public String getImplementationName()
 133:   {
 134:     return "GNU JMX";
 135:   }
 136: 
 137:   /**
 138:    * Returns the vendor of this Java Management eXtensions (JMX) implementation.
 139:    *
 140:    * @return the implementation vendor.
 141:    */
 142:   public String getImplementationVendor()
 143:   {
 144:     return "The GNU Classpath Project";
 145:   }
 146: 
 147:   /**
 148:    * Returns the version of this Java Management eXtensions (JMX) implementation.
 149:    *
 150:    * @return the implementation version.
 151:    */
 152:   public String getImplementationVersion()
 153:   {
 154:     return SystemProperties.getProperty("gnu.classpath.version");
 155:   }
 156: 
 157:   /**
 158:    * Returns the unique identifier for this management server.
 159:    *
 160:    * @return the unique id of the server.
 161:    */
 162:   public String getMBeanServerId()
 163:   {
 164:     return id;
 165:   }
 166: 
 167:   /**
 168:    * Returns an array describing the notifications this
 169:    * bean may send to its registered listeners.  Ideally, this
 170:    * array should be complete, but in some cases, this may
 171:    * not be possible.  However, be aware that some listeners
 172:    * may expect this to be so.
 173:    *
 174:    * @return the array of possible notifications.
 175:    */
 176:   public MBeanNotificationInfo[] getNotificationInfo()
 177:   {
 178:     return new MBeanNotificationInfo[]
 179:       {
 180:         new MBeanNotificationInfo(new String[]
 181:           {
 182:             MBeanServerNotification.REGISTRATION_NOTIFICATION,
 183:             MBeanServerNotification.UNREGISTRATION_NOTIFICATION,
 184:           },
 185:                                   MBeanServerNotification.class.getName(),
 186:                                   "Server registration notifications")
 187:       };
 188:   }
 189: 
 190:   /**
 191:    * Returns the name of this Java Management eXtensions (JMX) specification.
 192:    *
 193:    * @return the specification name.
 194:    */
 195:   public String getSpecificationName()
 196:   {
 197:     return "JMX";
 198:   }
 199: 
 200: 
 201:   /**
 202:    * Returns the vendor of this Java Management eXtensions (JMX) specification.
 203:    *
 204:    * @return the specification vendor.
 205:    */
 206:   public String getSpecificationVendor()
 207:   {
 208:     return "Sun Microsystems";
 209:   }
 210: 
 211:   /**
 212:    * Returns the version of this Java Management eXtensions (JMX) specification.
 213:    *
 214:    * @return the specification version.
 215:    */
 216:   public String getSpecificationVersion()
 217:   {
 218:     return "1.2";
 219:   }
 220: 
 221:   /**
 222:    * Removes the specified listener from the list of recipients
 223:    * of notifications from this bean.  This includes all combinations
 224:    * of filters and passback objects registered for this listener.
 225:    * For more specific removal of listeners, see
 226:    * {@link #removeNotificationListener(NotificationListener,
 227:    * NotificationFilter, java.lang.Object)}
 228:    *
 229:    * @param listener the listener to remove.
 230:    * @throws ListenerNotFoundException if the specified listener
 231:    *                                   is not registered with this bean.
 232:    * @see #addNotificationListener(NotificationListener, NotificationFilter,
 233:    *                               java.lang.Object)
 234:    */
 235:   public void removeNotificationListener(NotificationListener listener)
 236:     throws ListenerNotFoundException
 237:   {
 238:     Iterator<ListenerData> it = listeners.iterator();
 239:     boolean foundOne = false;
 240:     while (it.hasNext())
 241:       {
 242:         if (it.next().getListener() == listener)
 243:           {
 244:             it.remove();
 245:             foundOne = true;
 246:           }
 247:       }
 248:     if (!foundOne)
 249:       throw new ListenerNotFoundException("The specified listener, " + listener +
 250:                                           "is not registered with this bean.");
 251:   }
 252: 
 253:   /**
 254:    * Removes the specified listener from the list of recipients
 255:    * of notifications from this delegate.  Only the first instance with
 256:    * the supplied filter and passback object is removed.
 257:    * <code>null</code> is used as a valid value for these parameters,
 258:    * rather than as a way to remove all registration instances for
 259:    * the specified listener; for this behaviour instead, see
 260:    * {@link #removeNotificationListener(NotificationListener)}.
 261:    *
 262:    * @param listener the listener to remove.
 263:    * @param filter the filter of the listener to remove.
 264:    * @param passback the passback object of the listener to remove.
 265:    * @throws ListenerNotFoundException if the specified listener
 266:    *                                   is not registered with this bean.
 267:    * @see #addNotificationListener(NotificationListener, NotificationFilter,
 268:    *                               java.lang.Object)
 269:    * @see #removeNotificationListener(NotificationListener)
 270:    */
 271:   public void removeNotificationListener(NotificationListener listener,
 272:                                          NotificationFilter filter,
 273:                                          Object passback)
 274:     throws ListenerNotFoundException
 275:   {
 276:     if (!(listeners.remove(new ListenerData(listener, filter, passback))))
 277:       {
 278:         throw new ListenerNotFoundException("The specified listener, " + listener +
 279:                                             " with filter " + filter +
 280:                                             "and passback " + passback +
 281:                                             ", is not registered with this bean.");
 282:       }
 283:   }
 284: 
 285:   /**
 286:    * Allows the server to use the delegate to send a notification.
 287:    * If the supplied notification has a sequence number <= 0, then
 288:    * it is replaced with the delegate's own sequence number.
 289:    *
 290:    * @param notification the notification to send.
 291:    */
 292:   public void sendNotification(Notification notification)
 293:   {
 294:     if (notification.getSequenceNumber() <= 0)
 295:       notification.setSequenceNumber(++seqNo);
 296:     for (ListenerData ldata : listeners)
 297:       {
 298:         NotificationFilter filter = ldata.getFilter();
 299:         if (filter == null || filter.isNotificationEnabled(notification))
 300:           ldata.getListener().handleNotification(notification, ldata.getPassback());
 301:       }
 302:   }
 303: 
 304: }