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