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      */
RoleUnresolved(String name, List<ObjectName> value, int pbType)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      */
getRoleName()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      */
getRoleValue()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      */
getProblemType()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      */
setRoleName(String name)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      */
setRoleValue(List<ObjectName> value)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      */
setProblemType(int pbType)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      */
clone()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      */
toString()283     public String toString() {
284         StringBuilder result = new StringBuilder();
285         result.append("role name: " + 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: " + problemType);
298         return result.toString();
299     }
300 
301     /**
302      * Deserializes a {@link RoleUnresolved} from an {@link ObjectInputStream}.
303      */
readObject(ObjectInputStream in)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      */
writeObject(ObjectOutputStream out)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 }
359