001 /*
002 * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.management.relation;
027
028 import com.sun.jmx.mbeanserver.GetPropertyAction;
029
030 import java.io.IOException;
031 import java.io.ObjectInputStream;
032 import java.io.ObjectOutputStream;
033 import java.io.ObjectStreamField;
034 import java.io.Serializable;
035 import java.security.AccessController;
036
037 import javax.management.MBeanServer;
038
039 import javax.management.NotCompliantMBeanException;
040
041 /**
042 * A RoleInfo object summarises a role in a relation type.
043 *
044 * <p>The <b>serialVersionUID</b> of this class is <code>2504952983494636987L</code>.
045 *
046 * @since 1.5
047 */
048 @SuppressWarnings("serial")
049 // serialVersionUID not constant
050 public class RoleInfo implements Serializable {
051
052 // Serialization compatibility stuff:
053 // Two serial forms are supported in this class. The selected form depends
054 // on system property "jmx.serial.form":
055 // - "1.0" for JMX 1.0
056 // - any other value for JMX 1.1 and higher
057 //
058 // Serial version for old serial form
059 private static final long oldSerialVersionUID = 7227256952085334351L;
060 //
061 // Serial version for new serial form
062 private static final long newSerialVersionUID = 2504952983494636987L;
063 //
064 // Serializable fields in old serial form
065 private static final ObjectStreamField[] oldSerialPersistentFields = {
066 new ObjectStreamField("myName", String.class),
067 new ObjectStreamField("myIsReadableFlg", boolean.class),
068 new ObjectStreamField("myIsWritableFlg", boolean.class),
069 new ObjectStreamField("myDescription", String.class),
070 new ObjectStreamField("myMinDegree", int.class),
071 new ObjectStreamField("myMaxDegree", int.class),
072 new ObjectStreamField("myRefMBeanClassName", String.class) };
073 //
074 // Serializable fields in new serial form
075 private static final ObjectStreamField[] newSerialPersistentFields = {
076 new ObjectStreamField("name", String.class),
077 new ObjectStreamField("isReadable", boolean.class),
078 new ObjectStreamField("isWritable", boolean.class),
079 new ObjectStreamField("description", String.class),
080 new ObjectStreamField("minDegree", int.class),
081 new ObjectStreamField("maxDegree", int.class),
082 new ObjectStreamField("referencedMBeanClassName",
083 String.class) };
084 //
085 // Actual serial version and serial form
086 private static final long serialVersionUID;
087 /**
088 * @serialField name String Role name
089 * @serialField isReadable boolean Read access mode: <code>true</code> if role is readable
090 * @serialField isWritable boolean Write access mode: <code>true</code> if role is writable
091 * @serialField description String Role description
092 * @serialField minDegree int Minimum degree (i.e. minimum number of referenced MBeans in corresponding role)
093 * @serialField maxDegree int Maximum degree (i.e. maximum number of referenced MBeans in corresponding role)
094 * @serialField referencedMBeanClassName String Name of class of MBean(s) expected to be referenced in corresponding role
095 */
096 private static final ObjectStreamField[] serialPersistentFields;
097 private static boolean compat = false;
098 static {
099 try {
100 GetPropertyAction act = new GetPropertyAction(
101 "jmx.serial.form");
102 String form = AccessController.doPrivileged(act);
103 compat = (form != null && form.equals("1.0"));
104 } catch (Exception e) {
105 // OK : Too bad, no compat with 1.0
106 }
107 if (compat) {
108 serialPersistentFields = oldSerialPersistentFields;
109 serialVersionUID = oldSerialVersionUID;
110 } else {
111 serialPersistentFields = newSerialPersistentFields;
112 serialVersionUID = newSerialVersionUID;
113 }
114 }
115 //
116 // END Serialization compatibility stuff
117
118 //
119 // Public constants
120 //
121
122 /**
123 * To specify an unlimited cardinality.
124 */
125 public static final int ROLE_CARDINALITY_INFINITY = -1;
126
127 //
128 // Private members
129 //
130
131 /**
132 * @serial Role name
133 */
134 private String name = null;
135
136 /**
137 * @serial Read access mode: <code>true</code> if role is readable
138 */
139 private boolean isReadable;
140
141 /**
142 * @serial Write access mode: <code>true</code> if role is writable
143 */
144 private boolean isWritable;
145
146 /**
147 * @serial Role description
148 */
149 private String description = null;
150
151 /**
152 * @serial Minimum degree (i.e. minimum number of referenced MBeans in corresponding role)
153 */
154 private int minDegree;
155
156 /**
157 * @serial Maximum degree (i.e. maximum number of referenced MBeans in corresponding role)
158 */
159 private int maxDegree;
160
161 /**
162 * @serial Name of class of MBean(s) expected to be referenced in corresponding role
163 */
164 private String referencedMBeanClassName = null;
165
166 //
167 // Constructors
168 //
169
170 /**
171 * Constructor.
172 *
173 * @param roleName name of the role.
174 * @param mbeanClassName name of the class of MBean(s) expected to
175 * be referenced in corresponding role. If an MBean <em>M</em> is in
176 * this role, then the MBean server must return true for
177 * {@link MBeanServer#isInstanceOf isInstanceOf(M, mbeanClassName)}.
178 * @param read flag to indicate if the corresponding role
179 * can be read
180 * @param write flag to indicate if the corresponding role
181 * can be set
182 * @param min minimum degree for role, i.e. minimum number of
183 * MBeans to provide in corresponding role
184 * Must be less than or equal to <tt>max</tt>.
185 * (ROLE_CARDINALITY_INFINITY for unlimited)
186 * @param max maximum degree for role, i.e. maximum number of
187 * MBeans to provide in corresponding role
188 * Must be greater than or equal to <tt>min</tt>
189 * (ROLE_CARDINALITY_INFINITY for unlimited)
190 * @param descr description of the role (can be null)
191 *
192 * @exception IllegalArgumentException if null parameter
193 * @exception InvalidRoleInfoException if the minimum degree is
194 * greater than the maximum degree.
195 * @exception ClassNotFoundException As of JMX 1.2, this exception
196 * can no longer be thrown. It is retained in the declaration of
197 * this class for compatibility with existing code.
198 * @exception NotCompliantMBeanException if the class mbeanClassName
199 * is not a MBean class.
200 */
201 public RoleInfo(String roleName, String mbeanClassName,
202 boolean read, boolean write, int min, int max, String descr)
203 throws IllegalArgumentException, InvalidRoleInfoException,
204 ClassNotFoundException, NotCompliantMBeanException {
205
206 init(roleName, mbeanClassName, read, write, min, max, descr);
207 return;
208 }
209
210 /**
211 * Constructor.
212 *
213 * @param roleName name of the role
214 * @param mbeanClassName name of the class of MBean(s) expected to
215 * be referenced in corresponding role. If an MBean <em>M</em> is in
216 * this role, then the MBean server must return true for
217 * {@link MBeanServer#isInstanceOf isInstanceOf(M, mbeanClassName)}.
218 * @param read flag to indicate if the corresponding role
219 * can be read
220 * @param write flag to indicate if the corresponding role
221 * can be set
222 *
223 * <P>Minimum and maximum degrees defaulted to 1.
224 * <P>Description of role defaulted to null.
225 *
226 * @exception IllegalArgumentException if null parameter
227 * @exception ClassNotFoundException As of JMX 1.2, this exception
228 * can no longer be thrown. It is retained in the declaration of
229 * this class for compatibility with existing code.
230 * @exception NotCompliantMBeanException As of JMX 1.2, this
231 * exception can no longer be thrown. It is retained in the
232 * declaration of this class for compatibility with existing code.
233 */
234 public RoleInfo(String roleName, String mbeanClassName,
235 boolean read, boolean write)
236 throws IllegalArgumentException, ClassNotFoundException,
237 NotCompliantMBeanException {
238
239 try {
240 init(roleName, mbeanClassName, read, write, 1, 1, null);
241 } catch (InvalidRoleInfoException exc) {
242 // OK : Can never happen as the minimum
243 // degree equals the maximum degree.
244 }
245
246 return;
247 }
248
249 /**
250 * Constructor.
251 *
252 * @param roleName name of the role
253 * @param mbeanClassName name of the class of MBean(s) expected to
254 * be referenced in corresponding role. If an MBean <em>M</em> is in
255 * this role, then the MBean server must return true for
256 * {@link MBeanServer#isInstanceOf isInstanceOf(M, mbeanClassName)}.
257 *
258 * <P>IsReadable and IsWritable defaulted to true.
259 * <P>Minimum and maximum degrees defaulted to 1.
260 * <P>Description of role defaulted to null.
261 *
262 * @exception IllegalArgumentException if null parameter
263 * @exception ClassNotFoundException As of JMX 1.2, this exception
264 * can no longer be thrown. It is retained in the declaration of
265 * this class for compatibility with existing code.
266 * @exception NotCompliantMBeanException As of JMX 1.2, this
267 * exception can no longer be thrown. It is retained in the
268 * declaration of this class for compatibility with existing code.
269 */
270 public RoleInfo(String roleName, String mbeanClassName)
271 throws IllegalArgumentException, ClassNotFoundException,
272 NotCompliantMBeanException {
273
274 try {
275 init(roleName, mbeanClassName, true, true, 1, 1, null);
276 } catch (InvalidRoleInfoException exc) {
277 // OK : Can never happen as the minimum
278 // degree equals the maximum degree.
279 }
280
281 return;
282 }
283
284 /**
285 * Copy constructor.
286 *
287 * @param roleInfo the <tt>RoleInfo</tt> instance to be copied.
288 *
289 * @exception IllegalArgumentException if null parameter
290 */
291 public RoleInfo(RoleInfo roleInfo) throws IllegalArgumentException {
292
293 if (roleInfo == null) {
294 // Revisit [cebro] Localize message
295 String excMsg = "Invalid parameter.";
296 throw new IllegalArgumentException(excMsg);
297 }
298
299 try {
300 init(roleInfo.getName(), roleInfo.getRefMBeanClassName(),
301 roleInfo.isReadable(), roleInfo.isWritable(),
302 roleInfo.getMinDegree(), roleInfo.getMaxDegree(),
303 roleInfo.getDescription());
304 } catch (InvalidRoleInfoException exc3) {
305 // OK : Can never happen as the minimum degree and the maximum
306 // degree were already checked at the time the roleInfo
307 // instance was created.
308 }
309 }
310
311 //
312 // Accessors
313 //
314
315 /**
316 * Returns the name of the role.
317 *
318 * @return the name of the role.
319 */
320 public String getName() {
321 return name;
322 }
323
324 /**
325 * Returns read access mode for the role (true if it is readable).
326 *
327 * @return true if the role is readable.
328 */
329 public boolean isReadable() {
330 return isReadable;
331 }
332
333 /**
334 * Returns write access mode for the role (true if it is writable).
335 *
336 * @return true if the role is writable.
337 */
338 public boolean isWritable() {
339 return isWritable;
340 }
341
342 /**
343 * Returns description text for the role.
344 *
345 * @return the description of the role.
346 */
347 public String getDescription() {
348 return description;
349 }
350
351 /**
352 * Returns minimum degree for corresponding role reference.
353 *
354 * @return the minimum degree.
355 */
356 public int getMinDegree() {
357 return minDegree;
358 }
359
360 /**
361 * Returns maximum degree for corresponding role reference.
362 *
363 * @return the maximum degree.
364 */
365 public int getMaxDegree() {
366 return maxDegree;
367 }
368
369 /**
370 * <p>Returns name of type of MBean expected to be referenced in
371 * corresponding role.</p>
372 *
373 * @return the name of the referenced type.
374 */
375 public String getRefMBeanClassName() {
376 return referencedMBeanClassName;
377 }
378
379 /**
380 * Returns true if the <tt>value</tt> parameter is greater than or equal to
381 * the expected minimum degree, false otherwise.
382 *
383 * @param value the value to be checked
384 *
385 * @return true if greater than or equal to minimum degree, false otherwise.
386 */
387 public boolean checkMinDegree(int value) {
388 if (value >= ROLE_CARDINALITY_INFINITY
389 && (minDegree == ROLE_CARDINALITY_INFINITY || value >= minDegree)) {
390 return true;
391 } else {
392 return false;
393 }
394 }
395
396 /**
397 * Returns true if the <tt>value</tt> parameter is lower than or equal to
398 * the expected maximum degree, false otherwise.
399 *
400 * @param value the value to be checked
401 *
402 * @return true if lower than or equal to maximum degree, false otherwise.
403 */
404 public boolean checkMaxDegree(int value) {
405 if (value >= ROLE_CARDINALITY_INFINITY
406 && (maxDegree == ROLE_CARDINALITY_INFINITY || (value != ROLE_CARDINALITY_INFINITY && value <= maxDegree))) {
407 return true;
408 } else {
409 return false;
410 }
411 }
412
413 /**
414 * Returns a string describing the role info.
415 *
416 * @return a description of the role info.
417 */
418 public String toString() {
419 StringBuilder result = new StringBuilder();
420 result.append("role info name: " + name);
421 result.append("; isReadable: " + isReadable);
422 result.append("; isWritable: " + isWritable);
423 result.append("; description: " + description);
424 result.append("; minimum degree: " + minDegree);
425 result.append("; maximum degree: " + maxDegree);
426 result.append("; MBean class: " + referencedMBeanClassName);
427 return result.toString();
428 }
429
430 //
431 // Misc
432 //
433
434 // Initialization
435 private void init(String roleName, String mbeanClassName,
436 boolean read, boolean write, int min, int max, String descr)
437 throws IllegalArgumentException, InvalidRoleInfoException {
438
439 if (roleName == null || mbeanClassName == null) {
440 // Revisit [cebro] Localize message
441 String excMsg = "Invalid parameter.";
442 throw new IllegalArgumentException(excMsg);
443 }
444
445 name = roleName;
446 isReadable = read;
447 isWritable = write;
448 if (descr != null) {
449 description = descr;
450 }
451
452 boolean invalidRoleInfoFlg = false;
453 StringBuilder excMsgStrB = new StringBuilder();
454 if (max != ROLE_CARDINALITY_INFINITY
455 && (min == ROLE_CARDINALITY_INFINITY || min > max)) {
456 // Revisit [cebro] Localize message
457 excMsgStrB.append("Minimum degree ");
458 excMsgStrB.append(min);
459 excMsgStrB.append(" is greater than maximum degree ");
460 excMsgStrB.append(max);
461 invalidRoleInfoFlg = true;
462
463 } else if (min < ROLE_CARDINALITY_INFINITY
464 || max < ROLE_CARDINALITY_INFINITY) {
465 // Revisit [cebro] Localize message
466 excMsgStrB
467 .append("Minimum or maximum degree has an illegal value, must be [0, ROLE_CARDINALITY_INFINITY].");
468 invalidRoleInfoFlg = true;
469 }
470 if (invalidRoleInfoFlg) {
471 throw new InvalidRoleInfoException(excMsgStrB.toString());
472 }
473 minDegree = min;
474 maxDegree = max;
475
476 referencedMBeanClassName = mbeanClassName;
477
478 return;
479 }
480
481 /**
482 * Deserializes a {@link RoleInfo} from an {@link ObjectInputStream}.
483 */
484 private void readObject(ObjectInputStream in) throws IOException,
485 ClassNotFoundException {
486 if (compat) {
487 // Read an object serialized in the old serial form
488 //
489 ObjectInputStream.GetField fields = in.readFields();
490 name = (String) fields.get("myName", null);
491 if (fields.defaulted("myName")) {
492 throw new NullPointerException("myName");
493 }
494 isReadable = fields.get("myIsReadableFlg", false);
495 if (fields.defaulted("myIsReadableFlg")) {
496 throw new NullPointerException("myIsReadableFlg");
497 }
498 isWritable = fields.get("myIsWritableFlg", false);
499 if (fields.defaulted("myIsWritableFlg")) {
500 throw new NullPointerException("myIsWritableFlg");
501 }
502 description = (String) fields.get("myDescription", null);
503 if (fields.defaulted("myDescription")) {
504 throw new NullPointerException("myDescription");
505 }
506 minDegree = fields.get("myMinDegree", 0);
507 if (fields.defaulted("myMinDegree")) {
508 throw new NullPointerException("myMinDegree");
509 }
510 maxDegree = fields.get("myMaxDegree", 0);
511 if (fields.defaulted("myMaxDegree")) {
512 throw new NullPointerException("myMaxDegree");
513 }
514 referencedMBeanClassName = (String) fields.get(
515 "myRefMBeanClassName", null);
516 if (fields.defaulted("myRefMBeanClassName")) {
517 throw new NullPointerException("myRefMBeanClassName");
518 }
519 } else {
520 // Read an object serialized in the new serial form
521 //
522 in.defaultReadObject();
523 }
524 }
525
526 /**
527 * Serializes a {@link RoleInfo} to an {@link ObjectOutputStream}.
528 */
529 private void writeObject(ObjectOutputStream out) throws IOException {
530 if (compat) {
531 // Serializes this instance in the old serial form
532 //
533 ObjectOutputStream.PutField fields = out.putFields();
534 fields.put("myName", name);
535 fields.put("myIsReadableFlg", isReadable);
536 fields.put("myIsWritableFlg", isWritable);
537 fields.put("myDescription", description);
538 fields.put("myMinDegree", minDegree);
539 fields.put("myMaxDegree", maxDegree);
540 fields.put("myRefMBeanClassName", referencedMBeanClassName);
541 out.writeFields();
542 } else {
543 // Serializes this instance in the new serial form
544 //
545 out.defaultWriteObject();
546 }
547 }
548
549 }
|