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