mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

jcambon
07.55.2008 c15ef13192cb53cf8fd0931975a17b1c79441b74
Fix for issue #3089: Configuration Reference - Missing aggregation relations 

To be handle properly, this fix required an enhancement in the Introspection API,
to be able to get the aggregation relations FROM and TO a given managed object.

The following methods have been added to AbstractManagedObjectDefinition class :

getAllAggregationPropertyDefinitions()
getAllReverseAggregationPropertyDefinitions()
getAggregationPropertyDefinition(String name)
getAggregationPropertyDefinitions()
getReverseAggregationPropertyDefinitions()


Then, added the aggregation relations in the the Configuration Reference generated doc,
in sections "Relations From this Component" and "Relations From this component" (today, only the composition relations are listed).

Note that the aggregation relations are not represented in the tree views on the left frame.
Any suggestion to do this is welcome!

2 files modified
368 ■■■■ changed files
opendj-sdk/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java 183 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/doc/ConfigGuideGeneration.java 185 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java
@@ -42,6 +42,7 @@
import java.util.MissingResourceException;
import java.util.Set;
import java.util.Vector;
import org.opends.messages.Message;
import org.opends.server.admin.DefinitionDecodingException.Reason;
@@ -94,6 +95,21 @@
  // object definition including inherited relation definitions.
  private final Map<String, RelationDefinition<?, ?>> allRelationDefinitions;
  // The set of aggregation property definitions applicable to this
  // managed object definition.
  private final Map<String, AggregationPropertyDefinition<?, ?>>
    aggregationPropertyDefinitions;
  // The set of aggregation property definitions directly referencing this
  // managed object definition.
  private final Vector<AggregationPropertyDefinition<?, ?>>
    reverseAggregationPropertyDefinitions;
  // The set of all aggregation property definitions associated with this
  // managed object definition including inherited relation definitions.
  private final Map<String, AggregationPropertyDefinition<?, ?>>
    allAggregationPropertyDefinitions;
  // The set of tags associated with this managed object.
  private final Set<Tag> allTags;
@@ -128,6 +144,12 @@
    this.allPropertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
    this.allRelationDefinitions =
      new HashMap<String, RelationDefinition<?, ?>>();
    this.aggregationPropertyDefinitions =
      new HashMap<String, AggregationPropertyDefinition<?,?>>();
    this.reverseAggregationPropertyDefinitions =
      new Vector<AggregationPropertyDefinition<?,?>>();
    this.allAggregationPropertyDefinitions =
      new HashMap<String, AggregationPropertyDefinition<?, ?>>();
    this.allTags = new HashSet<Tag>();
    this.options = EnumSet.noneOf(ManagedObjectOption.class);
@@ -146,6 +168,12 @@
        allRelationDefinitions.put(rd.getName(), rd);
      }
      for (AggregationPropertyDefinition<?, ?> apd :
        parent.getAllAggregationPropertyDefinitions()) {
        allAggregationPropertyDefinitions.put(apd.getName(), apd);
      }
      // Tag inheritance is performed during preprocessing.
    }
  }
@@ -262,6 +290,52 @@
  /**
   * Get all the aggregation property definitions associated with this type of
   * managed object. The returned collection will contain inherited
   * aggregation property definitions.
   *
   * @return Returns an unmodifiable collection containing all the
   *         aggregation property definitions associated with this type of
   *         managed object.
   */
  public final Collection<AggregationPropertyDefinition<?, ?>>
      getAllAggregationPropertyDefinitions() {
    return Collections.unmodifiableCollection(
      allAggregationPropertyDefinitions.values());
  }
  /**
   * Get all the aggregation property definitions which refer to this managed
   * object definition. The returned collection will contain aggregation
   * property definitions which refer to parents of this managed object
   * definition.
   *
   * @return Returns a collection containing all the aggregation property
   *         definitions which refer to this managed object
   *         definition. The caller is free to modify the collection
   *         if required.
   */
  public final Collection<AggregationPropertyDefinition<?, ?>>
  getAllReverseAggregationPropertyDefinitions() {
    // This method does not used a cached set of aggregation properties because
    // aggregation properties may be updated after child definitions have been
    // defined.
    List<AggregationPropertyDefinition<?, ?>> apdlist =
      new LinkedList<AggregationPropertyDefinition<?, ?>>();
    if (parent != null) {
      apdlist.addAll(parent.getAllReverseAggregationPropertyDefinitions());
    }
    apdlist.addAll(reverseAggregationPropertyDefinitions);
    return apdlist;
  }
  /**
   * Get all the tags associated with this type of managed object. The
   * returned collection will contain inherited tags.
   *
@@ -524,6 +598,68 @@
  /**
   * Get the specified aggregation property definition associated with this type
   * of managed object.The search will include any inherited aggregation
   * property definitions.
   *
   * @param name
   *          The name of the aggregation property definition to be retrieved.
   * @return Returns the specified aggregation property definition associated
   *         with this type of managed object.
   * @throws IllegalArgumentException
   *           If the specified aggregation property name was null or empty or
   *           if the requested aggregation property definition was not found.
   */
  public final AggregationPropertyDefinition<?, ?>
    getAggregationPropertyDefinition(String name)
    throws IllegalArgumentException {
    if ((name == null) || (name.length() == 0)) {
      throw new IllegalArgumentException(
        "null or empty aggregation property name");
    }
    AggregationPropertyDefinition<?, ?> d =
      allAggregationPropertyDefinitions.get(name);
    if (d == null) {
      throw new IllegalArgumentException("aggregation property definition \""
        + name + "\" not found");
    }
    return d;
  }
  /**
   * Get the aggregation property definitions defined by this managed object
   * definition. The returned collection will not contain inherited
   * aggregation property definitions.
   *
   * @return Returns an unmodifiable collection containing the
   *         aggregation property definitions defined by this managed object
   *         definition.
   */
  public final Collection<AggregationPropertyDefinition<?, ?>>
    getAggregationPropertyDefinitions() {
    return Collections.unmodifiableCollection(
      aggregationPropertyDefinitions.values());
  }
  /**
   * Get the aggregation property definitions which refer directly to this
   * managed object definition. The returned collection will not contain
   * aggregation property definitions which refer to parents of this managed
   * object definition.
   *
   * @return Returns an unmodifiable collection containing the
   *         aggregation property definitions which refer directly to this
   *         managed object definition.
   */
  public final Collection<AggregationPropertyDefinition<?, ?>>
    getReverseAggregationPropertyDefinitions() {
    return Collections.unmodifiableCollection(
      reverseAggregationPropertyDefinitions);
  }
  /**
   * Gets the synopsis of this managed object definition in the
   * default locale.
   *
@@ -817,6 +953,15 @@
      rd.initialize();
    }
    for (AggregationPropertyDefinition<?, ?> apd :
      getAllAggregationPropertyDefinitions()) {
      apd.initialize();
      // Now register the aggregation property in the referenced managed object
      // definition for reverse lookups.
      registerReverseAggregationPropertyDefinition(apd);
    }
    for (Constraint constraint : getAllConstraints()) {
      constraint.initialize();
    }
@@ -848,10 +993,19 @@
   *          The property definition to be registered.
   */
  protected final void registerPropertyDefinition(PropertyDefinition<?> d) {
    String name = d.getName();
    String propName = d.getName();
    propertyDefinitions.put(name, d);
    allPropertyDefinitions.put(name, d);
    propertyDefinitions.put(propName, d);
    allPropertyDefinitions.put(propName, d);
    if (d instanceof AggregationPropertyDefinition) {
      AggregationPropertyDefinition apd = (AggregationPropertyDefinition) d;
      aggregationPropertyDefinitions.put(propName, apd);
      // The key must also contain the managed object name, since several MOs
      // in an inheritance tree may aggregate the same aggregation property name
      allAggregationPropertyDefinitions.put(
        apd.getManagedObjectDefinition().getName() + ":" + propName, apd);
    }
  }
@@ -867,10 +1021,10 @@
   */
  protected final void registerRelationDefinition(RelationDefinition<?, ?> d) {
    // Register the relation in this managed object definition.
    String name = d.getName();
    String relName = d.getName();
    relationDefinitions.put(name, d);
    allRelationDefinitions.put(name, d);
    relationDefinitions.put(relName, d);
    allRelationDefinitions.put(relName, d);
    // Now register the relation in the referenced managed object
    // definition for reverse lookups.
@@ -937,9 +1091,9 @@
  final void deregisterRelationDefinition(
      RelationDefinition<?, ?> d) {
   // Deregister the relation from this managed object definition.
    String name = d.getName();
    relationDefinitions.remove(name);
    allRelationDefinitions.remove(name);
    String relName = d.getName();
    relationDefinitions.remove(relName);
    allRelationDefinitions.remove(relName);
    // Now deregister the relation from the referenced managed object
    // definition for reverse lookups.
@@ -971,6 +1125,17 @@
  // Register a aggregation property definition in the referenced managed object
  // definition's reverse lookup table.
  private void registerReverseAggregationPropertyDefinition(
    AggregationPropertyDefinition<?, ?> apd) {
    apd.getRelationDefinition().getChildDefinition().
      reverseAggregationPropertyDefinitions.add(apd);
  }
  // Recursively descend definition hierarchy to find the best match definition.
  private AbstractManagedObjectDefinition<? extends C, ? extends S>
      resolveManagedObjectDefinitionAux(
opendj-sdk/opends/src/server/org/opends/server/admin/doc/ConfigGuideGeneration.java
@@ -453,62 +453,7 @@
    }
    // Relations
    if (!mo.getRelationDefinitions().isEmpty()) {
      boolean emptyList = true;
      @SuppressWarnings("unchecked")
      Collection<RelationDefinition> rels = mo.getRelationDefinitions();
      for ( RelationDefinition rel : rels) {
        if (rel.hasOption(RelationOption.HIDDEN)) {
          continue;
        }
        emptyList = false;
      }
      if (!emptyList) {
        heading3("Relations From this Component");
        paragraph(
          "The following components have a direct composition relation FROM " +
          mo.getUserFriendlyPluralName() + " :");
        for ( RelationDefinition rel : rels) {
          if (rel.hasOption(RelationOption.HIDDEN)) {
            continue;
          }
          beginList();
          AbstractManagedObjectDefinition childRel = rel.getChildDefinition();
          link(childRel.getUserFriendlyName().toString(), childRel.getName() +
            ".html");
          endList();
        }
      }
    }
    if (!mo.getReverseRelationDefinitions().isEmpty()) {
      boolean emptyList = true;
      @SuppressWarnings("unchecked")
      Collection<RelationDefinition> rels = mo.getReverseRelationDefinitions();
      for ( RelationDefinition rel : rels) {
        if (rel.hasOption(RelationOption.HIDDEN)) {
          continue;
        }
        // check if it is not root
        if (rel.getParentDefinition().getName().equals("")) {
          continue;
        }
        emptyList = false;
      }
      if (!emptyList) {
        heading3("Relations To this Component");
        paragraph(
          "The following components have a direct composition relation TO " +
          mo.getUserFriendlyPluralName() + " :");
        for ( RelationDefinition rel : rels) {
          beginList();
          AbstractManagedObjectDefinition childRel = rel.getParentDefinition();
          link(childRel.getUserFriendlyName().toString(), childRel.getName() +
            ".html");
          endList();
        }
      }
    }
    generateRelationsSection(mo);
    // Page links in case of LDAP mapping
    if (ldapMapping) {
@@ -596,6 +541,134 @@
  }
  private void generateRelationsSection(AbstractManagedObjectDefinition mo) {
    // Composition relations
    @SuppressWarnings("unchecked")
    Collection<RelationDefinition> compRels = mo.getRelationDefinitions();
    @SuppressWarnings("unchecked")
    Collection<RelationDefinition> reverseCompRels =
      mo.getReverseRelationDefinitions();
    // Aggregation properties
    @SuppressWarnings("unchecked")
    Collection<AggregationPropertyDefinition> aggregProps =
      mo.getAggregationPropertyDefinitions();
    @SuppressWarnings("unchecked")
    Collection<AggregationPropertyDefinition> reverseAggregProps =
      mo.getReverseAggregationPropertyDefinitions();
    // Check if something to print in composition relations
    // (even if the list not empty, it may contain only hidden relations)
    boolean isCompRelsEmpty = true;
    if (!compRels.isEmpty()) {
      for (RelationDefinition rel : compRels) {
        if (rel.hasOption(RelationOption.HIDDEN)) {
          continue;
        }
        isCompRelsEmpty = false;
      }
    }
    boolean isReverseCompRelsEmpty = true;
    if (!reverseCompRels.isEmpty()) {
      for (RelationDefinition rel : reverseCompRels) {
        if (rel.hasOption(RelationOption.HIDDEN)) {
          continue;
        }
        // check if it is not root
        if (rel.getParentDefinition().getName().equals("")) {
          continue;
        }
        isReverseCompRelsEmpty = false;
      }
    }
    //
    // Relations FROM this component
    //
    if (!isCompRelsEmpty || !aggregProps.isEmpty()) {
        heading3("Relations From this Component");
    }
    if (!isCompRelsEmpty) {
      paragraph(
        "The following components have a direct COMPOSITION relation FROM " +
        mo.getUserFriendlyPluralName() + " :");
      for ( RelationDefinition rel : compRels) {
        if (rel.hasOption(RelationOption.HIDDEN)) {
          continue;
        }
        beginList();
        AbstractManagedObjectDefinition childRel = rel.getChildDefinition();
        link(childRel.getUserFriendlyName().toString(), childRel.getName() +
          ".html");
        endList();
      }
    }
    if (!aggregProps.isEmpty()) {
      paragraph(
        "The following components have a direct AGGREGATION relation FROM " +
        mo.getUserFriendlyPluralName() + " :");
      TreeMap<String, AbstractManagedObjectDefinition> componentList =
        new TreeMap<String, AbstractManagedObjectDefinition>();
      for ( AggregationPropertyDefinition agg : aggregProps) {
        RelationDefinition rel = agg.getRelationDefinition();
        AbstractManagedObjectDefinition childRel = rel.getChildDefinition();
        componentList.put(childRel.getName(), childRel);
      }
      for (AbstractManagedObjectDefinition component : componentList.values()) {
        beginList();
        link(component.getUserFriendlyName().toString(), component.getName() +
          ".html");
        endList();
      }
    }
    //
    // Relations TO this component
    //
    if (!isReverseCompRelsEmpty || !reverseAggregProps.isEmpty()) {
        heading3("Relations To this Component");
    }
    if (!mo.getReverseRelationDefinitions().isEmpty()) {
      if (!isReverseCompRelsEmpty) {
        paragraph(
          "The following components have a direct COMPOSITION relation TO " +
          mo.getUserFriendlyPluralName() + " :");
        for ( RelationDefinition rel : reverseCompRels) {
          beginList();
          AbstractManagedObjectDefinition childRel = rel.getParentDefinition();
          link(childRel.getUserFriendlyName().toString(), childRel.getName() +
            ".html");
          endList();
        }
      }
    }
    if (!reverseAggregProps.isEmpty()) {
      paragraph(
        "The following components have a direct AGGREGATION relation TO " +
        mo.getUserFriendlyPluralName() + " :");
      TreeMap<String, AbstractManagedObjectDefinition> componentList =
        new TreeMap<String, AbstractManagedObjectDefinition>();
      for ( AggregationPropertyDefinition agg : reverseAggregProps) {
        AbstractManagedObjectDefinition fromMo =
          agg.getManagedObjectDefinition();
        componentList.put(fromMo.getName(), fromMo);
      }
      for (AbstractManagedObjectDefinition component : componentList.values()) {
        beginList();
        link(component.getUserFriendlyName().toString(), component.getName() +
          ".html");
        endList();
      }
    }
  }
  private void generateProperty(
    AbstractManagedObjectDefinition mo, PropertyDefinition prop) {