001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2007-2008 Sun Microsystems, Inc. 026 */ 027 028 package org.opends.server.admin; 029 030 031 032 import java.util.ArrayList; 033 import java.util.Collection; 034 import java.util.Collections; 035 import java.util.EnumSet; 036 import java.util.HashMap; 037 import java.util.HashSet; 038 import java.util.LinkedList; 039 import java.util.List; 040 import java.util.Locale; 041 import java.util.Map; 042 import java.util.MissingResourceException; 043 import java.util.Set; 044 045 import java.util.Vector; 046 import org.opends.messages.Message; 047 import org.opends.server.admin.DefinitionDecodingException.Reason; 048 049 050 051 /** 052 * Defines the structure of an abstract managed object. Abstract managed objects 053 * cannot be instantiated. 054 * <p> 055 * Applications can query a managed object definition in order to determine the 056 * overall configuration model of an application. 057 * 058 * @param <C> 059 * The type of client managed object configuration that this definition 060 * represents. 061 * @param <S> 062 * The type of server managed object configuration that this definition 063 * represents. 064 */ 065 public abstract class AbstractManagedObjectDefinition 066 <C extends ConfigurationClient, S extends Configuration> { 067 068 // The name of the definition. 069 private final String name; 070 071 // The parent managed object definition if applicable. 072 private final AbstractManagedObjectDefinition<? super C, ? super S> parent; 073 074 // The set of constraints associated with this managed object 075 // definition. 076 private final Collection<Constraint> constraints; 077 078 // The set of property definitions applicable to this managed object 079 // definition. 080 private final Map<String, PropertyDefinition<?>> propertyDefinitions; 081 082 // The set of relation definitions applicable to this managed object 083 // definition. 084 private final Map<String, RelationDefinition<?, ?>> relationDefinitions; 085 086 // The set of relation definitions directly referencing this managed 087 // object definition. 088 private final Set<RelationDefinition<C, S>> reverseRelationDefinitions; 089 090 // The set of all property definitions associated with this managed 091 // object definition including inherited property definitions. 092 private final Map<String, PropertyDefinition<?>> allPropertyDefinitions; 093 094 // The set of all relation definitions associated with this managed 095 // object definition including inherited relation definitions. 096 private final Map<String, RelationDefinition<?, ?>> allRelationDefinitions; 097 098 // The set of aggregation property definitions applicable to this 099 // managed object definition. 100 private final Map<String, AggregationPropertyDefinition<?, ?>> 101 aggregationPropertyDefinitions; 102 103 // The set of aggregation property definitions directly referencing this 104 // managed object definition. 105 private final Vector<AggregationPropertyDefinition<?, ?>> 106 reverseAggregationPropertyDefinitions; 107 108 // The set of all aggregation property definitions associated with this 109 // managed object definition including inherited relation definitions. 110 private final Map<String, AggregationPropertyDefinition<?, ?>> 111 allAggregationPropertyDefinitions; 112 113 // The set of tags associated with this managed object. 114 private final Set<Tag> allTags; 115 116 // Options applicable to this definition. 117 private final Set<ManagedObjectOption> options; 118 119 // The set of managed object definitions which inherit from this definition. 120 private final Map<String, 121 AbstractManagedObjectDefinition<? extends C, ? extends S>> children; 122 123 124 125 /** 126 * Create a new abstract managed object definition. 127 * 128 * @param name 129 * The name of the definition. 130 * @param parent 131 * The parent definition, or <code>null</code> if there 132 * is no parent (only the {@link TopCfgDefn} should have a 133 * <code>null</code> parent, unless the definition is 134 * being used for testing). 135 */ 136 protected AbstractManagedObjectDefinition(String name, 137 AbstractManagedObjectDefinition<? super C, ? super S> parent) { 138 this.name = name; 139 this.parent = parent; 140 this.constraints = new LinkedList<Constraint>(); 141 this.propertyDefinitions = new HashMap<String, PropertyDefinition<?>>(); 142 this.relationDefinitions = new HashMap<String, RelationDefinition<?,?>>(); 143 this.reverseRelationDefinitions = new HashSet<RelationDefinition<C,S>>(); 144 this.allPropertyDefinitions = new HashMap<String, PropertyDefinition<?>>(); 145 this.allRelationDefinitions = 146 new HashMap<String, RelationDefinition<?, ?>>(); 147 this.aggregationPropertyDefinitions = 148 new HashMap<String, AggregationPropertyDefinition<?,?>>(); 149 this.reverseAggregationPropertyDefinitions = 150 new Vector<AggregationPropertyDefinition<?,?>>(); 151 this.allAggregationPropertyDefinitions = 152 new HashMap<String, AggregationPropertyDefinition<?, ?>>(); 153 this.allTags = new HashSet<Tag>(); 154 this.options = EnumSet.noneOf(ManagedObjectOption.class); 155 156 this.children = new HashMap<String, 157 AbstractManagedObjectDefinition<? extends C, ? extends S>>(); 158 159 // If we have a parent definition then inherit its features. 160 if (parent != null) { 161 registerInParent(); 162 163 for (PropertyDefinition<?> pd : parent.getAllPropertyDefinitions()) { 164 allPropertyDefinitions.put(pd.getName(), pd); 165 } 166 167 for (RelationDefinition<?, ?> rd : parent.getAllRelationDefinitions()) { 168 allRelationDefinitions.put(rd.getName(), rd); 169 } 170 171 for (AggregationPropertyDefinition<?, ?> apd : 172 parent.getAllAggregationPropertyDefinitions()) { 173 174 allAggregationPropertyDefinitions.put(apd.getName(), apd); 175 } 176 177 // Tag inheritance is performed during preprocessing. 178 } 179 } 180 181 182 183 /** 184 * Get all the child managed object definitions which inherit from 185 * this managed object definition. 186 * 187 * @return Returns an unmodifiable collection containing all the 188 * subordinate managed object definitions which inherit from 189 * this managed object definition. 190 */ 191 public final Collection<AbstractManagedObjectDefinition 192 <? extends C, ? extends S>> getAllChildren() { 193 List<AbstractManagedObjectDefinition<? extends C, ? extends S>> list = 194 new ArrayList<AbstractManagedObjectDefinition<? extends C, ? extends S>>( 195 children.values()); 196 197 for (AbstractManagedObjectDefinition<? extends C, ? extends S> child : 198 children.values()) { 199 list.addAll(child.getAllChildren()); 200 } 201 202 return Collections.unmodifiableCollection(list); 203 } 204 205 206 207 /** 208 * Get all the constraints associated with this type of managed 209 * object. The returned collection will contain inherited 210 * constraints. 211 * 212 * @return Returns a collection containing all the constraints 213 * associated with this type of managed object. The caller 214 * is free to modify the collection if required. 215 */ 216 public final Collection<Constraint> getAllConstraints() { 217 // This method does not used a cached set of constraints because 218 // constraints may be updated after child definitions have been 219 // defined. 220 List<Constraint> allConstraints = new LinkedList<Constraint>(); 221 222 if (parent != null) { 223 allConstraints.addAll(parent.getAllConstraints()); 224 } 225 allConstraints.addAll(constraints); 226 227 return allConstraints; 228 } 229 230 231 232 /** 233 * Get all the property definitions associated with this type of 234 * managed object. The returned collection will contain inherited 235 * property definitions. 236 * 237 * @return Returns an unmodifiable collection containing all the 238 * property definitions associated with this type of managed 239 * object. 240 */ 241 public final Collection<PropertyDefinition<?>> getAllPropertyDefinitions() { 242 return Collections.unmodifiableCollection(allPropertyDefinitions.values()); 243 } 244 245 246 247 /** 248 * Get all the relation definitions associated with this type of 249 * managed object. The returned collection will contain inherited 250 * relation definitions. 251 * 252 * @return Returns an unmodifiable collection containing all the 253 * relation definitions associated with this type of managed 254 * object. 255 */ 256 public final Collection<RelationDefinition<?, ?>> 257 getAllRelationDefinitions() { 258 return Collections.unmodifiableCollection(allRelationDefinitions.values()); 259 } 260 261 262 263 /** 264 * Get all the relation definitions which refer to this managed 265 * object definition. The returned collection will contain relation 266 * definitions which refer to parents of this managed object 267 * definition. 268 * 269 * @return Returns a collection containing all the relation 270 * definitions which refer to this managed object 271 * definition. The caller is free to modify the collection 272 * if required. 273 */ 274 public final Collection<RelationDefinition<? super C, ? super S>> 275 getAllReverseRelationDefinitions() { 276 // This method does not used a cached set of relations because 277 // relations may be updated after child definitions have been 278 // defined. 279 List<RelationDefinition<? super C, ? super S>> rdlist = 280 new LinkedList<RelationDefinition<? super C, ? super S>>(); 281 282 if (parent != null) { 283 rdlist.addAll(parent.getAllReverseRelationDefinitions()); 284 } 285 rdlist.addAll(reverseRelationDefinitions); 286 287 return rdlist; 288 } 289 290 291 292 /** 293 * Get all the aggregation property definitions associated with this type of 294 * managed object. The returned collection will contain inherited 295 * aggregation property definitions. 296 * 297 * @return Returns an unmodifiable collection containing all the 298 * aggregation property definitions associated with this type of 299 * managed object. 300 */ 301 public final Collection<AggregationPropertyDefinition<?, ?>> 302 getAllAggregationPropertyDefinitions() { 303 return Collections.unmodifiableCollection( 304 allAggregationPropertyDefinitions.values()); 305 } 306 307 308 309 /** 310 * Get all the aggregation property definitions which refer to this managed 311 * object definition. The returned collection will contain aggregation 312 * property definitions which refer to parents of this managed object 313 * definition. 314 * 315 * @return Returns a collection containing all the aggregation property 316 * definitions which refer to this managed object 317 * definition. The caller is free to modify the collection 318 * if required. 319 */ 320 public final Collection<AggregationPropertyDefinition<?, ?>> 321 getAllReverseAggregationPropertyDefinitions() { 322 // This method does not used a cached set of aggregation properties because 323 // aggregation properties may be updated after child definitions have been 324 // defined. 325 List<AggregationPropertyDefinition<?, ?>> apdlist = 326 new LinkedList<AggregationPropertyDefinition<?, ?>>(); 327 328 if (parent != null) { 329 apdlist.addAll(parent.getAllReverseAggregationPropertyDefinitions()); 330 } 331 apdlist.addAll(reverseAggregationPropertyDefinitions); 332 333 return apdlist; 334 } 335 336 337 338 /** 339 * Get all the tags associated with this type of managed object. The 340 * returned collection will contain inherited tags. 341 * 342 * @return Returns an unmodifiable collection containing all the 343 * tags associated with this type of managed object. 344 */ 345 public final Collection<Tag> getAllTags() { 346 return Collections.unmodifiableCollection(allTags); 347 } 348 349 350 351 /** 352 * Get the named child managed object definition which inherits from 353 * this managed object definition. This method will recursively 354 * search down through the inheritance hierarchy. 355 * 356 * @param name 357 * The name of the managed object definition sub-type. 358 * @return Returns the named child managed object definition which 359 * inherits from this managed object definition. 360 * @throws IllegalArgumentException 361 * If the specified managed object definition name was 362 * null or empty or if the requested subordinate managed 363 * object definition was not found. 364 */ 365 public final AbstractManagedObjectDefinition<? extends C, ? extends S> 366 getChild(String name) throws IllegalArgumentException { 367 if ((name == null) || (name.length() == 0)) { 368 throw new IllegalArgumentException("null or empty managed object name"); 369 } 370 371 AbstractManagedObjectDefinition<? extends C, ? extends S> d = children 372 .get(name); 373 374 if (d == null) { 375 // Recursively search. 376 for (AbstractManagedObjectDefinition<? extends C, ? extends S> child : 377 children.values()) { 378 try { 379 d = child.getChild(name); 380 break; 381 } catch (IllegalArgumentException e) { 382 // Try the next child. 383 } 384 } 385 } 386 387 if (d == null) { 388 throw new IllegalArgumentException("child managed object definition \"" 389 + name + "\" not found"); 390 } 391 392 return d; 393 } 394 395 396 397 /** 398 * Get the child managed object definitions which inherit directly 399 * from this managed object definition. 400 * 401 * @return Returns an unmodifiable collection containing the 402 * subordinate managed object definitions which inherit 403 * directly from this managed object definition. 404 */ 405 public final Collection<AbstractManagedObjectDefinition 406 <? extends C, ? extends S>> getChildren() { 407 return Collections.unmodifiableCollection(children.values()); 408 } 409 410 411 412 /** 413 * Get the constraints defined by this managed object definition. 414 * The returned collection will not contain inherited constraints. 415 * 416 * @return Returns an unmodifiable collection containing the 417 * constraints defined by this managed object definition. 418 */ 419 public final Collection<Constraint> getConstraints() { 420 return Collections.unmodifiableCollection(constraints); 421 } 422 423 424 425 /** 426 * Gets the optional description of this managed object definition 427 * in the default locale. 428 * 429 * @return Returns the description of this managed object definition 430 * in the default locale, or <code>null</code> if there is 431 * no description. 432 * @throws UnsupportedOperationException 433 * If this managed object definition is the 434 * {@link TopCfgDefn}. 435 */ 436 public final Message getDescription() throws UnsupportedOperationException { 437 return getDescription(Locale.getDefault()); 438 } 439 440 441 442 /** 443 * Gets the optional description of this managed object definition 444 * in the specified locale. 445 * 446 * @param locale 447 * The locale. 448 * @return Returns the description of this managed object definition 449 * in the specified locale, or <code>null</code> if there 450 * is no description. 451 * @throws UnsupportedOperationException 452 * If this managed object definition is the 453 * {@link TopCfgDefn}. 454 */ 455 public final Message getDescription(Locale locale) 456 throws UnsupportedOperationException { 457 try { 458 return ManagedObjectDefinitionI18NResource.getInstance() 459 .getMessage(this, "description", locale); 460 } catch (MissingResourceException e) { 461 return null; 462 } 463 } 464 465 466 467 /** 468 * Get the name of the definition. 469 * 470 * @return Returns the name of the definition. 471 */ 472 public final String getName() { 473 return name; 474 } 475 476 477 478 /** 479 * Get the parent managed object definition, if applicable. 480 * 481 * @return Returns the parent of this managed object definition, or 482 * <code>null</code> if this definition is the 483 * {@link TopCfgDefn}. 484 */ 485 public final AbstractManagedObjectDefinition<? super C, 486 ? super S> getParent() { 487 return parent; 488 } 489 490 491 492 /** 493 * Get the specified property definition associated with this type 494 * of managed object. The search will include any inherited property 495 * definitions. 496 * 497 * @param name 498 * The name of the property definition to be retrieved. 499 * @return Returns the specified property definition associated with 500 * this type of managed object. 501 * @throws IllegalArgumentException 502 * If the specified property name was null or empty or if 503 * the requested property definition was not found. 504 */ 505 public final PropertyDefinition<?> getPropertyDefinition(String name) 506 throws IllegalArgumentException { 507 if ((name == null) || (name.length() == 0)) { 508 throw new IllegalArgumentException("null or empty property name"); 509 } 510 511 PropertyDefinition<?> d = allPropertyDefinitions.get(name); 512 if (d == null) { 513 throw new IllegalArgumentException("property definition \"" + name 514 + "\" not found"); 515 } 516 517 return d; 518 } 519 520 521 522 /** 523 * Get the property definitions defined by this managed object 524 * definition. The returned collection will not contain inherited 525 * property definitions. 526 * 527 * @return Returns an unmodifiable collection containing the 528 * property definitions defined by this managed object 529 * definition. 530 */ 531 public final Collection<PropertyDefinition<?>> getPropertyDefinitions() { 532 return Collections.unmodifiableCollection(propertyDefinitions 533 .values()); 534 } 535 536 537 538 /** 539 * Get the specified relation definition associated with this type 540 * of managed object.The search will include any inherited relation 541 * definitions. 542 * 543 * @param name 544 * The name of the relation definition to be retrieved. 545 * @return Returns the specified relation definition associated with 546 * this type of managed object. 547 * @throws IllegalArgumentException 548 * If the specified relation name was null or empty or if 549 * the requested relation definition was not found. 550 */ 551 public final RelationDefinition<?, ?> getRelationDefinition(String name) 552 throws IllegalArgumentException { 553 if ((name == null) || (name.length() == 0)) { 554 throw new IllegalArgumentException("null or empty relation name"); 555 } 556 557 RelationDefinition<?, ?> d = allRelationDefinitions.get(name); 558 if (d == null) { 559 throw new IllegalArgumentException("relation definition \"" + name 560 + "\" not found"); 561 } 562 563 return d; 564 } 565 566 567 568 /** 569 * Get the relation definitions defined by this managed object 570 * definition. The returned collection will not contain inherited 571 * relation definitions. 572 * 573 * @return Returns an unmodifiable collection containing the 574 * relation definitions defined by this managed object 575 * definition. 576 */ 577 public final Collection<RelationDefinition<?,?>> getRelationDefinitions() { 578 return Collections.unmodifiableCollection(relationDefinitions.values()); 579 } 580 581 582 583 /** 584 * Get the relation definitions which refer directly to this managed 585 * object definition. The returned collection will not contain 586 * relation definitions which refer to parents of this managed 587 * object definition. 588 * 589 * @return Returns an unmodifiable collection containing the 590 * relation definitions which refer directly to this managed 591 * object definition. 592 */ 593 public final Collection<RelationDefinition<C, S>> 594 getReverseRelationDefinitions() { 595 return Collections.unmodifiableCollection(reverseRelationDefinitions); 596 } 597 598 599 600 /** 601 * Get the specified aggregation property definition associated with this type 602 * of managed object.The search will include any inherited aggregation 603 * property definitions. 604 * 605 * @param name 606 * The name of the aggregation property definition to be retrieved. 607 * @return Returns the specified aggregation property definition associated 608 * with this type of managed object. 609 * @throws IllegalArgumentException 610 * If the specified aggregation property name was null or empty or 611 * if the requested aggregation property definition was not found. 612 */ 613 public final AggregationPropertyDefinition<?, ?> 614 getAggregationPropertyDefinition(String name) 615 throws IllegalArgumentException { 616 if ((name == null) || (name.length() == 0)) { 617 throw new IllegalArgumentException( 618 "null or empty aggregation property name"); 619 } 620 621 AggregationPropertyDefinition<?, ?> d = 622 allAggregationPropertyDefinitions.get(name); 623 if (d == null) { 624 throw new IllegalArgumentException("aggregation property definition \"" 625 + name + "\" not found"); 626 } 627 628 return d; 629 } 630 631 /** 632 * Get the aggregation property definitions defined by this managed object 633 * definition. The returned collection will not contain inherited 634 * aggregation property definitions. 635 * 636 * @return Returns an unmodifiable collection containing the 637 * aggregation property definitions defined by this managed object 638 * definition. 639 */ 640 public final Collection<AggregationPropertyDefinition<?, ?>> 641 getAggregationPropertyDefinitions() { 642 return Collections.unmodifiableCollection( 643 aggregationPropertyDefinitions.values()); 644 } 645 646 /** 647 * Get the aggregation property definitions which refer directly to this 648 * managed object definition. The returned collection will not contain 649 * aggregation property definitions which refer to parents of this managed 650 * object definition. 651 * 652 * @return Returns an unmodifiable collection containing the 653 * aggregation property definitions which refer directly to this 654 * managed object definition. 655 */ 656 public final Collection<AggregationPropertyDefinition<?, ?>> 657 getReverseAggregationPropertyDefinitions() { 658 return Collections.unmodifiableCollection( 659 reverseAggregationPropertyDefinitions); 660 } 661 662 /** 663 * Gets the synopsis of this managed object definition in the 664 * default locale. 665 * 666 * @return Returns the synopsis of this managed object definition in 667 * the default locale. 668 * @throws UnsupportedOperationException 669 * If this managed object definition is the 670 * {@link TopCfgDefn}. 671 */ 672 public final Message getSynopsis() throws UnsupportedOperationException { 673 return getSynopsis(Locale.getDefault()); 674 } 675 676 677 678 /** 679 * Gets the synopsis of this managed object definition in the 680 * specified locale. 681 * 682 * @param locale 683 * The locale. 684 * @return Returns the synopsis of this managed object definition in 685 * the specified locale. 686 * @throws UnsupportedOperationException 687 * If this managed object definition is the 688 * {@link TopCfgDefn}. 689 */ 690 public final Message getSynopsis(Locale locale) 691 throws UnsupportedOperationException { 692 return ManagedObjectDefinitionI18NResource.getInstance() 693 .getMessage(this, "synopsis", locale); 694 } 695 696 697 698 /** 699 * Gets the user friendly name of this managed object definition in 700 * the default locale. 701 * 702 * @return Returns the user friendly name of this managed object 703 * definition in the default locale. 704 * @throws UnsupportedOperationException 705 * If this managed object definition is the 706 * {@link TopCfgDefn}. 707 */ 708 public final Message getUserFriendlyName() 709 throws UnsupportedOperationException { 710 return getUserFriendlyName(Locale.getDefault()); 711 } 712 713 714 715 /** 716 * Gets the user friendly name of this managed object definition in 717 * the specified locale. 718 * 719 * @param locale 720 * The locale. 721 * @return Returns the user friendly name of this managed object 722 * definition in the specified locale. 723 * @throws UnsupportedOperationException 724 * If this managed object definition is the 725 * {@link TopCfgDefn}. 726 */ 727 public final Message getUserFriendlyName(Locale locale) 728 throws UnsupportedOperationException { 729 // TODO: have admin framework getMessage return a Message 730 return Message.raw(ManagedObjectDefinitionI18NResource.getInstance() 731 .getMessage(this, "user-friendly-name", locale)); 732 } 733 734 735 736 /** 737 * Gets the user friendly plural name of this managed object 738 * definition in the default locale. 739 * 740 * @return Returns the user friendly plural name of this managed 741 * object definition in the default locale. 742 * @throws UnsupportedOperationException 743 * If this managed object definition is the 744 * {@link TopCfgDefn}. 745 */ 746 public final Message getUserFriendlyPluralName() 747 throws UnsupportedOperationException { 748 return getUserFriendlyPluralName(Locale.getDefault()); 749 } 750 751 752 753 /** 754 * Gets the user friendly plural name of this managed object 755 * definition in the specified locale. 756 * 757 * @param locale 758 * The locale. 759 * @return Returns the user friendly plural name of this managed 760 * object definition in the specified locale. 761 * @throws UnsupportedOperationException 762 * If this managed object definition is the 763 * {@link TopCfgDefn}. 764 */ 765 public final Message getUserFriendlyPluralName(Locale locale) 766 throws UnsupportedOperationException { 767 return ManagedObjectDefinitionI18NResource.getInstance() 768 .getMessage(this, "user-friendly-plural-name", locale); 769 } 770 771 772 773 /** 774 * Determine whether there are any child managed object definitions which 775 * inherit from this managed object definition. 776 * 777 * @return Returns <code>true</code> if this type of managed object has any 778 * child managed object definitions, <code>false</code> otherwise. 779 */ 780 public final boolean hasChildren() { 781 return !children.isEmpty(); 782 } 783 784 785 786 /** 787 * Determines whether or not this managed object definition has the 788 * specified option. 789 * 790 * @param option 791 * The option to test. 792 * @return Returns <code>true</code> if the option is set, or 793 * <code>false</code> otherwise. 794 */ 795 public final boolean hasOption(ManagedObjectOption option) { 796 return options.contains(option); 797 } 798 799 800 801 /** 802 * Determines whether or not this managed object definition has the 803 * specified tag. 804 * 805 * @param t 806 * The tag definition. 807 * @return Returns <code>true</code> if this managed object 808 * definition has the specified tag. 809 */ 810 public final boolean hasTag(Tag t) { 811 return allTags.contains(t); 812 } 813 814 815 816 /** 817 * Determines whether or not this managed object definition is a 818 * sub-type of the provided managed object definition. This managed 819 * object definition is a sub-type of the provided managed object 820 * definition if they are both the same or if the provided managed 821 * object definition can be obtained by recursive invocations of the 822 * {@link #getParent()} method. 823 * 824 * @param d 825 * The managed object definition to be checked. 826 * @return Returns <code>true</code> if this managed object 827 * definition is a sub-type of the provided managed object 828 * definition. 829 */ 830 public final boolean isChildOf(AbstractManagedObjectDefinition<?, ?> d) { 831 AbstractManagedObjectDefinition<?, ?> i; 832 for (i = this; i != null; i = i.parent) { 833 if (i == d) { 834 return true; 835 } 836 } 837 return false; 838 } 839 840 841 842 /** 843 * Determines whether or not this managed object definition is a 844 * super-type of the provided managed object definition. This 845 * managed object definition is a super-type of the provided managed 846 * object definition if they are both the same or if the provided 847 * managed object definition is a member of the set of children 848 * returned from {@link #getAllChildren()}. 849 * 850 * @param d 851 * The managed object definition to be checked. 852 * @return Returns <code>true</code> if this managed object 853 * definition is a super-type of the provided managed object 854 * definition. 855 */ 856 public final boolean isParentOf(AbstractManagedObjectDefinition<?, ?> d) { 857 return d.isChildOf(this); 858 } 859 860 861 862 /** 863 * Determines whether or not this managed object definition is the 864 * {@link TopCfgDefn}. 865 * 866 * @return Returns <code>true</code> if this managed object 867 * definition is the {@link TopCfgDefn}. 868 */ 869 public final boolean isTop() { 870 // Casting to Object and instanceof check are required 871 // to workaround a bug in JDK versions prior to 1.5.0_08. 872 return ((Object) this instanceof TopCfgDefn); 873 } 874 875 876 877 /** 878 * Finds a sub-type of this managed object definition which most closely 879 * corresponds to the matching criteria of the provided definition resolver. 880 * 881 * @param r 882 * The definition resolver. 883 * @return Returns the sub-type of this managed object definition which most 884 * closely corresponds to the matching criteria of the provided 885 * definition resolver. 886 * @throws DefinitionDecodingException 887 * If no matching sub-type could be found or if the resolved 888 * definition was abstract. 889 * @see DefinitionResolver 890 */ 891 @SuppressWarnings("unchecked") 892 public final ManagedObjectDefinition<? extends C, ? extends S> 893 resolveManagedObjectDefinition( 894 DefinitionResolver r) throws DefinitionDecodingException { 895 AbstractManagedObjectDefinition<? extends C, ? extends S> rd; 896 rd = resolveManagedObjectDefinitionAux(this, r); 897 if (rd == null) { 898 // Unable to resolve the definition. 899 throw new DefinitionDecodingException(this, 900 Reason.WRONG_TYPE_INFORMATION); 901 } else if (rd instanceof ManagedObjectDefinition) { 902 return (ManagedObjectDefinition<? extends C, ? extends S>) rd; 903 } else { 904 // Resolved definition was abstract. 905 throw new DefinitionDecodingException(this, 906 Reason.ABSTRACT_TYPE_INFORMATION); 907 } 908 } 909 910 911 912 /** 913 * {@inheritDoc} 914 */ 915 @Override 916 public final String toString() { 917 StringBuilder builder = new StringBuilder(); 918 toString(builder); 919 return builder.toString(); 920 } 921 922 923 924 /** 925 * Append a string representation of the managed object definition to the 926 * provided string builder. 927 * 928 * @param builder 929 * The string builder where the string representation should be 930 * appended. 931 */ 932 public final void toString(StringBuilder builder) { 933 builder.append(getName()); 934 } 935 936 937 938 /** 939 * Initializes all of the components associated with this managed 940 * object definition. 941 * 942 * @throws Exception 943 * If this managed object definition could not be 944 * initialized. 945 */ 946 protected final void initialize() throws Exception { 947 for (PropertyDefinition<?> pd : getAllPropertyDefinitions()) { 948 pd.initialize(); 949 pd.getDefaultBehaviorProvider().initialize(); 950 } 951 952 for (RelationDefinition<?, ?> rd : getAllRelationDefinitions()) { 953 rd.initialize(); 954 } 955 956 for (AggregationPropertyDefinition<?, ?> apd : 957 getAllAggregationPropertyDefinitions()) { 958 959 apd.initialize(); 960 // Now register the aggregation property in the referenced managed object 961 // definition for reverse lookups. 962 registerReverseAggregationPropertyDefinition(apd); 963 } 964 965 for (Constraint constraint : getAllConstraints()) { 966 constraint.initialize(); 967 } 968 } 969 970 971 972 /** 973 * Register a constraint with this managed object definition. 974 * <p> 975 * This method <b>must not</b> be called by applications. 976 * 977 * @param constraint 978 * The constraint to be registered. 979 */ 980 protected final void registerConstraint(Constraint constraint) { 981 constraints.add(constraint); 982 } 983 984 985 986 /** 987 * Register a property definition with this managed object definition, 988 * overriding any existing property definition with the same name. 989 * <p> 990 * This method <b>must not</b> be called by applications. 991 * 992 * @param d 993 * The property definition to be registered. 994 */ 995 protected final void registerPropertyDefinition(PropertyDefinition<?> d) { 996 String propName = d.getName(); 997 998 propertyDefinitions.put(propName, d); 999 allPropertyDefinitions.put(propName, d); 1000 1001 if (d instanceof AggregationPropertyDefinition) { 1002 AggregationPropertyDefinition apd = (AggregationPropertyDefinition) d; 1003 aggregationPropertyDefinitions.put(propName, apd); 1004 // The key must also contain the managed object name, since several MOs 1005 // in an inheritance tree may aggregate the same aggregation property name 1006 allAggregationPropertyDefinitions.put( 1007 apd.getManagedObjectDefinition().getName() + ":" + propName, apd); 1008 } 1009 } 1010 1011 1012 1013 /** 1014 * Register a relation definition with this managed object definition, 1015 * overriding any existing relation definition with the same name. 1016 * <p> 1017 * This method <b>must not</b> be called by applications. 1018 * 1019 * @param d 1020 * The relation definition to be registered. 1021 */ 1022 protected final void registerRelationDefinition(RelationDefinition<?, ?> d) { 1023 // Register the relation in this managed object definition. 1024 String relName = d.getName(); 1025 1026 relationDefinitions.put(relName, d); 1027 allRelationDefinitions.put(relName, d); 1028 1029 // Now register the relation in the referenced managed object 1030 // definition for reverse lookups. 1031 registerReverseRelationDefinition(d); 1032 } 1033 1034 1035 1036 /** 1037 * Register an option with this managed object definition. 1038 * <p> 1039 * This method <b>must not</b> be called by applications. 1040 * 1041 * @param option 1042 * The option to be registered. 1043 */ 1044 protected final void registerOption(ManagedObjectOption option) { 1045 options.add(option); 1046 } 1047 1048 1049 1050 /** 1051 * Register a tag with this managed object definition. 1052 * <p> 1053 * This method <b>must not</b> be called by applications. 1054 * 1055 * @param tag 1056 * The tag to be registered. 1057 */ 1058 protected final void registerTag(Tag tag) { 1059 allTags.add(tag); 1060 } 1061 1062 1063 1064 /** 1065 * Deregister a constraint from the managed object definition. 1066 * <p> 1067 * This method <b>must not</b> be called by applications and is 1068 * only intended for internal testing. 1069 * 1070 * @param constraint 1071 * The constraint to be deregistered. 1072 */ 1073 final void deregisterConstraint(Constraint constraint) { 1074 if (!constraints.remove(constraint)) { 1075 throw new RuntimeException("Failed to deregister a constraint"); 1076 } 1077 } 1078 1079 1080 1081 /** 1082 * Deregister a relation definition from the managed object 1083 * definition. 1084 * <p> 1085 * This method <b>must not</b> be called by applications and is 1086 * only intended for internal testing. 1087 * 1088 * @param d 1089 * The relation definition to be deregistered. 1090 */ 1091 final void deregisterRelationDefinition( 1092 RelationDefinition<?, ?> d) { 1093 // Deregister the relation from this managed object definition. 1094 String relName = d.getName(); 1095 relationDefinitions.remove(relName); 1096 allRelationDefinitions.remove(relName); 1097 1098 // Now deregister the relation from the referenced managed object 1099 // definition for reverse lookups. 1100 d.getChildDefinition().reverseRelationDefinitions.remove(d); 1101 } 1102 1103 1104 1105 /** 1106 * Register this managed object definition in its parent. 1107 * <p> 1108 * This method <b>must not</b> be called by applications and is 1109 * only intended for internal testing. 1110 */ 1111 final void registerInParent() { 1112 if (parent != null) { 1113 parent.children.put(name, this); 1114 } 1115 } 1116 1117 1118 1119 // Register a relation definition in the referenced managed object 1120 // definition's reverse lookup table. 1121 private <CC extends ConfigurationClient, SS extends Configuration> 1122 void registerReverseRelationDefinition(RelationDefinition<CC, SS> rd) { 1123 rd.getChildDefinition().reverseRelationDefinitions.add(rd); 1124 } 1125 1126 1127 1128 // Register a aggregation property definition in the referenced managed object 1129 // definition's reverse lookup table. 1130 private void registerReverseAggregationPropertyDefinition( 1131 AggregationPropertyDefinition<?, ?> apd) { 1132 1133 apd.getRelationDefinition().getChildDefinition(). 1134 reverseAggregationPropertyDefinitions.add(apd); 1135 } 1136 1137 1138 1139 // Recursively descend definition hierarchy to find the best match definition. 1140 private AbstractManagedObjectDefinition<? extends C, ? extends S> 1141 resolveManagedObjectDefinitionAux( 1142 AbstractManagedObjectDefinition<? extends C, ? extends S> d, 1143 DefinitionResolver r) { 1144 if (!r.matches(d)) { 1145 return null; 1146 } 1147 1148 for (AbstractManagedObjectDefinition<? extends C, ? extends S> child : d 1149 .getChildren()) { 1150 AbstractManagedObjectDefinition<? extends C, ? extends S> rd = 1151 resolveManagedObjectDefinitionAux(child, r); 1152 if (rd != null) { 1153 return rd; 1154 } 1155 } 1156 1157 return d; 1158 } 1159 }