1 /*
   2  * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.management.relation;
  27 
  28 import static com.sun.jmx.mbeanserver.Util.cast;
  29 import com.sun.jmx.mbeanserver.GetPropertyAction;
  30 
  31 import java.io.IOException;
  32 import java.io.ObjectInputStream;
  33 import java.io.ObjectOutputStream;
  34 import java.io.ObjectStreamField;
  35 import java.io.Serializable;
  36 
  37 import java.security.AccessController;
  38 
  39 import java.util.ArrayList;
  40 import java.util.Iterator;
  41 import java.util.List;
  42 
  43 import javax.management.ObjectName;
  44 
  45 /**
  46  * Represents an unresolved role: a role not retrieved from a relation due
  47  * to a problem. It provides the role name, value (if problem when trying to
  48  * set the role) and an integer defining the problem (constants defined in
  49  * RoleStatus).
  50  *
  51  * <p>The <b>serialVersionUID</b> of this class is <code>-48350262537070138L</code>.
  52  *
  53  * @since 1.5
  54  */
  55 @SuppressWarnings("serial")  // serialVersionUID not constant
  56 public class RoleUnresolved implements Serializable {
  57 
  58     // Serialization compatibility stuff:
  59     // Two serial forms are supported in this class. The selected form depends
  60     // on system property "jmx.serial.form":
  61     //  - "1.0" for JMX 1.0
  62     //  - any other value for JMX 1.1 and higher
  63     //
  64     // Serial version for old serial form
  65     private static final long oldSerialVersionUID = -9026457686611660144L;
  66     //
  67     // Serial version for new serial form
  68     private static final long newSerialVersionUID = -48350262537070138L;
  69     //
  70     // Serializable fields in old serial form
  71     private static final ObjectStreamField[] oldSerialPersistentFields =
  72     {
  73       new ObjectStreamField("myRoleName", String.class),
  74       new ObjectStreamField("myRoleValue", ArrayList.class),
  75       new ObjectStreamField("myPbType", int.class)
  76     };
  77     //
  78     // Serializable fields in new serial form
  79     private static final ObjectStreamField[] newSerialPersistentFields =
  80     {
  81       new ObjectStreamField("roleName", String.class),
  82       new ObjectStreamField("roleValue", List.class),
  83       new ObjectStreamField("problemType", int.class)
  84     };
  85     //
  86     // Actual serial version and serial form
  87     private static final long serialVersionUID;
  88     /** @serialField roleName String Role name
  89      *  @serialField roleValue List Role value ({@link List} of {@link ObjectName} objects)
  90      *  @serialField problemType int Problem type
  91      */
  92     private static final ObjectStreamField[] serialPersistentFields;
  93     private static boolean compat = false;
  94     static {
  95         try {
  96             GetPropertyAction act = new GetPropertyAction("jmx.serial.form");
  97             String form = AccessController.doPrivileged(act);
  98             compat = (form != null && form.equals("1.0"));
  99         } catch (Exception e) {
 100             // OK : Too bad, no compat with 1.0
 101         }
 102         if (compat) {
 103             serialPersistentFields = oldSerialPersistentFields;
 104             serialVersionUID = oldSerialVersionUID;
 105         } else {
 106             serialPersistentFields = newSerialPersistentFields;
 107             serialVersionUID = newSerialVersionUID;
 108         }
 109     }
 110     //
 111     // END Serialization compatibility stuff
 112 
 113     //
 114     // Private members
 115     //
 116 
 117     /**
 118      * @serial Role name
 119      */
 120     private String roleName = null;
 121 
 122     /**
 123      * @serial Role value ({@link List} of {@link ObjectName} objects)
 124      */
 125     private List<ObjectName> roleValue = null;
 126 
 127     /**
 128      * @serial Problem type
 129      */
 130     private int problemType;
 131 
 132     //
 133     // Constructor
 134     //
 135 
 136     /**
 137      * Constructor.
 138      *
 139      * @param name  name of the role
 140      * @param value  value of the role (if problem when setting the
 141      * role)
 142      * @param pbType  type of problem (according to known problem types,
 143      * listed as static final members).
 144      *
 145      * @exception IllegalArgumentException  if null parameter or incorrect
 146      * problem type
 147      */
 148     public RoleUnresolved(String name,
 149                           List<ObjectName> value,
 150                           int pbType)
 151         throws IllegalArgumentException {
 152 
 153         if (name == null) {
 154             String excMsg = "Invalid parameter.";
 155             throw new IllegalArgumentException(excMsg);
 156         }
 157 
 158         setRoleName(name);
 159         setRoleValue(value);
 160         // Can throw IllegalArgumentException
 161         setProblemType(pbType);
 162         return;
 163     }
 164 
 165     //
 166     // Accessors
 167     //
 168 
 169     /**
 170      * Retrieves role name.
 171      *
 172      * @return the role name.
 173      *
 174      * @see #setRoleName
 175      */
 176     public String getRoleName() {
 177         return roleName;
 178     }
 179 
 180     /**
 181      * Retrieves role value.
 182      *
 183      * @return an ArrayList of ObjectName objects, the one provided to be set
 184      * in given role. Null if the unresolved role is returned for a read
 185      * access.
 186      *
 187      * @see #setRoleValue
 188      */
 189     public List<ObjectName> getRoleValue() {
 190         return roleValue;
 191     }
 192 
 193     /**
 194      * Retrieves problem type.
 195      *
 196      * @return an integer corresponding to a problem, those being described as
 197      * static final members of current class.
 198      *
 199      * @see #setProblemType
 200      */
 201     public int getProblemType() {
 202         return problemType;
 203     }
 204 
 205     /**
 206      * Sets role name.
 207      *
 208      * @param name the new role name.
 209      *
 210      * @exception IllegalArgumentException  if null parameter
 211      *
 212      * @see #getRoleName
 213      */
 214     public void setRoleName(String name)
 215         throws IllegalArgumentException {
 216 
 217         if (name == null) {
 218             String excMsg = "Invalid parameter.";
 219             throw new IllegalArgumentException(excMsg);
 220         }
 221 
 222         roleName = name;
 223         return;
 224     }
 225 
 226     /**
 227      * Sets role value.
 228      *
 229      * @param value  List of ObjectName objects for referenced
 230      * MBeans not set in role.
 231      *
 232      * @see #getRoleValue
 233      */
 234     public void setRoleValue(List<ObjectName> value) {
 235 
 236         if (value != null) {
 237             roleValue = new ArrayList<ObjectName>(value);
 238         } else {
 239             roleValue = null;
 240         }
 241         return;
 242     }
 243 
 244     /**
 245      * Sets problem type.
 246      *
 247      * @param pbType  integer corresponding to a problem. Must be one of
 248      * those described as static final members of current class.
 249      *
 250      * @exception IllegalArgumentException  if incorrect problem type
 251      *
 252      * @see #getProblemType
 253      */
 254     public void setProblemType(int pbType)
 255         throws IllegalArgumentException {
 256 
 257         if (!(RoleStatus.isRoleStatus(pbType))) {
 258             String excMsg = "Incorrect problem type.";
 259             throw new IllegalArgumentException(excMsg);
 260         }
 261         problemType = pbType;
 262         return;
 263     }
 264 
 265     /**
 266      * Clone this object.
 267      *
 268      * @return an independent clone.
 269      */
 270     public Object clone() {
 271         try {
 272             return new RoleUnresolved(roleName, roleValue, problemType);
 273         } catch (IllegalArgumentException exc) {
 274             return null; // :)
 275         }
 276     }
 277 
 278     /**
 279      * Return a string describing this object.
 280      *
 281      * @return a description of this RoleUnresolved object.
 282      */
 283     public String toString() {
 284         StringBuilder result = new StringBuilder();
 285         result.append("role name: ").append(roleName);
 286         if (roleValue != null) {
 287             result.append("; value: ");
 288             for (Iterator<ObjectName> objNameIter = roleValue.iterator();
 289                  objNameIter.hasNext();) {
 290                 ObjectName currObjName = objNameIter.next();
 291                 result.append(currObjName.toString());
 292                 if (objNameIter.hasNext()) {
 293                     result.append(", ");
 294                 }
 295             }
 296         }
 297         result.append("; problem type: ").append(problemType);
 298         return result.toString();
 299     }
 300 
 301     /**
 302      * Deserializes a {@link RoleUnresolved} from an {@link ObjectInputStream}.
 303      */
 304     private void readObject(ObjectInputStream in)
 305             throws IOException, ClassNotFoundException {
 306       if (compat)
 307       {
 308         // Read an object serialized in the old serial form
 309         //
 310         ObjectInputStream.GetField fields = in.readFields();
 311         roleName = (String) fields.get("myRoleName", null);
 312         if (fields.defaulted("myRoleName"))
 313         {
 314           throw new NullPointerException("myRoleName");
 315         }
 316         roleValue = cast(fields.get("myRoleValue", null));
 317         if (fields.defaulted("myRoleValue"))
 318         {
 319           throw new NullPointerException("myRoleValue");
 320         }
 321         problemType = fields.get("myPbType", 0);
 322         if (fields.defaulted("myPbType"))
 323         {
 324           throw new NullPointerException("myPbType");
 325         }
 326       }
 327       else
 328       {
 329         // Read an object serialized in the new serial form
 330         //
 331         in.defaultReadObject();
 332       }
 333     }
 334 
 335 
 336     /**
 337      * Serializes a {@link RoleUnresolved} to an {@link ObjectOutputStream}.
 338      */
 339     private void writeObject(ObjectOutputStream out)
 340             throws IOException {
 341       if (compat)
 342       {
 343         // Serializes this instance in the old serial form
 344         //
 345         ObjectOutputStream.PutField fields = out.putFields();
 346         fields.put("myRoleName", roleName);
 347         fields.put("myRoleValue", roleValue);
 348         fields.put("myPbType", problemType);
 349         out.writeFields();
 350       }
 351       else
 352       {
 353         // Serializes this instance in the new serial form
 354         //
 355         out.defaultWriteObject();
 356       }
 357     }
 358 }