0001 /*
0002 * Portions Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
0003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004 *
0005 * This code is free software; you can redistribute it and/or modify it
0006 * under the terms of the GNU General Public License version 2 only, as
0007 * published by the Free Software Foundation. Sun designates this
0008 * particular file as subject to the "Classpath" exception as provided
0009 * by Sun in the LICENSE file that accompanied this code.
0010 *
0011 * This code is distributed in the hope that it will be useful, but WITHOUT
0012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014 * version 2 for more details (a copy is included in the LICENSE file that
0015 * accompanied this code).
0016 *
0017 * You should have received a copy of the GNU General Public License version
0018 * 2 along with this work; if not, write to the Free Software Foundation,
0019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020 *
0021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022 * CA 95054 USA or visit www.sun.com if you need additional information or
0023 * have any questions.
0024 */
0025 /*
0026 * @(#)author IBM Corp.
0027 *
0028 * Copyright IBM Corp. 1999-2000. All rights reserved.
0029 */
0030
0031 package javax.management.modelmbean;
0032
0033 import static com.sun.jmx.defaults.JmxProperties.MODELMBEAN_LOGGER;
0034 import com.sun.jmx.mbeanserver.GetPropertyAction;
0035
0036 import java.io.IOException;
0037 import java.io.ObjectInputStream;
0038 import java.io.ObjectOutputStream;
0039 import java.io.ObjectStreamField;
0040 import java.security.AccessController;
0041 import java.util.logging.Level;
0042
0043 import javax.management.Descriptor;
0044 import javax.management.MBeanAttributeInfo;
0045 import javax.management.MBeanConstructorInfo;
0046 import javax.management.MBeanException;
0047 import javax.management.MBeanInfo;
0048 import javax.management.MBeanNotificationInfo;
0049 import javax.management.MBeanOperationInfo;
0050 import javax.management.RuntimeOperationsException;
0051
0052 /**
0053 * This class represents the meta data for ModelMBeans. Descriptors have been
0054 * added on the meta data objects.
0055 * <P>
0056 * Java resources wishing to be manageable instantiate the ModelMBean using the
0057 * MBeanServer's createMBean method. The resource then sets the ModelMBeanInfo
0058 * and Descriptors for the ModelMBean instance. The attributes and operations
0059 * exposed via the ModelMBeanInfo for the ModelMBean are accessible
0060 * from MBeans, connectors/adaptors like other MBeans. Through the Descriptors,
0061 * values and methods in the managed application can be defined and mapped to
0062 * attributes and operations of the ModelMBean.
0063 * This mapping can be defined during development in a file or dynamically and
0064 * programmatically at runtime.
0065 * <P>
0066 * Every ModelMBean which is instantiated in the MBeanServer becomes manageable:
0067 * its attributes and operations
0068 * become remotely accessible through the connectors/adaptors connected to that
0069 * MBeanServer.
0070 * A Java object cannot be registered in the MBeanServer unless it is a JMX
0071 * compliant MBean.
0072 * By instantiating a ModelMBean, resources are guaranteed that the MBean is
0073 * valid.
0074 *
0075 * MBeanException and RuntimeOperationsException must be thrown on every public
0076 * method. This allows for wrapping exceptions from distributed
0077 * communications (RMI, EJB, etc.)
0078 *
0079 * <p>The <b>serialVersionUID</b> of this class is
0080 * <code>-1935722590756516193L</code>.
0081 *
0082 * @since 1.5
0083 */
0084 @SuppressWarnings("serial")
0085 public class ModelMBeanInfoSupport extends MBeanInfo implements
0086 ModelMBeanInfo {
0087
0088 // Serialization compatibility stuff:
0089 // Two serial forms are supported in this class. The selected form depends
0090 // on system property "jmx.serial.form":
0091 // - "1.0" for JMX 1.0
0092 // - any other value for JMX 1.1 and higher
0093 //
0094 // Serial version for old serial form
0095 private static final long oldSerialVersionUID = -3944083498453227709L;
0096 //
0097 // Serial version for new serial form
0098 private static final long newSerialVersionUID = -1935722590756516193L;
0099 //
0100 // Serializable fields in old serial form
0101 private static final ObjectStreamField[] oldSerialPersistentFields = {
0102 new ObjectStreamField("modelMBeanDescriptor",
0103 Descriptor.class),
0104 new ObjectStreamField("mmbAttributes",
0105 MBeanAttributeInfo[].class),
0106 new ObjectStreamField("mmbConstructors",
0107 MBeanConstructorInfo[].class),
0108 new ObjectStreamField("mmbNotifications",
0109 MBeanNotificationInfo[].class),
0110 new ObjectStreamField("mmbOperations",
0111 MBeanOperationInfo[].class),
0112 new ObjectStreamField("currClass", String.class) };
0113 //
0114 // Serializable fields in new serial form
0115 private static final ObjectStreamField[] newSerialPersistentFields = {
0116 new ObjectStreamField("modelMBeanDescriptor",
0117 Descriptor.class),
0118 new ObjectStreamField("modelMBeanAttributes",
0119 MBeanAttributeInfo[].class),
0120 new ObjectStreamField("modelMBeanConstructors",
0121 MBeanConstructorInfo[].class),
0122 new ObjectStreamField("modelMBeanNotifications",
0123 MBeanNotificationInfo[].class),
0124 new ObjectStreamField("modelMBeanOperations",
0125 MBeanOperationInfo[].class) };
0126 //
0127 // Actual serial version and serial form
0128 private static final long serialVersionUID;
0129 /**
0130 * @serialField modelMBeanDescriptor Descriptor The descriptor containing
0131 * MBean wide policy
0132 * @serialField modelMBeanAttributes ModelMBeanAttributeInfo[] The array of
0133 * {@link ModelMBeanAttributeInfo} objects which
0134 * have descriptors
0135 * @serialField modelMBeanConstructors MBeanConstructorInfo[] The array of
0136 * {@link ModelMBeanConstructorInfo} objects which
0137 * have descriptors
0138 * @serialField modelMBeanNotifications MBeanNotificationInfo[] The array of
0139 * {@link ModelMBeanNotificationInfo} objects which
0140 * have descriptors
0141 * @serialField modelMBeanOperations MBeanOperationInfo[] The array of
0142 * {@link ModelMBeanOperationInfo} objects which
0143 * have descriptors
0144 */
0145 private static final ObjectStreamField[] serialPersistentFields;
0146 private static boolean compat = false;
0147 static {
0148 try {
0149 GetPropertyAction act = new GetPropertyAction(
0150 "jmx.serial.form");
0151 String form = AccessController.doPrivileged(act);
0152 compat = (form != null && form.equals("1.0"));
0153 } catch (Exception e) {
0154 // OK: No compat with 1.0
0155 }
0156 if (compat) {
0157 serialPersistentFields = oldSerialPersistentFields;
0158 serialVersionUID = oldSerialVersionUID;
0159 } else {
0160 serialPersistentFields = newSerialPersistentFields;
0161 serialVersionUID = newSerialVersionUID;
0162 }
0163 }
0164 //
0165 // END Serialization compatibility stuff
0166
0167 /**
0168 * @serial The descriptor containing MBean wide policy
0169 */
0170 private Descriptor modelMBeanDescriptor = null;
0171
0172 /* The following fields always have the same values as the
0173 fields inherited from MBeanInfo and are retained only for
0174 compatibility. By rewriting the serialization code we could
0175 get rid of them.
0176
0177 These fields can't be final because they are assigned to by
0178 readObject(). */
0179
0180 /**
0181 * @serial The array of {@link ModelMBeanAttributeInfo} objects which
0182 * have descriptors
0183 */
0184 private MBeanAttributeInfo[] modelMBeanAttributes;
0185
0186 /**
0187 * @serial The array of {@link ModelMBeanConstructorInfo} objects which
0188 * have descriptors
0189 */
0190 private MBeanConstructorInfo[] modelMBeanConstructors;
0191
0192 /**
0193 * @serial The array of {@link ModelMBeanNotificationInfo} objects which
0194 * have descriptors
0195 */
0196 private MBeanNotificationInfo[] modelMBeanNotifications;
0197
0198 /**
0199 * @serial The array of {@link ModelMBeanOperationInfo} objects which
0200 * have descriptors
0201 */
0202 private MBeanOperationInfo[] modelMBeanOperations;
0203
0204 private static final String ATTR = "attribute";
0205 private static final String OPER = "operation";
0206 private static final String NOTF = "notification";
0207 private static final String CONS = "constructor";
0208 private static final String MMB = "mbean";
0209 private static final String ALL = "all";
0210 private static final String currClass = "ModelMBeanInfoSupport";
0211
0212 /**
0213 * Constructs a ModelMBeanInfoSupport which is a duplicate of the given
0214 * ModelMBeanInfo. The returned object is a shallow copy of the given
0215 * object. Neither the Descriptor nor the contained arrays
0216 * ({@code ModelMBeanAttributeInfo[]} etc) are cloned. This method is
0217 * chiefly of interest to modify the Descriptor of the returned instance
0218 * via {@link #setDescriptor setDescriptor} without affecting the
0219 * Descriptor of the original object.
0220 *
0221 * @param mbi the ModelMBeanInfo instance from which the ModelMBeanInfo
0222 * being created is initialized.
0223 */
0224 public ModelMBeanInfoSupport(ModelMBeanInfo mbi) {
0225 super (mbi.getClassName(), mbi.getDescription(), mbi
0226 .getAttributes(), mbi.getConstructors(), mbi
0227 .getOperations(), mbi.getNotifications());
0228
0229 modelMBeanAttributes = mbi.getAttributes();
0230 modelMBeanConstructors = mbi.getConstructors();
0231 modelMBeanOperations = mbi.getOperations();
0232 modelMBeanNotifications = mbi.getNotifications();
0233
0234 try {
0235 Descriptor mbeandescriptor = mbi.getMBeanDescriptor();
0236 modelMBeanDescriptor = validDescriptor(mbeandescriptor);
0237 } catch (MBeanException mbe) {
0238 modelMBeanDescriptor = validDescriptor(null);
0239 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0240 MODELMBEAN_LOGGER.logp(Level.FINER,
0241 ModelMBeanInfoSupport.class.getName(),
0242 "ModelMBeanInfo(ModelMBeanInfo)",
0243 "Could not get a valid modelMBeanDescriptor, "
0244 + "setting a default Descriptor");
0245 }
0246 }
0247
0248 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0249 MODELMBEAN_LOGGER.logp(Level.FINER,
0250 ModelMBeanInfoSupport.class.getName(),
0251 "ModelMBeanInfo(ModelMBeanInfo)", "Exit");
0252 }
0253 }
0254
0255 /**
0256 * Creates a ModelMBeanInfoSupport with the provided information,
0257 * but the descriptor is a default.
0258 * The default descriptor is: name=className, descriptorType="mbean",
0259 * displayName=className, persistPolicy="never", log="F", visibility="1"
0260 *
0261 * @param className classname of the MBean
0262 * @param description human readable description of the
0263 * ModelMBean
0264 * @param attributes array of ModelMBeanAttributeInfo objects
0265 * which have descriptors
0266 * @param constructors array of ModelMBeanConstructorInfo
0267 * objects which have descriptors
0268 * @param operations array of ModelMBeanOperationInfo objects
0269 * which have descriptors
0270 * @param notifications array of ModelMBeanNotificationInfo
0271 * objects which have descriptors
0272 */
0273 public ModelMBeanInfoSupport(String className, String description,
0274 ModelMBeanAttributeInfo[] attributes,
0275 ModelMBeanConstructorInfo[] constructors,
0276 ModelMBeanOperationInfo[] operations,
0277 ModelMBeanNotificationInfo[] notifications) {
0278 this (className, description, attributes, constructors,
0279 operations, notifications, null);
0280 }
0281
0282 /**
0283 * Creates a ModelMBeanInfoSupport with the provided information
0284 * and the descriptor given in parameter.
0285 *
0286 * @param className classname of the MBean
0287 * @param description human readable description of the
0288 * ModelMBean
0289 * @param attributes array of ModelMBeanAttributeInfo objects
0290 * which have descriptors
0291 * @param constructors array of ModelMBeanConstructorInfo
0292 * objects which have descriptor
0293 * @param operations array of ModelMBeanOperationInfo objects
0294 * which have descriptor
0295 * @param notifications array of ModelMBeanNotificationInfo
0296 * objects which have descriptor
0297 * @param mbeandescriptor descriptor to be used as the
0298 * MBeanDescriptor containing MBean wide policy. If the
0299 * descriptor is null, a default descriptor will be constructed.
0300 * The default descriptor is:
0301 * name=className, descriptorType="mbean", displayName=className,
0302 * persistPolicy="never", log="F", visibility="1". If the descriptor
0303 * does not contain all of these fields, the missing ones are
0304 * added with these default values.
0305 *
0306 * @exception RuntimeOperationsException Wraps an
0307 * IllegalArgumentException for invalid descriptor passed in
0308 * parameter. (see {@link #getMBeanDescriptor
0309 * getMBeanDescriptor} for the definition of a valid MBean
0310 * descriptor.)
0311 */
0312
0313 public ModelMBeanInfoSupport(String className, String description,
0314 ModelMBeanAttributeInfo[] attributes,
0315 ModelMBeanConstructorInfo[] constructors,
0316 ModelMBeanOperationInfo[] operations,
0317 ModelMBeanNotificationInfo[] notifications,
0318 Descriptor mbeandescriptor) {
0319 super (className, description, (attributes != null) ? attributes
0320 : NO_ATTRIBUTES, (constructors != null) ? constructors
0321 : NO_CONSTRUCTORS, (operations != null) ? operations
0322 : NO_OPERATIONS,
0323 (notifications != null) ? notifications
0324 : NO_NOTIFICATIONS);
0325 /* The values saved here are possibly null, but we
0326 check this everywhere they are referenced. If at
0327 some stage we replace null with an empty array
0328 here, as we do in the superclass constructor
0329 parameters, then we must also do this in
0330 readObject(). */
0331 modelMBeanAttributes = attributes;
0332 modelMBeanConstructors = constructors;
0333 modelMBeanOperations = operations;
0334 modelMBeanNotifications = notifications;
0335 modelMBeanDescriptor = validDescriptor(mbeandescriptor);
0336 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0337 MODELMBEAN_LOGGER
0338 .logp(
0339 Level.FINER,
0340 ModelMBeanInfoSupport.class.getName(),
0341 "ModelMBeanInfoSupport(String,String,ModelMBeanAttributeInfo[],"
0342 + "ModelMBeanConstructorInfo[],ModelMBeanOperationInfo[],"
0343 + "ModelMBeanNotificationInfo[],Descriptor)",
0344 "Exit");
0345 }
0346 }
0347
0348 private static final ModelMBeanAttributeInfo[] NO_ATTRIBUTES = new ModelMBeanAttributeInfo[0];
0349 private static final ModelMBeanConstructorInfo[] NO_CONSTRUCTORS = new ModelMBeanConstructorInfo[0];
0350 private static final ModelMBeanNotificationInfo[] NO_NOTIFICATIONS = new ModelMBeanNotificationInfo[0];
0351 private static final ModelMBeanOperationInfo[] NO_OPERATIONS = new ModelMBeanOperationInfo[0];
0352
0353 // Java doc inherited from MOdelMBeanInfo interface
0354
0355 /**
0356 * Returns a shallow clone of this instance. Neither the Descriptor nor
0357 * the contained arrays ({@code ModelMBeanAttributeInfo[]} etc) are
0358 * cloned. This method is chiefly of interest to modify the Descriptor
0359 * of the clone via {@link #setDescriptor setDescriptor} without affecting
0360 * the Descriptor of the original object.
0361 *
0362 * @return a shallow clone of this instance.
0363 */
0364 public Object clone() {
0365 return (new ModelMBeanInfoSupport(this ));
0366 }
0367
0368 public Descriptor[] getDescriptors(String inDescriptorType)
0369 throws MBeanException, RuntimeOperationsException {
0370 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0371 MODELMBEAN_LOGGER.logp(Level.FINER,
0372 ModelMBeanInfoSupport.class.getName(),
0373 "getDescriptors(String)", "Entry");
0374 }
0375
0376 if ((inDescriptorType == null) || (inDescriptorType.isEmpty())) {
0377 inDescriptorType = "all";
0378 }
0379
0380 // if no descriptors of that type, will return empty array
0381 //
0382 final Descriptor[] retList;
0383
0384 if (inDescriptorType.equalsIgnoreCase(MMB)) {
0385 retList = new Descriptor[] { modelMBeanDescriptor };
0386 } else if (inDescriptorType.equalsIgnoreCase(ATTR)) {
0387 final MBeanAttributeInfo[] attrList = modelMBeanAttributes;
0388 int numAttrs = 0;
0389 if (attrList != null)
0390 numAttrs = attrList.length;
0391
0392 retList = new Descriptor[numAttrs];
0393 for (int i = 0; i < numAttrs; i++) {
0394 retList[i] = (((ModelMBeanAttributeInfo) attrList[i])
0395 .getDescriptor());
0396 }
0397 } else if (inDescriptorType.equalsIgnoreCase(OPER)) {
0398 final MBeanOperationInfo[] operList = modelMBeanOperations;
0399 int numOpers = 0;
0400 if (operList != null)
0401 numOpers = operList.length;
0402
0403 retList = new Descriptor[numOpers];
0404 for (int i = 0; i < numOpers; i++) {
0405 retList[i] = (((ModelMBeanOperationInfo) operList[i])
0406 .getDescriptor());
0407 }
0408 } else if (inDescriptorType.equalsIgnoreCase(CONS)) {
0409 final MBeanConstructorInfo[] consList = modelMBeanConstructors;
0410 int numCons = 0;
0411 if (consList != null)
0412 numCons = consList.length;
0413
0414 retList = new Descriptor[numCons];
0415 for (int i = 0; i < numCons; i++) {
0416 retList[i] = (((ModelMBeanConstructorInfo) consList[i])
0417 .getDescriptor());
0418 }
0419 } else if (inDescriptorType.equalsIgnoreCase(NOTF)) {
0420 final MBeanNotificationInfo[] notifList = modelMBeanNotifications;
0421 int numNotifs = 0;
0422 if (notifList != null)
0423 numNotifs = notifList.length;
0424
0425 retList = new Descriptor[numNotifs];
0426 for (int i = 0; i < numNotifs; i++) {
0427 retList[i] = (((ModelMBeanNotificationInfo) notifList[i])
0428 .getDescriptor());
0429 }
0430 } else if (inDescriptorType.equalsIgnoreCase(ALL)) {
0431
0432 final MBeanAttributeInfo[] attrList = modelMBeanAttributes;
0433 int numAttrs = 0;
0434 if (attrList != null)
0435 numAttrs = attrList.length;
0436
0437 final MBeanOperationInfo[] operList = modelMBeanOperations;
0438 int numOpers = 0;
0439 if (operList != null)
0440 numOpers = operList.length;
0441
0442 final MBeanConstructorInfo[] consList = modelMBeanConstructors;
0443 int numCons = 0;
0444 if (consList != null)
0445 numCons = consList.length;
0446
0447 final MBeanNotificationInfo[] notifList = modelMBeanNotifications;
0448 int numNotifs = 0;
0449 if (notifList != null)
0450 numNotifs = notifList.length;
0451
0452 int count = numAttrs + numCons + numOpers + numNotifs + 1;
0453 retList = new Descriptor[count];
0454
0455 retList[count - 1] = modelMBeanDescriptor;
0456
0457 int j = 0;
0458 for (int i = 0; i < numAttrs; i++) {
0459 retList[j] = (((ModelMBeanAttributeInfo) attrList[i])
0460 .getDescriptor());
0461 j++;
0462 }
0463 for (int i = 0; i < numCons; i++) {
0464 retList[j] = (((ModelMBeanConstructorInfo) consList[i])
0465 .getDescriptor());
0466 j++;
0467 }
0468 for (int i = 0; i < numOpers; i++) {
0469 retList[j] = (((ModelMBeanOperationInfo) operList[i])
0470 .getDescriptor());
0471 j++;
0472 }
0473 for (int i = 0; i < numNotifs; i++) {
0474 retList[j] = (((ModelMBeanNotificationInfo) notifList[i])
0475 .getDescriptor());
0476 j++;
0477 }
0478 } else {
0479 final IllegalArgumentException iae = new IllegalArgumentException(
0480 "Descriptor Type is invalid");
0481 final String msg = "Exception occurred trying to find"
0482 + " the descriptors of the MBean";
0483 throw new RuntimeOperationsException(iae, msg);
0484 }
0485 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0486 MODELMBEAN_LOGGER.logp(Level.FINER,
0487 ModelMBeanInfoSupport.class.getName(),
0488 "getDescriptors(String)", "Exit");
0489 }
0490
0491 return retList;
0492 }
0493
0494 public void setDescriptors(Descriptor[] inDescriptors)
0495 throws MBeanException, RuntimeOperationsException {
0496 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0497 MODELMBEAN_LOGGER.logp(Level.FINER,
0498 ModelMBeanInfoSupport.class.getName(),
0499 "setDescriptors(Descriptor[])", "Entry");
0500 }
0501 if (inDescriptors == null) {
0502 // throw RuntimeOperationsException - invalid descriptor
0503 throw new RuntimeOperationsException(
0504 new IllegalArgumentException(
0505 "Descriptor list is invalid"),
0506 "Exception occurred trying to set the descriptors "
0507 + "of the MBeanInfo");
0508 }
0509 if (inDescriptors.length == 0) { // empty list, no-op
0510 return;
0511 }
0512 for (int j = 0; j < inDescriptors.length; j++) {
0513 setDescriptor(inDescriptors[j], null);
0514 }
0515 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0516 MODELMBEAN_LOGGER.logp(Level.FINER,
0517 ModelMBeanInfoSupport.class.getName(),
0518 "setDescriptors(Descriptor[])", "Exit");
0519 }
0520
0521 }
0522
0523 /**
0524 * Returns a Descriptor requested by name.
0525 *
0526 * @param inDescriptorName The name of the descriptor.
0527 *
0528 * @return Descriptor containing a descriptor for the ModelMBean with the
0529 * same name. If no descriptor is found, null is returned.
0530 *
0531 * @exception MBeanException Wraps a distributed communication Exception.
0532 * @exception RuntimeOperationsException Wraps an IllegalArgumentException
0533 * for null name.
0534 *
0535 * @see #setDescriptor
0536 */
0537
0538 public Descriptor getDescriptor(String inDescriptorName)
0539 throws MBeanException, RuntimeOperationsException {
0540 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0541 MODELMBEAN_LOGGER.logp(Level.FINER,
0542 ModelMBeanInfoSupport.class.getName(),
0543 "getDescriptor(String)", "Entry");
0544 }
0545 return (getDescriptor(inDescriptorName, null));
0546 }
0547
0548 public Descriptor getDescriptor(String inDescriptorName,
0549 String inDescriptorType) throws MBeanException,
0550 RuntimeOperationsException {
0551 if (inDescriptorName == null) {
0552 // throw RuntimeOperationsException - invalid descriptor
0553 throw new RuntimeOperationsException(
0554 new IllegalArgumentException(
0555 "Descriptor is invalid"),
0556 "Exception occurred trying to set the descriptors of "
0557 + "the MBeanInfo");
0558 }
0559
0560 if (MMB.equalsIgnoreCase(inDescriptorType)) {
0561 return (Descriptor) modelMBeanDescriptor.clone();
0562 }
0563
0564 /* The logic here is a bit convoluted, because we are
0565 dealing with two possible cases, depending on whether
0566 inDescriptorType is null. If it's not null, then only
0567 one of the following ifs will run, and it will either
0568 return a descriptor or null. If inDescriptorType is
0569 null, then all of the following ifs will run until one
0570 of them finds a descriptor. */
0571 if (ATTR.equalsIgnoreCase(inDescriptorType)
0572 || inDescriptorType == null) {
0573 ModelMBeanAttributeInfo attr = getAttribute(inDescriptorName);
0574 if (attr != null)
0575 return attr.getDescriptor();
0576 if (inDescriptorType != null)
0577 return null;
0578 }
0579 if (OPER.equalsIgnoreCase(inDescriptorType)
0580 || inDescriptorType == null) {
0581 ModelMBeanOperationInfo oper = getOperation(inDescriptorName);
0582 if (oper != null)
0583 return oper.getDescriptor();
0584 if (inDescriptorType != null)
0585 return null;
0586 }
0587 if (CONS.equalsIgnoreCase(inDescriptorType)
0588 || inDescriptorType == null) {
0589 ModelMBeanConstructorInfo oper = getConstructor(inDescriptorName);
0590 if (oper != null)
0591 return oper.getDescriptor();
0592 if (inDescriptorType != null)
0593 return null;
0594 }
0595 if (NOTF.equalsIgnoreCase(inDescriptorType)
0596 || inDescriptorType == null) {
0597 ModelMBeanNotificationInfo notif = getNotification(inDescriptorName);
0598 if (notif != null)
0599 return notif.getDescriptor();
0600 if (inDescriptorType != null)
0601 return null;
0602 }
0603 if (inDescriptorType == null)
0604 return null;
0605 throw new RuntimeOperationsException(
0606 new IllegalArgumentException(
0607 "Descriptor Type is invalid"),
0608 "Exception occurred trying to find the descriptors of the MBean");
0609
0610 }
0611
0612 public void setDescriptor(Descriptor inDescriptor,
0613 String inDescriptorType) throws MBeanException,
0614 RuntimeOperationsException {
0615 final String excMsg = "Exception occurred trying to set the descriptors of the MBean";
0616 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0617 MODELMBEAN_LOGGER.logp(Level.FINER,
0618 ModelMBeanInfoSupport.class.getName(),
0619 "setDescriptor(Descriptor,String)", "Entry");
0620 }
0621
0622 if (inDescriptor == null) {
0623 inDescriptor = new DescriptorSupport();
0624 }
0625
0626 if ((inDescriptorType == null) || (inDescriptorType.isEmpty())) {
0627 inDescriptorType = (String) inDescriptor
0628 .getFieldValue("descriptorType");
0629
0630 if (inDescriptorType == null) {
0631 MODELMBEAN_LOGGER.logp(Level.FINER,
0632 ModelMBeanInfoSupport.class.getName(),
0633 "setDescriptor(Descriptor,String)",
0634 "descriptorType null in both String parameter and Descriptor, defaulting to "
0635 + MMB);
0636 inDescriptorType = MMB;
0637 }
0638 }
0639
0640 String inDescriptorName = (String) inDescriptor
0641 .getFieldValue("name");
0642 if (inDescriptorName == null) {
0643 MODELMBEAN_LOGGER.logp(Level.FINER,
0644 ModelMBeanInfoSupport.class.getName(),
0645 "setDescriptor(Descriptor,String)",
0646 "descriptor name null, defaulting to "
0647 + this .getClassName());
0648 inDescriptorName = this .getClassName();
0649 }
0650 boolean found = false;
0651 if (inDescriptorType.equalsIgnoreCase(MMB)) {
0652 setMBeanDescriptor(inDescriptor);
0653 found = true;
0654 } else if (inDescriptorType.equalsIgnoreCase(ATTR)) {
0655 MBeanAttributeInfo[] attrList = modelMBeanAttributes;
0656 int numAttrs = 0;
0657 if (attrList != null)
0658 numAttrs = attrList.length;
0659
0660 for (int i = 0; i < numAttrs; i++) {
0661 if (inDescriptorName.equals(attrList[i].getName())) {
0662 found = true;
0663 ModelMBeanAttributeInfo mmbai = (ModelMBeanAttributeInfo) attrList[i];
0664 mmbai.setDescriptor(inDescriptor);
0665 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0666 StringBuilder strb = new StringBuilder()
0667 .append("Setting descriptor to ")
0668 .append(inDescriptor)
0669 .append(
0670 "\t\n local: AttributeInfo descriptor is ")
0671 .append(mmbai.getDescriptor())
0672 .append(
0673 "\t\n modelMBeanInfo: AttributeInfo descriptor is ")
0674 .append(
0675 this .getDescriptor(
0676 inDescriptorName,
0677 "attribute"));
0678 MODELMBEAN_LOGGER.logp(Level.FINER,
0679 ModelMBeanInfoSupport.class.getName(),
0680 "setDescriptor(Descriptor,String)",
0681 strb.toString());
0682 }
0683 }
0684 }
0685 } else if (inDescriptorType.equalsIgnoreCase(OPER)) {
0686 MBeanOperationInfo[] operList = modelMBeanOperations;
0687 int numOpers = 0;
0688 if (operList != null)
0689 numOpers = operList.length;
0690
0691 for (int i = 0; i < numOpers; i++) {
0692 if (inDescriptorName.equals(operList[i].getName())) {
0693 found = true;
0694 ModelMBeanOperationInfo mmboi = (ModelMBeanOperationInfo) operList[i];
0695 mmboi.setDescriptor(inDescriptor);
0696 }
0697 }
0698 } else if (inDescriptorType.equalsIgnoreCase(CONS)) {
0699 MBeanConstructorInfo[] consList = modelMBeanConstructors;
0700 int numCons = 0;
0701 if (consList != null)
0702 numCons = consList.length;
0703
0704 for (int i = 0; i < numCons; i++) {
0705 if (inDescriptorName.equals(consList[i].getName())) {
0706 found = true;
0707 ModelMBeanConstructorInfo mmbci = (ModelMBeanConstructorInfo) consList[i];
0708 mmbci.setDescriptor(inDescriptor);
0709 }
0710 }
0711 } else if (inDescriptorType.equalsIgnoreCase(NOTF)) {
0712 MBeanNotificationInfo[] notifList = modelMBeanNotifications;
0713 int numNotifs = 0;
0714 if (notifList != null)
0715 numNotifs = notifList.length;
0716
0717 for (int i = 0; i < numNotifs; i++) {
0718 if (inDescriptorName.equals(notifList[i].getName())) {
0719 found = true;
0720 ModelMBeanNotificationInfo mmbni = (ModelMBeanNotificationInfo) notifList[i];
0721 mmbni.setDescriptor(inDescriptor);
0722 }
0723 }
0724 } else {
0725 RuntimeException iae = new IllegalArgumentException(
0726 "Invalid descriptor type: " + inDescriptorType);
0727 throw new RuntimeOperationsException(iae, excMsg);
0728 }
0729
0730 if (!found) {
0731 RuntimeException iae = new IllegalArgumentException(
0732 "Descriptor name is invalid: " + "type="
0733 + inDescriptorType + "; name="
0734 + inDescriptorName);
0735 throw new RuntimeOperationsException(iae, excMsg);
0736 }
0737 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0738 MODELMBEAN_LOGGER.logp(Level.FINER,
0739 ModelMBeanInfoSupport.class.getName(),
0740 "setDescriptor(Descriptor,String)", "Exit");
0741 }
0742
0743 }
0744
0745 public ModelMBeanAttributeInfo getAttribute(String inName)
0746 throws MBeanException, RuntimeOperationsException {
0747 ModelMBeanAttributeInfo retInfo = null;
0748 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0749 MODELMBEAN_LOGGER.logp(Level.FINER,
0750 ModelMBeanInfoSupport.class.getName(),
0751 "getAttribute(String)", "Entry");
0752 }
0753 if (inName == null) {
0754 throw new RuntimeOperationsException(
0755 new IllegalArgumentException(
0756 "Attribute Name is null"),
0757 "Exception occurred trying to get the "
0758 + "ModelMBeanAttributeInfo of the MBean");
0759 }
0760 MBeanAttributeInfo[] attrList = modelMBeanAttributes;
0761 int numAttrs = 0;
0762 if (attrList != null)
0763 numAttrs = attrList.length;
0764
0765 for (int i = 0; (i < numAttrs) && (retInfo == null); i++) {
0766 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0767 final StringBuilder strb = new StringBuilder()
0768 .append(
0769 "\t\n this.getAttributes() MBeanAttributeInfo Array ")
0770 .append(i)
0771 .append(":")
0772 .append(
0773 ((ModelMBeanAttributeInfo) attrList[i])
0774 .getDescriptor())
0775 .append(
0776 "\t\n this.modelMBeanAttributes MBeanAttributeInfo Array ")
0777 .append(i)
0778 .append(":")
0779 .append(
0780 ((ModelMBeanAttributeInfo) modelMBeanAttributes[i])
0781 .getDescriptor());
0782 MODELMBEAN_LOGGER.logp(Level.FINER,
0783 ModelMBeanInfoSupport.class.getName(),
0784 "getAttribute(String)", strb.toString());
0785 }
0786 if (inName.equals(attrList[i].getName())) {
0787 retInfo = ((ModelMBeanAttributeInfo) attrList[i]
0788 .clone());
0789 }
0790 }
0791 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0792 MODELMBEAN_LOGGER.logp(Level.FINER,
0793 ModelMBeanInfoSupport.class.getName(),
0794 "getAttribute(String)", "Exit");
0795 }
0796
0797 return retInfo;
0798 }
0799
0800 public ModelMBeanOperationInfo getOperation(String inName)
0801 throws MBeanException, RuntimeOperationsException {
0802 ModelMBeanOperationInfo retInfo = null;
0803 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0804 MODELMBEAN_LOGGER.logp(Level.FINER,
0805 ModelMBeanInfoSupport.class.getName(),
0806 "getOperation(String)", "Entry");
0807 }
0808 if (inName == null) {
0809 throw new RuntimeOperationsException(
0810 new IllegalArgumentException("inName is null"),
0811 "Exception occurred trying to get the "
0812 + "ModelMBeanOperationInfo of the MBean");
0813 }
0814 MBeanOperationInfo[] operList = modelMBeanOperations; //this.getOperations();
0815 int numOpers = 0;
0816 if (operList != null)
0817 numOpers = operList.length;
0818
0819 for (int i = 0; (i < numOpers) && (retInfo == null); i++) {
0820 if (inName.equals(operList[i].getName())) {
0821 retInfo = ((ModelMBeanOperationInfo) operList[i]
0822 .clone());
0823 }
0824 }
0825 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0826 MODELMBEAN_LOGGER.logp(Level.FINER,
0827 ModelMBeanInfoSupport.class.getName(),
0828 "getOperation(String)", "Exit");
0829 }
0830
0831 return retInfo;
0832 }
0833
0834 /**
0835 * Returns the ModelMBeanConstructorInfo requested by name.
0836 * If no ModelMBeanConstructorInfo exists for this name null is returned.
0837 *
0838 * @param inName the name of the constructor.
0839 *
0840 * @return the constructor info for the named constructor, or null
0841 * if there is none.
0842 *
0843 * @exception MBeanException Wraps a distributed communication Exception.
0844 * @exception RuntimeOperationsException Wraps an IllegalArgumentException
0845 * for a null constructor name.
0846 */
0847
0848 public ModelMBeanConstructorInfo getConstructor(String inName)
0849 throws MBeanException, RuntimeOperationsException {
0850 ModelMBeanConstructorInfo retInfo = null;
0851 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0852 MODELMBEAN_LOGGER.logp(Level.FINER,
0853 ModelMBeanInfoSupport.class.getName(),
0854 "getConstructor(String)", "Entry");
0855 }
0856 if (inName == null) {
0857 throw new RuntimeOperationsException(
0858 new IllegalArgumentException(
0859 "Constructor name is null"),
0860 "Exception occurred trying to get the "
0861 + "ModelMBeanConstructorInfo of the MBean");
0862 }
0863 MBeanConstructorInfo[] consList = modelMBeanConstructors; //this.getConstructors();
0864 int numCons = 0;
0865 if (consList != null)
0866 numCons = consList.length;
0867
0868 for (int i = 0; (i < numCons) && (retInfo == null); i++) {
0869 if (inName.equals(consList[i].getName())) {
0870 retInfo = ((ModelMBeanConstructorInfo) consList[i]
0871 .clone());
0872 }
0873 }
0874 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0875 MODELMBEAN_LOGGER.logp(Level.FINER,
0876 ModelMBeanInfoSupport.class.getName(),
0877 "getConstructor(String)", "Exit");
0878 }
0879
0880 return retInfo;
0881 }
0882
0883 public ModelMBeanNotificationInfo getNotification(String inName)
0884 throws MBeanException, RuntimeOperationsException {
0885 ModelMBeanNotificationInfo retInfo = null;
0886 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0887 MODELMBEAN_LOGGER.logp(Level.FINER,
0888 ModelMBeanInfoSupport.class.getName(),
0889 "getNotification(String)", "Entry");
0890 }
0891 if (inName == null) {
0892 throw new RuntimeOperationsException(
0893 new IllegalArgumentException(
0894 "Notification name is null"),
0895 "Exception occurred trying to get the "
0896 + "ModelMBeanNotificationInfo of the MBean");
0897 }
0898 MBeanNotificationInfo[] notifList = modelMBeanNotifications; //this.getNotifications();
0899 int numNotifs = 0;
0900 if (notifList != null)
0901 numNotifs = notifList.length;
0902
0903 for (int i = 0; (i < numNotifs) && (retInfo == null); i++) {
0904 if (inName.equals(notifList[i].getName())) {
0905 retInfo = ((ModelMBeanNotificationInfo) notifList[i]
0906 .clone());
0907 }
0908 }
0909 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0910 MODELMBEAN_LOGGER.logp(Level.FINER,
0911 ModelMBeanInfoSupport.class.getName(),
0912 "getNotification(String)", "Exit");
0913 }
0914
0915 return retInfo;
0916 }
0917
0918 /* We override MBeanInfo.getDescriptor() to return our descriptor. */
0919 /**
0920 * @since 1.6
0921 */
0922 @Override
0923 public Descriptor getDescriptor() {
0924 return getMBeanDescriptorNoException();
0925 }
0926
0927 public Descriptor getMBeanDescriptor() throws MBeanException {
0928 return getMBeanDescriptorNoException();
0929 }
0930
0931 private Descriptor getMBeanDescriptorNoException() {
0932 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0933 MODELMBEAN_LOGGER.logp(Level.FINER,
0934 ModelMBeanInfoSupport.class.getName(),
0935 "getMBeanDescriptorNoException()", "Entry");
0936 }
0937
0938 if (modelMBeanDescriptor == null)
0939 modelMBeanDescriptor = validDescriptor(null);
0940
0941 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0942 MODELMBEAN_LOGGER.logp(Level.FINER,
0943 ModelMBeanInfoSupport.class.getName(),
0944 "getMBeanDescriptorNoException()",
0945 "Exit, returning: " + modelMBeanDescriptor);
0946 }
0947 return (Descriptor) modelMBeanDescriptor.clone();
0948 }
0949
0950 public void setMBeanDescriptor(Descriptor inMBeanDescriptor)
0951 throws MBeanException, RuntimeOperationsException {
0952 if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
0953 MODELMBEAN_LOGGER.logp(Level.FINER,
0954 ModelMBeanInfoSupport.class.getName(),
0955 "setMBeanDescriptor(Descriptor)", "Entry");
0956 }
0957 modelMBeanDescriptor = validDescriptor(inMBeanDescriptor);
0958 }
0959
0960 /**
0961 * Clones the passed in Descriptor, sets default values, and checks for validity.
0962 * If the Descriptor is invalid (for instance by having the wrong "name"),
0963 * this indicates programming error and a RuntimeOperationsException will be thrown.
0964 *
0965 * The following fields will be defaulted if they are not already set:
0966 * displayName=className,name=className,descriptorType="mbean",
0967 * persistPolicy="never", log="F", visibility="1"
0968 *
0969 * @param in Descriptor to be checked, or null which is equivalent to
0970 * an empty Descriptor.
0971 * @exception RuntimeOperationsException if Descriptor is invalid
0972 */
0973 private Descriptor validDescriptor(final Descriptor in)
0974 throws RuntimeOperationsException {
0975 Descriptor clone = null;
0976 if (in == null) {
0977 clone = new DescriptorSupport();
0978 MODELMBEAN_LOGGER.finer("Null Descriptor, creating new.");
0979 } else {
0980 clone = (Descriptor) in.clone();
0981 }
0982
0983 //Setting defaults.
0984 if (clone.getFieldValue("name") == null) {
0985 clone.setField("name", this .getClassName());
0986 MODELMBEAN_LOGGER.finer("Defaulting Descriptor name to "
0987 + this .getClassName());
0988 }
0989 if (clone.getFieldValue("descriptorType") == null) {
0990 clone.setField("descriptorType", MMB);
0991 MODELMBEAN_LOGGER.finer("Defaulting descriptorType to \""
0992 + MMB + "\"");
0993 }
0994 if (clone.getFieldValue("displayName") == null) {
0995 clone.setField("displayName", this .getClassName());
0996 MODELMBEAN_LOGGER
0997 .finer("Defaulting Descriptor displayName to "
0998 + this .getClassName());
0999 }
1000 if (clone.getFieldValue("persistPolicy") == null) {
1001 clone.setField("persistPolicy", "never");
1002 MODELMBEAN_LOGGER
1003 .finer("Defaulting Descriptor persistPolicy to \"never\"");
1004 }
1005 if (clone.getFieldValue("log") == null) {
1006 clone.setField("log", "F");
1007 MODELMBEAN_LOGGER
1008 .finer("Defaulting Descriptor \"log\" field to \"F\"");
1009 }
1010 if (clone.getFieldValue("visibility") == null) {
1011 clone.setField("visibility", "1");
1012 MODELMBEAN_LOGGER
1013 .finer("Defaulting Descriptor visibility to 1");
1014 }
1015
1016 //Checking validity
1017 if (!clone.isValid()) {
1018 throw new RuntimeOperationsException(
1019 new IllegalArgumentException(
1020 "Invalid Descriptor argument"),
1021 "The isValid() method of the Descriptor object itself returned false,"
1022 + "one or more required fields are invalid. Descriptor:"
1023 + clone.toString());
1024 }
1025
1026 if (!((String) clone.getFieldValue("descriptorType"))
1027 .equalsIgnoreCase(MMB)) {
1028 throw new RuntimeOperationsException(
1029 new IllegalArgumentException(
1030 "Invalid Descriptor argument"),
1031 "The Descriptor \"descriptorType\" field does not match the object described. "
1032 + " Expected: " + MMB + " , was: "
1033 + clone.getFieldValue("descriptorType"));
1034 }
1035
1036 return clone;
1037 }
1038
1039 /**
1040 * Deserializes a {@link ModelMBeanInfoSupport} from an {@link ObjectInputStream}.
1041 */
1042 private void readObject(ObjectInputStream in) throws IOException,
1043 ClassNotFoundException {
1044 if (compat) {
1045 // Read an object serialized in the old serial form
1046 //
1047 ObjectInputStream.GetField fields = in.readFields();
1048 modelMBeanDescriptor = (Descriptor) fields.get(
1049 "modelMBeanDescriptor", null);
1050 if (fields.defaulted("modelMBeanDescriptor")) {
1051 throw new NullPointerException("modelMBeanDescriptor");
1052 }
1053 modelMBeanAttributes = (MBeanAttributeInfo[]) fields.get(
1054 "mmbAttributes", null);
1055 if (fields.defaulted("mmbAttributes")) {
1056 throw new NullPointerException("mmbAttributes");
1057 }
1058 modelMBeanConstructors = (MBeanConstructorInfo[]) fields
1059 .get("mmbConstructors", null);
1060 if (fields.defaulted("mmbConstructors")) {
1061 throw new NullPointerException("mmbConstructors");
1062 }
1063 modelMBeanNotifications = (MBeanNotificationInfo[]) fields
1064 .get("mmbNotifications", null);
1065 if (fields.defaulted("mmbNotifications")) {
1066 throw new NullPointerException("mmbNotifications");
1067 }
1068 modelMBeanOperations = (MBeanOperationInfo[]) fields.get(
1069 "mmbOperations", null);
1070 if (fields.defaulted("mmbOperations")) {
1071 throw new NullPointerException("mmbOperations");
1072 }
1073 } else {
1074 // Read an object serialized in the new serial form
1075 //
1076 in.defaultReadObject();
1077 }
1078 }
1079
1080 /**
1081 * Serializes a {@link ModelMBeanInfoSupport} to an {@link ObjectOutputStream}.
1082 */
1083 private void writeObject(ObjectOutputStream out) throws IOException {
1084 if (compat) {
1085 // Serializes this instance in the old serial form
1086 //
1087 ObjectOutputStream.PutField fields = out.putFields();
1088 fields.put("modelMBeanDescriptor", modelMBeanDescriptor);
1089 fields.put("mmbAttributes", modelMBeanAttributes);
1090 fields.put("mmbConstructors", modelMBeanConstructors);
1091 fields.put("mmbNotifications", modelMBeanNotifications);
1092 fields.put("mmbOperations", modelMBeanOperations);
1093 fields.put("currClass", currClass);
1094 out.writeFields();
1095 } else {
1096 // Serializes this instance in the new serial form
1097 //
1098 out.defaultWriteObject();
1099 }
1100 }
1101
1102 }
|