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