1/* 2 * Copyright (c) 2000, 2006, 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 26package javax.management.relation; 27 28 29import com.sun.jmx.mbeanserver.GetPropertyAction; 30 31import java.io.IOException; 32import java.io.ObjectInputStream; 33import java.io.ObjectOutputStream; 34import java.io.ObjectStreamField; 35import java.io.Serializable; 36import java.security.AccessController; 37 38import javax.management.MBeanServer; 39 40import javax.management.NotCompliantMBeanException; 41 42/** 43 * A RoleInfo object summarises a role in a relation type. 44 * 45 * <p>The <b>serialVersionUID</b> of this class is {@code 2504952983494636987L}. 46 * 47 * @since 1.5 48 */ 49@SuppressWarnings("serial") // serialVersionUID not constant 50public class RoleInfo implements Serializable { 51 52 // Serialization compatibility stuff: 53 // Two serial forms are supported in this class. The selected form depends 54 // on system property "jmx.serial.form": 55 // - "1.0" for JMX 1.0 56 // - any other value for JMX 1.1 and higher 57 // 58 // Serial version for old serial form 59 private static final long oldSerialVersionUID = 7227256952085334351L; 60 // 61 // Serial version for new serial form 62 private static final long newSerialVersionUID = 2504952983494636987L; 63 // 64 // Serializable fields in old serial form 65 private static final ObjectStreamField[] oldSerialPersistentFields = 66 { 67 new ObjectStreamField("myName", String.class), 68 new ObjectStreamField("myIsReadableFlg", boolean.class), 69 new ObjectStreamField("myIsWritableFlg", boolean.class), 70 new ObjectStreamField("myDescription", String.class), 71 new ObjectStreamField("myMinDegree", int.class), 72 new ObjectStreamField("myMaxDegree", int.class), 73 new ObjectStreamField("myRefMBeanClassName", String.class) 74 }; 75 // 76 // Serializable fields in new serial form 77 private static final ObjectStreamField[] newSerialPersistentFields = 78 { 79 new ObjectStreamField("name", String.class), 80 new ObjectStreamField("isReadable", boolean.class), 81 new ObjectStreamField("isWritable", boolean.class), 82 new ObjectStreamField("description", String.class), 83 new ObjectStreamField("minDegree", int.class), 84 new ObjectStreamField("maxDegree", int.class), 85 new ObjectStreamField("referencedMBeanClassName", String.class) 86 }; 87 // 88 // Actual serial version and serial form 89 private static final long serialVersionUID; 90 /** 91 * @serialField name String Role name 92 * @serialField isReadable boolean Read access mode: {@code true} if role is readable 93 * @serialField isWritable boolean Write access mode: {@code true} if role is writable 94 * @serialField description String Role description 95 * @serialField minDegree int Minimum degree (i.e. minimum number of referenced MBeans in corresponding role) 96 * @serialField maxDegree int Maximum degree (i.e. maximum number of referenced MBeans in corresponding role) 97 * @serialField referencedMBeanClassName String Name of class of MBean(s) expected to be referenced in corresponding role 98 */ 99 private static final ObjectStreamField[] serialPersistentFields; 100 private static boolean compat = false; 101 static { 102 try { 103 GetPropertyAction act = new GetPropertyAction("jmx.serial.form"); 104 String form = AccessController.doPrivileged(act); 105 compat = (form != null && form.equals("1.0")); 106 } catch (Exception e) { 107 // OK : Too bad, no compat with 1.0 108 } 109 if (compat) { 110 serialPersistentFields = oldSerialPersistentFields; 111 serialVersionUID = oldSerialVersionUID; 112 } else { 113 serialPersistentFields = newSerialPersistentFields; 114 serialVersionUID = newSerialVersionUID; 115 } 116 } 117 // 118 // END Serialization compatibility stuff 119 120 // 121 // Public constants 122 // 123 124 /** 125 * To specify an unlimited cardinality. 126 */ 127 public static final int ROLE_CARDINALITY_INFINITY = -1; 128 129 // 130 // Private members 131 // 132 133 /** 134 * @serial Role name 135 */ 136 private String name = null; 137 138 /** 139 * @serial Read access mode: {@code true} if role is readable 140 */ 141 private boolean isReadable; 142 143 /** 144 * @serial Write access mode: {@code true} if role is writable 145 */ 146 private boolean isWritable; 147 148 /** 149 * @serial Role description 150 */ 151 private String description = null; 152 153 /** 154 * @serial Minimum degree (i.e. minimum number of referenced MBeans in corresponding role) 155 */ 156 private int minDegree; 157 158 /** 159 * @serial Maximum degree (i.e. maximum number of referenced MBeans in corresponding role) 160 */ 161 private int maxDegree; 162 163 /** 164 * @serial Name of class of MBean(s) expected to be referenced in corresponding role 165 */ 166 private String referencedMBeanClassName = null; 167 168 // 169 // Constructors 170 // 171 172 /** 173 * Constructor. 174 * 175 * @param roleName name of the role. 176 * @param mbeanClassName name of the class of MBean(s) expected to 177 * be referenced in corresponding role. If an MBean <em>M</em> is in 178 * this role, then the MBean server must return true for 179 * {@link MBeanServer#isInstanceOf isInstanceOf(M, mbeanClassName)}. 180 * @param read flag to indicate if the corresponding role 181 * can be read 182 * @param write flag to indicate if the corresponding role 183 * can be set 184 * @param min minimum degree for role, i.e. minimum number of 185 * MBeans to provide in corresponding role 186 * Must be less than or equal to {@code max}. 187 * (ROLE_CARDINALITY_INFINITY for unlimited) 188 * @param max maximum degree for role, i.e. maximum number of 189 * MBeans to provide in corresponding role 190 * Must be greater than or equal to {@code min} 191 * (ROLE_CARDINALITY_INFINITY for unlimited) 192 * @param descr description of the role (can be null) 193 * 194 * @exception IllegalArgumentException if null parameter 195 * @exception InvalidRoleInfoException if the minimum degree is 196 * greater than the maximum degree. 197 * @exception ClassNotFoundException As of JMX 1.2, this exception 198 * can no longer be thrown. It is retained in the declaration of 199 * this class for compatibility with existing code. 200 * @exception NotCompliantMBeanException if the class mbeanClassName 201 * is not a MBean class. 202 */ 203 public RoleInfo(String roleName, 204 String mbeanClassName, 205 boolean read, 206 boolean write, 207 int min, 208 int max, 209 String descr) 210 throws IllegalArgumentException, 211 InvalidRoleInfoException, 212 ClassNotFoundException, 213 NotCompliantMBeanException { 214 215 init(roleName, 216 mbeanClassName, 217 read, 218 write, 219 min, 220 max, 221 descr); 222 return; 223 } 224 225 /** 226 * Constructor. 227 * 228 * @param roleName name of the role 229 * @param mbeanClassName name of the class of MBean(s) expected to 230 * be referenced in corresponding role. If an MBean <em>M</em> is in 231 * this role, then the MBean server must return true for 232 * {@link MBeanServer#isInstanceOf isInstanceOf(M, mbeanClassName)}. 233 * @param read flag to indicate if the corresponding role 234 * can be read 235 * @param write flag to indicate if the corresponding role 236 * can be set 237 * 238 * <P>Minimum and maximum degrees defaulted to 1. 239 * <P>Description of role defaulted to null. 240 * 241 * @exception IllegalArgumentException if null parameter 242 * @exception ClassNotFoundException As of JMX 1.2, this exception 243 * can no longer be thrown. It is retained in the declaration of 244 * this class for compatibility with existing code. 245 * @exception NotCompliantMBeanException As of JMX 1.2, this 246 * exception can no longer be thrown. It is retained in the 247 * declaration of this class for compatibility with existing code. 248 */ 249 public RoleInfo(String roleName, 250 String mbeanClassName, 251 boolean read, 252 boolean write) 253 throws IllegalArgumentException, 254 ClassNotFoundException, 255 NotCompliantMBeanException { 256 257 try { 258 init(roleName, 259 mbeanClassName, 260 read, 261 write, 262 1, 263 1, 264 null); 265 } catch (InvalidRoleInfoException exc) { 266 // OK : Can never happen as the minimum 267 // degree equals the maximum degree. 268 } 269 270 return; 271 } 272 273 /** 274 * Constructor. 275 * 276 * @param roleName name of the role 277 * @param mbeanClassName name of the class of MBean(s) expected to 278 * be referenced in corresponding role. If an MBean <em>M</em> is in 279 * this role, then the MBean server must return true for 280 * {@link MBeanServer#isInstanceOf isInstanceOf(M, mbeanClassName)}. 281 * 282 * <P>IsReadable and IsWritable defaulted to true. 283 * <P>Minimum and maximum degrees defaulted to 1. 284 * <P>Description of role defaulted to null. 285 * 286 * @exception IllegalArgumentException if null parameter 287 * @exception ClassNotFoundException As of JMX 1.2, this exception 288 * can no longer be thrown. It is retained in the declaration of 289 * this class for compatibility with existing code. 290 * @exception NotCompliantMBeanException As of JMX 1.2, this 291 * exception can no longer be thrown. It is retained in the 292 * declaration of this class for compatibility with existing code. 293 */ 294 public RoleInfo(String roleName, 295 String mbeanClassName) 296 throws IllegalArgumentException, 297 ClassNotFoundException, 298 NotCompliantMBeanException { 299 300 try { 301 init(roleName, 302 mbeanClassName, 303 true, 304 true, 305 1, 306 1, 307 null); 308 } catch (InvalidRoleInfoException exc) { 309 // OK : Can never happen as the minimum 310 // degree equals the maximum degree. 311 } 312 313 return; 314 } 315 316 /** 317 * Copy constructor. 318 * 319 * @param roleInfo the {@code RoleInfo} instance to be copied. 320 * 321 * @exception IllegalArgumentException if null parameter 322 */ 323 public RoleInfo(RoleInfo roleInfo) 324 throws IllegalArgumentException { 325 326 if (roleInfo == null) { 327 // Revisit [cebro] Localize message 328 String excMsg = "Invalid parameter."; 329 throw new IllegalArgumentException(excMsg); 330 } 331 332 try { 333 init(roleInfo.getName(), 334 roleInfo.getRefMBeanClassName(), 335 roleInfo.isReadable(), 336 roleInfo.isWritable(), 337 roleInfo.getMinDegree(), 338 roleInfo.getMaxDegree(), 339 roleInfo.getDescription()); 340 } catch (InvalidRoleInfoException exc3) { 341 // OK : Can never happen as the minimum degree and the maximum 342 // degree were already checked at the time the roleInfo 343 // instance was created. 344 } 345 } 346 347 // 348 // Accessors 349 // 350 351 /** 352 * Returns the name of the role. 353 * 354 * @return the name of the role. 355 */ 356 public String getName() { 357 return name; 358 } 359 360 /** 361 * Returns read access mode for the role (true if it is readable). 362 * 363 * @return true if the role is readable. 364 */ 365 public boolean isReadable() { 366 return isReadable; 367 } 368 369 /** 370 * Returns write access mode for the role (true if it is writable). 371 * 372 * @return true if the role is writable. 373 */ 374 public boolean isWritable() { 375 return isWritable; 376 } 377 378 /** 379 * Returns description text for the role. 380 * 381 * @return the description of the role. 382 */ 383 public String getDescription() { 384 return description; 385 } 386 387 /** 388 * Returns minimum degree for corresponding role reference. 389 * 390 * @return the minimum degree. 391 */ 392 public int getMinDegree() { 393 return minDegree; 394 } 395 396 /** 397 * Returns maximum degree for corresponding role reference. 398 * 399 * @return the maximum degree. 400 */ 401 public int getMaxDegree() { 402 return maxDegree; 403 } 404 405 /** 406 * <p>Returns name of type of MBean expected to be referenced in 407 * corresponding role.</p> 408 * 409 * @return the name of the referenced type. 410 */ 411 public String getRefMBeanClassName() { 412 return referencedMBeanClassName; 413 } 414 415 /** 416 * Returns true if the {@code value} parameter is greater than or equal to 417 * the expected minimum degree, false otherwise. 418 * 419 * @param value the value to be checked 420 * 421 * @return true if greater than or equal to minimum degree, false otherwise. 422 */ 423 public boolean checkMinDegree(int value) { 424 if (value >= ROLE_CARDINALITY_INFINITY && 425 (minDegree == ROLE_CARDINALITY_INFINITY 426 || value >= minDegree)) { 427 return true; 428 } else { 429 return false; 430 } 431 } 432 433 /** 434 * Returns true if the {@code value} parameter is lower than or equal to 435 * the expected maximum degree, false otherwise. 436 * 437 * @param value the value to be checked 438 * 439 * @return true if lower than or equal to maximum degree, false otherwise. 440 */ 441 public boolean checkMaxDegree(int value) { 442 if (value >= ROLE_CARDINALITY_INFINITY && 443 (maxDegree == ROLE_CARDINALITY_INFINITY || 444 (value != ROLE_CARDINALITY_INFINITY && 445 value <= maxDegree))) { 446 return true; 447 } else { 448 return false; 449 } 450 } 451 452 /** 453 * Returns a string describing the role info. 454 * 455 * @return a description of the role info. 456 */ 457 public String toString() { 458 StringBuilder result = new StringBuilder(); 459 result.append("role info name: " + name); 460 result.append("; isReadable: " + isReadable); 461 result.append("; isWritable: " + isWritable); 462 result.append("; description: " + description); 463 result.append("; minimum degree: " + minDegree); 464 result.append("; maximum degree: " + maxDegree); 465 result.append("; MBean class: " + referencedMBeanClassName); 466 return result.toString(); 467 } 468 469 // 470 // Misc 471 // 472 473 // Initialization 474 private void init(String roleName, 475 String mbeanClassName, 476 boolean read, 477 boolean write, 478 int min, 479 int max, 480 String descr) 481 throws IllegalArgumentException, 482 InvalidRoleInfoException { 483 484 if (roleName == null || 485 mbeanClassName == null) { 486 // Revisit [cebro] Localize message 487 String excMsg = "Invalid parameter."; 488 throw new IllegalArgumentException(excMsg); 489 } 490 491 name = roleName; 492 isReadable = read; 493 isWritable = write; 494 if (descr != null) { 495 description = descr; 496 } 497 498 boolean invalidRoleInfoFlg = false; 499 StringBuilder excMsgStrB = new StringBuilder(); 500 if (max != ROLE_CARDINALITY_INFINITY && 501 (min == ROLE_CARDINALITY_INFINITY || 502 min > max)) { 503 // Revisit [cebro] Localize message 504 excMsgStrB.append("Minimum degree "); 505 excMsgStrB.append(min); 506 excMsgStrB.append(" is greater than maximum degree "); 507 excMsgStrB.append(max); 508 invalidRoleInfoFlg = true; 509 510 } else if (min < ROLE_CARDINALITY_INFINITY || 511 max < ROLE_CARDINALITY_INFINITY) { 512 // Revisit [cebro] Localize message 513 excMsgStrB.append("Minimum or maximum degree has an illegal value, must be [0, ROLE_CARDINALITY_INFINITY]."); 514 invalidRoleInfoFlg = true; 515 } 516 if (invalidRoleInfoFlg) { 517 throw new InvalidRoleInfoException(excMsgStrB.toString()); 518 } 519 minDegree = min; 520 maxDegree = max; 521 522 referencedMBeanClassName = mbeanClassName; 523 524 return; 525 } 526 527 /** 528 * Deserializes a {@link RoleInfo} from an {@link ObjectInputStream}. 529 */ 530 private void readObject(ObjectInputStream in) 531 throws IOException, ClassNotFoundException { 532 if (compat) 533 { 534 // Read an object serialized in the old serial form 535 // 536 ObjectInputStream.GetField fields = in.readFields(); 537 name = (String) fields.get("myName", null); 538 if (fields.defaulted("myName")) 539 { 540 throw new NullPointerException("myName"); 541 } 542 isReadable = fields.get("myIsReadableFlg", false); 543 if (fields.defaulted("myIsReadableFlg")) 544 { 545 throw new NullPointerException("myIsReadableFlg"); 546 } 547 isWritable = fields.get("myIsWritableFlg", false); 548 if (fields.defaulted("myIsWritableFlg")) 549 { 550 throw new NullPointerException("myIsWritableFlg"); 551 } 552 description = (String) fields.get("myDescription", null); 553 if (fields.defaulted("myDescription")) 554 { 555 throw new NullPointerException("myDescription"); 556 } 557 minDegree = fields.get("myMinDegree", 0); 558 if (fields.defaulted("myMinDegree")) 559 { 560 throw new NullPointerException("myMinDegree"); 561 } 562 maxDegree = fields.get("myMaxDegree", 0); 563 if (fields.defaulted("myMaxDegree")) 564 { 565 throw new NullPointerException("myMaxDegree"); 566 } 567 referencedMBeanClassName = (String) fields.get("myRefMBeanClassName", null); 568 if (fields.defaulted("myRefMBeanClassName")) 569 { 570 throw new NullPointerException("myRefMBeanClassName"); 571 } 572 } 573 else 574 { 575 // Read an object serialized in the new serial form 576 // 577 in.defaultReadObject(); 578 } 579 } 580 581 582 /** 583 * Serializes a {@link RoleInfo} to an {@link ObjectOutputStream}. 584 */ 585 private void writeObject(ObjectOutputStream out) 586 throws IOException { 587 if (compat) 588 { 589 // Serializes this instance in the old serial form 590 // 591 ObjectOutputStream.PutField fields = out.putFields(); 592 fields.put("myName", name); 593 fields.put("myIsReadableFlg", isReadable); 594 fields.put("myIsWritableFlg", isWritable); 595 fields.put("myDescription", description); 596 fields.put("myMinDegree", minDegree); 597 fields.put("myMaxDegree", maxDegree); 598 fields.put("myRefMBeanClassName", referencedMBeanClassName); 599 out.writeFields(); 600 } 601 else 602 { 603 // Serializes this instance in the new serial form 604 // 605 out.defaultWriteObject(); 606 } 607 } 608 609} 610