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 listeners = new ArrayList();
  73: 
  74:   /**
  75:    * The sequence identifier used by the delegate.
  76:    */
  77:   private long seqNo;
  78: 
  79:   /**
  80:    * Default constructor which generates the id.
  81:    */
  82:   public MBeanServerDelegate()
  83:   {
  84:     String hostName;
  85:     try
  86:       {
  87:         hostName = InetAddress.getLocalHost().getHostName();
  88:       }
  89:     catch (UnknownHostException e)
  90:       {
  91:         hostName = "Unknown host";
  92:       }
  93:     id = hostName + "_" + new Date().getTime();
  94:   }
  95: 
  96:   /**
  97:    * Registers the specified listener as a new recipient of
  98:    * notifications from the delegate.  If non-null, the filter
  99:    * argument will be used to select which notifications are
 100:    * delivered.  The supplied object will also be passed to
 101:    * the recipient with each notification.  This should not
 102:    * be modified by the broadcaster, but instead should be
 103:    * passed unmodified to the listener.
 104:    *
 105:    * @param listener the new listener, who will receive
 106:    *                 notifications from this broadcasting bean.
 107:    * @param filter a filter to determine which notifications are
 108:    *               delivered to the listener, or <code>null</code>
 109:    *               if no filtering is required.
 110:    * @param passback an object to be passed to the listener with
 111:    *                 each notification.
 112:    * @throws IllegalArgumentException if <code>listener</code> is
 113:    *                                  <code>null</code>.
 114:    * @see #removeNotificationListener(NotificationListener)
 115:    */
 116:   public void addNotificationListener(NotificationListener listener,
 117:                       NotificationFilter filter,
 118:                       Object passback)
 119:     throws IllegalArgumentException
 120:   {
 121:     if (listener == null)
 122:       throw new IllegalArgumentException("A null listener was supplied.");
 123:     listeners.add(new ListenerData(listener, filter, passback));
 124:   }
 125: 
 126:   /**
 127:    * Returns the name of this Java Management eXtensions (JMX) implementation.
 128:    *
 129:    * @return the implementation name.
 130:    */
 131:   public String getImplementationName()
 132:   {
 133:     return "GNU JMX";
 134:   }
 135: 
 136:   /**
 137:    * Returns the vendor of this Java Management eXtensions (JMX) implementation.
 138:    *
 139:    * @return the implementation vendor.
 140:    */
 141:   public String getImplementationVendor()
 142:   {
 143:     return "The GNU Classpath Project";
 144:   }
 145: 
 146:   /**
 147:    * Returns the version of this Java Management eXtensions (JMX) implementation.
 148:    *
 149:    * @return the implementation version.
 150:    */
 151:   public String getImplementationVersion()
 152:   {
 153:     return SystemProperties.getProperty("gnu.classpath.version");
 154:   }
 155: 
 156:   /**
 157:    * Returns the unique identifier for this management server.
 158:    *
 159:    * @return the unique id of the server.
 160:    */
 161:   public String getMBeanServerId()
 162:   {
 163:     return id;
 164:   }
 165: 
 166:   /**
 167:    * Returns an array describing the notifications this
 168:    * bean may send to its registered listeners.  Ideally, this
 169:    * array should be complete, but in some cases, this may
 170:    * not be possible.  However, be aware that some listeners
 171:    * may expect this to be so.
 172:    *
 173:    * @return the array of possible notifications.
 174:    */
 175:   public MBeanNotificationInfo[] getNotificationInfo()
 176:   {
 177:     return new MBeanNotificationInfo[] 
 178:       {
 179:     new MBeanNotificationInfo(new String[]
 180:       {
 181:         MBeanServerNotification.REGISTRATION_NOTIFICATION,
 182:         MBeanServerNotification.UNREGISTRATION_NOTIFICATION,
 183:       },
 184:                   MBeanServerNotification.class.getName(),
 185:                   "Server registration notifications")
 186:       };
 187:   }
 188: 
 189:   /**
 190:    * Returns the name of this Java Management eXtensions (JMX) specification.
 191:    *
 192:    * @return the specification name.
 193:    */
 194:   public String getSpecificationName()
 195:   {
 196:     return "JMX";
 197:   }
 198: 
 199: 
 200:   /**
 201:    * Returns the vendor of this Java Management eXtensions (JMX) specification.
 202:    *
 203:    * @return the specification vendor.
 204:    */
 205:   public String getSpecificationVendor()
 206:   {
 207:     return "Sun Microsystems";
 208:   }
 209: 
 210:   /**
 211:    * Returns the version of this Java Management eXtensions (JMX) specification.
 212:    *
 213:    * @return the specification version.
 214:    */
 215:   public String getSpecificationVersion()
 216:   {
 217:     return "1.2";
 218:   }
 219: 
 220:   /**
 221:    * Removes the specified listener from the list of recipients
 222:    * of notifications from this bean.  This includes all combinations
 223:    * of filters and passback objects registered for this listener.
 224:    * For more specific removal of listeners, see
 225:    * {@link #removeNotificationListener(NotificationListener,
 226:    * NotificationFilter, java.lang.Object)}
 227:    *
 228:    * @param listener the listener to remove.
 229:    * @throws ListenerNotFoundException if the specified listener
 230:    *                                   is not registered with this bean.
 231:    * @see #addNotificationListener(NotificationListener, NotificationFilter,
 232:    *                               java.lang.Object)
 233:    */
 234:   public void removeNotificationListener(NotificationListener listener)
 235:     throws ListenerNotFoundException
 236:   {
 237:     Iterator it = listeners.iterator();
 238:     boolean foundOne = false;
 239:     while (it.hasNext())
 240:       {
 241:     ListenerData data = (ListenerData) it.next();
 242:     if (data.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:     Iterator it = listeners.iterator();
 297:     while (it.hasNext())
 298:       {
 299:     ListenerData ldata = (ListenerData) it.next();
 300:     NotificationFilter filter = ldata.getFilter();
 301:     if (filter == null || filter.isNotificationEnabled(notification))
 302:       ldata.getListener().handleNotification(notification, ldata.getPassback());
 303:       }
 304:   }
 305: 
 306: }