/* * @(#)RoleInfo.java 1.34 03/12/19 * * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package javax.management.relation; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.ObjectStreamField; import java.io.Serializable; import java.security.AccessController; import java.security.PrivilegedAction; import javax.management.NotCompliantMBeanException; import javax.management.MBeanInfo; import javax.management.MBeanServer; import javax.management.loading.ClassLoaderRepository; import com.sun.jmx.mbeanserver.GetPropertyAction; import com.sun.jmx.mbeanserver.Introspector; /** * A RoleInfo object summarises a role in a relation type. * * @since 1.5 */ public class RoleInfo implements Serializable { // Serialization compatibility stuff: // Two serial forms are supported in this class. The selected form depends // on system property "jmx.serial.form": // - "1.0" for JMX 1.0 // - any other value for JMX 1.1 and higher // // Serial version for old serial form private static final long oldSerialVersionUID = 7227256952085334351L; // // Serial version for new serial form private static final long newSerialVersionUID = 2504952983494636987L; // // Serializable fields in old serial form private static final ObjectStreamField[] oldSerialPersistentFields = { new ObjectStreamField("myName", String.class), new ObjectStreamField("myIsReadableFlg", boolean.class), new ObjectStreamField("myIsWritableFlg", boolean.class), new ObjectStreamField("myDescription", String.class), new ObjectStreamField("myMinDegree", int.class), new ObjectStreamField("myMaxDegree", int.class), new ObjectStreamField("myRefMBeanClassName", String.class) }; // // Serializable fields in new serial form private static final ObjectStreamField[] newSerialPersistentFields = { new ObjectStreamField("name", String.class), new ObjectStreamField("isReadable", boolean.class), new ObjectStreamField("isWritable", boolean.class), new ObjectStreamField("description", String.class), new ObjectStreamField("minDegree", int.class), new ObjectStreamField("maxDegree", int.class), new ObjectStreamField("referencedMBeanClassName", String.class) }; // // Actual serial version and serial form private static final long serialVersionUID; /** * @serialField name String Role name * @serialField isReadable boolean Read access mode: true if role is readable * @serialField isWritable boolean Write access mode: true if role is writable * @serialField description String Role description * @serialField minDegree int Minimum degree (i.e. minimum number of referenced MBeans in corresponding role) * @serialField maxDegree int Maximum degree (i.e. maximum number of referenced MBeans in corresponding role) * @serialField referencedMBeanClassName String Name of class of MBean(s) expected to be referenced in corresponding role */ private static final ObjectStreamField[] serialPersistentFields; private static boolean compat = false; static { try { PrivilegedAction act = new GetPropertyAction("jmx.serial.form"); String form = (String) AccessController.doPrivileged(act); compat = (form != null && form.equals("1.0")); } catch (Exception e) { // OK : Too bad, no compat with 1.0 } if (compat) { serialPersistentFields = oldSerialPersistentFields; serialVersionUID = oldSerialVersionUID; } else { serialPersistentFields = newSerialPersistentFields; serialVersionUID = newSerialVersionUID; } } // // END Serialization compatibility stuff // // Public constants // /** * To specify an unlimited cardinality. */ public static int ROLE_CARDINALITY_INFINITY = -1; // // Private members // /** * @serial Role name */ private String name = null; /** * @serial Read access mode: true if role is readable */ private boolean isReadable; /** * @serial Write access mode: true if role is writable */ private boolean isWritable; /** * @serial Role description */ private String description = null; /** * @serial Minimum degree (i.e. minimum number of referenced MBeans in corresponding role) */ private int minDegree; /** * @serial Maximum degree (i.e. maximum number of referenced MBeans in corresponding role) */ private int maxDegree; /** * @serial Name of class of MBean(s) expected to be referenced in corresponding role */ private String referencedMBeanClassName = null; // // Constructors // /** * Constructor. * * @param theName name of the role. * @param theRefMBeanClassName name of the class of MBean(s) expected to * be referenced in corresponding role. If an MBean M is in * this role, then the MBean server must return true for * {@link MBeanServer#isInstanceOf isInstanceOf(M, theRefMBeanClassName)}. * @param theIsReadable flag to indicate if the corresponding role * can be read * @param theIsWritable flag to indicate if the corresponding role * can be set * @param theMinDegree minimum degree for role, i.e. minimum number of * MBeans to provide in corresponding role * Must be less or equal than theMaxDegree. * (ROLE_CARDINALITY_INFINITY for unlimited) * @param theMaxDegree maximum degree for role, i.e. maximum number of * MBeans to provide in corresponding role * Must be greater or equal than theMinDegree * (ROLE_CARDINALITY_INFINITY for unlimited) * @param theDescription description of the role (can be null) * * @exception IllegalArgumentException if null parameter * @exception InvalidRoleInfoException if the minimum degree is * greater than the maximum degree. * @exception ClassNotFoundException As of JMX 1.2, this exception * can no longer be thrown. It is retained in the declaration of * this class for compatibility with existing code. * @exception NotCompliantMBeanException if the class theRefMBeanClassName * is not a MBean class. */ public RoleInfo(String theName, String theRefMBeanClassName, boolean theIsReadable, boolean theIsWritable, int theMinDegree, int theMaxDegree, String theDescription) throws IllegalArgumentException, InvalidRoleInfoException, ClassNotFoundException, NotCompliantMBeanException { init(theName, theRefMBeanClassName, theIsReadable, theIsWritable, theMinDegree, theMaxDegree, theDescription); return; } /** * Constructor. * * @param theName name of the role * @param theRefMBeanClassName name of the class of MBean(s) expected to * be referenced in corresponding role. If an MBean M is in * this role, then the MBean server must return true for * {@link MBeanServer#isInstanceOf isInstanceOf(M, theRefMBeanClassName)}. * @param theIsReadable flag to indicate if the corresponding role * can be read * @param theIsWritable flag to indicate if the corresponding role * can be set * *

Minimum and maximum degrees defaulted to 1. *

Description of role defaulted to null. * * @exception IllegalArgumentException if null parameter * @exception ClassNotFoundException As of JMX 1.2, this exception * can no longer be thrown. It is retained in the declaration of * this class for compatibility with existing code. * @exception NotCompliantMBeanException As of JMX 1.2, this * exception can no longer be thrown. It is retained in the * declaration of this class for compatibility with existing code. */ public RoleInfo(String theName, String theRefMBeanClassName, boolean theIsReadable, boolean theIsWritable) throws IllegalArgumentException, ClassNotFoundException, NotCompliantMBeanException { try { init(theName, theRefMBeanClassName, theIsReadable, theIsWritable, 1, 1, null); } catch (InvalidRoleInfoException exc) { // OK : Can never happen as the minimum // degree equals the maximum degree. } return; } /** * Constructor. * * @param theName name of the role * @param theRefMBeanClassName name of the class of MBean(s) expected to * be referenced in corresponding role. If an MBean M is in * this role, then the MBean server must return true for * {@link MBeanServer#isInstanceOf isInstanceOf(M, theRefMBeanClassName)}. * *

IsReadable and IsWritable defaulted to true. *

Minimum and maximum degrees defaulted to 1. *

Description of role defaulted to null. * * @exception IllegalArgumentException if null parameter * @exception ClassNotFoundException As of JMX 1.2, this exception * can no longer be thrown. It is retained in the declaration of * this class for compatibility with existing code. * @exception NotCompliantMBeanException As of JMX 1.2, this * exception can no longer be thrown. It is retained in the * declaration of this class for compatibility with existing code. */ public RoleInfo(String theName, String theRefMBeanClassName) throws IllegalArgumentException, ClassNotFoundException, NotCompliantMBeanException { try { init(theName, theRefMBeanClassName, true, true, 1, 1, null); } catch (InvalidRoleInfoException exc) { // OK : Can never happen as the minimum // degree equals the maximum degree. } return; } /** * Copy constructor. * * @param theRoleInfo the RoleInfo to be copied. * * @exception IllegalArgumentException if null parameter */ public RoleInfo(RoleInfo theRoleInfo) throws IllegalArgumentException { if (theRoleInfo == null) { // Revisit [cebro] Localize message String excMsg = "Invalid parameter."; throw new IllegalArgumentException(excMsg); } try { init(theRoleInfo.getName(), theRoleInfo.getRefMBeanClassName(), theRoleInfo.isReadable(), theRoleInfo.isWritable(), theRoleInfo.getMinDegree(), theRoleInfo.getMaxDegree(), theRoleInfo.getDescription()); } catch (InvalidRoleInfoException exc3) { // OK : Can never happen as the minimum degree and the maximum // degree were already checked at the time the theRoleInfo // instance was created. } } // // Accessors // /** * Returns the name of the role. * * @return the name of the role. */ public String getName() { return name; } /** * Returns read access mode for the role (true if it is readable). * * @return true if the role is readable. */ public boolean isReadable() { return isReadable; } /** * Returns write access mode for the role (true if it is writable). * * @return true if the role is writable. */ public boolean isWritable() { return isWritable; } /** * Returns description text for the role. * * @return the description of the role. */ public String getDescription() { return description; } /** * Returns minimum degree for corresponding role reference. * * @return the minimum degree. */ public int getMinDegree() { return minDegree; } /** * Returns maximum degree for corresponding role reference. * * @return the maximum degree. */ public int getMaxDegree() { return maxDegree; } /** *

Returns name of type of MBean expected to be referenced in * corresponding role.

* * @return the name of the referenced type. */ public String getRefMBeanClassName() { return referencedMBeanClassName; } /** * Returns a boolean to specify if given value is greater or equal than * expected minimum degree (true if yes). * * @param theValue value * * @return true if greater or equal than minimum degree, false otherwise. */ public boolean checkMinDegree(int theValue) { if (theValue >= ROLE_CARDINALITY_INFINITY && (minDegree == ROLE_CARDINALITY_INFINITY || theValue >= minDegree)) { return true; } else { return false; } } /** * Returns a boolean to specify if given value is less or equal than * expected maximum degree (true if yes). * * @param theValue value * * @return true if less or equal than maximum degree, false otherwise. */ public boolean checkMaxDegree(int theValue) { if (theValue >= ROLE_CARDINALITY_INFINITY && (maxDegree == ROLE_CARDINALITY_INFINITY || (theValue != ROLE_CARDINALITY_INFINITY && theValue <= maxDegree))) { return true; } else { return false; } } /** * Returns a string describing the role info. * * @return a description of the role info. */ public String toString() { StringBuffer result = new StringBuffer(); result.append("role info name: " + name); result.append("; isReadable: " + isReadable); result.append("; isWritable: " + isWritable); result.append("; description: " + description); result.append("; minimum degree: " + minDegree); result.append("; maximum degree: " + maxDegree); result.append("; MBean class: " + referencedMBeanClassName); return result.toString(); } // // Misc // // Initialisation private void init(String theName, String theRefMBeanClassName, boolean theIsReadable, boolean theIsWritable, int theMinDegree, int theMaxDegree, String theDescription) throws IllegalArgumentException, InvalidRoleInfoException { if (theName == null || theRefMBeanClassName == null) { // Revisit [cebro] Localize message String excMsg = "Invalid parameter."; throw new IllegalArgumentException(excMsg); } name = theName; isReadable = theIsReadable; isWritable = theIsWritable; if (theDescription != null) { description = theDescription; } boolean invalidRoleInfoFlg = false; StringBuffer excMsgStrB = new StringBuffer(); if (theMaxDegree != ROLE_CARDINALITY_INFINITY && (theMinDegree == ROLE_CARDINALITY_INFINITY || theMinDegree > theMaxDegree)) { // Revisit [cebro] Localize message excMsgStrB.append("Minimum degree "); excMsgStrB.append(theMinDegree); excMsgStrB.append(" is greater than maximum degree "); excMsgStrB.append(theMaxDegree); invalidRoleInfoFlg = true; } else if (theMinDegree < ROLE_CARDINALITY_INFINITY || theMaxDegree < ROLE_CARDINALITY_INFINITY) { // Revisit [cebro] Localize message excMsgStrB.append("Minimum or maximum degree has an illegal value, must be [0, ROLE_CARDINALITY_INFINITY]."); invalidRoleInfoFlg = true; } if (invalidRoleInfoFlg) { throw new InvalidRoleInfoException(excMsgStrB.toString()); } minDegree = theMinDegree; maxDegree = theMaxDegree; referencedMBeanClassName = theRefMBeanClassName; return; } /** * Deserializes a {@link RoleInfo} from an {@link ObjectInputStream}. */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { if (compat) { // Read an object serialized in the old serial form // ObjectInputStream.GetField fields = in.readFields(); name = (String) fields.get("myName", null); if (fields.defaulted("myName")) { throw new NullPointerException("myName"); } isReadable = fields.get("myIsReadableFlg", false); if (fields.defaulted("myIsReadableFlg")) { throw new NullPointerException("myIsReadableFlg"); } isWritable = fields.get("myIsWritableFlg", false); if (fields.defaulted("myIsWritableFlg")) { throw new NullPointerException("myIsWritableFlg"); } description = (String) fields.get("myDescription", null); if (fields.defaulted("myDescription")) { throw new NullPointerException("myDescription"); } minDegree = fields.get("myMinDegree", (int)0); if (fields.defaulted("myMinDegree")) { throw new NullPointerException("myMinDegree"); } maxDegree = fields.get("myMaxDegree", (int)0); if (fields.defaulted("myMaxDegree")) { throw new NullPointerException("myMaxDegree"); } referencedMBeanClassName = (String) fields.get("myRefMBeanClassName", null); if (fields.defaulted("myRefMBeanClassName")) { throw new NullPointerException("myRefMBeanClassName"); } } else { // Read an object serialized in the new serial form // in.defaultReadObject(); } } /** * Serializes a {@link RoleInfo} to an {@link ObjectOutputStream}. */ private void writeObject(ObjectOutputStream out) throws IOException { if (compat) { // Serializes this instance in the old serial form // ObjectOutputStream.PutField fields = out.putFields(); fields.put("myName", name); fields.put("myIsReadableFlg", isReadable); fields.put("myIsWritableFlg", isWritable); fields.put("myDescription", description); fields.put("myMinDegree", minDegree); fields.put("myMaxDegree", maxDegree); fields.put("myRefMBeanClassName", referencedMBeanClassName); out.writeFields(); } else { // Serializes this instance in the new serial form // out.defaultWriteObject(); } } }