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

Gaetan Boismal
09.38.2015 dee3040496389ff70cdf1cec40422284d9ca62c5
OPENDJ-2092 OPENDJ-1759 New Schema elements GUI

CR-7193
This commit fixes control panel "new attribute type" and "new object class" features.
Changes made for both features:
* src/main/java/org/opends/guitools/controlpanel/task/NewSchemaElementsTask.java
** Re introduce code to create attribute type or object class string definition. This is needed because at the moment we add schema elements with their definition. Since r10478, definition is no more computed on the fly on a toString() call. We need to duplicate code as the only way to get a schema element definition is to add it to a schema before. Once the schema support will be fully migrated to the sdk this duplicated code should be remove. Note that the description generated is used only by machines, not humans
* src/main/java/org/opends/guitools/controlpanel/datamodel/ServerDescriptor.java
** Fix regression introduced in r11261 which has side effect to avoid schema element descriptor refresh after a schema element creation.
2 files modified
244 ■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/ServerDescriptor.java 74 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/NewSchemaElementsTask.java 170 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/ServerDescriptor.java
@@ -555,40 +555,52 @@
      return false;
    }
    // Just compare exhaustively objectclasses and attributes.
    Map<String, AttributeType> attrs1 = schema1.getAttributeTypes();
    Map<String, AttributeType> attrs2 = schema2.getAttributeTypes();
    if (attrs1.size() == attrs2.size())
    {
      for (String name : attrs1.keySet())
      {
        AttributeType attr1 = attrs1.get(name);
        AttributeType attr2 = attrs2.get(name);
        if (attr2 == null && !areAttributesEqual(attr1, attr2))
        {
          return false;
        }
      }
    }
    Map<String, ObjectClass> ocs1 = schema1.getObjectClasses();
    Map<String, ObjectClass> ocs2 = schema2.getObjectClasses();
    if (ocs1.size() == ocs2.size())
    {
      for (String name : ocs1.keySet())
      {
        ObjectClass oc1 = ocs1.get(name);
        ObjectClass oc2 = ocs2.get(name);
        if (oc2 == null || !areObjectClassesEqual(oc1, oc2))
        {
          return false;
        }
      }
    }
    return areEqual(schema1.getMatchingRules(), schema2.getMatchingRules())
    return areAttributeTypesEqual(schema1, schema2)
        && areObjectClassesEqual(schema1, schema2)
        && areEqual(schema1.getMatchingRules(), schema2.getMatchingRules())
        && areEqual(schema1.getSyntaxes(), schema2.getSyntaxes());
  }
  private static boolean areAttributeTypesEqual(Schema schema1, Schema schema2)
  {
    final Map<String, AttributeType> attrs1 = schema1.getAttributeTypes();
    final Map<String, AttributeType> attrs2 = schema2.getAttributeTypes();
    if (attrs1.size() != attrs2.size())
    {
      return false;
    }
    for (String name : attrs1.keySet())
    {
      AttributeType attr1 = attrs1.get(name);
      AttributeType attr2 = attrs2.get(name);
      if (attr2 == null && !areAttributesEqual(attr1, attr2))
      {
        return false;
      }
    }
    return true;
  }
  private static boolean areObjectClassesEqual(Schema schema1, Schema schema2)
  {
    final Map<String, ObjectClass> ocs1 = schema1.getObjectClasses();
    final Map<String, ObjectClass> ocs2 = schema2.getObjectClasses();
    if (ocs1.size() != ocs2.size())
    {
      return false;
    }
    for (String name : ocs1.keySet())
    {
      ObjectClass oc1 = ocs1.get(name);
      ObjectClass oc2 = ocs2.get(name);
      if (oc2 == null || !areObjectClassesEqual(oc1, oc2))
      {
        return false;
      }
    }
    return true;
  }
  /**
   * Method used to compare attributes defined in the schema.
   * Returns <CODE>true</CODE> if the two schema attributes are equal and
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/task/NewSchemaElementsTask.java
@@ -34,6 +34,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
@@ -48,6 +49,7 @@
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ModificationType;
import org.forgerock.opendj.ldap.schema.MatchingRule;
import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
import org.opends.guitools.controlpanel.ui.ColorAndFontConstants;
import org.opends.guitools.controlpanel.ui.ProgressDialog;
@@ -326,7 +328,7 @@
    try
    {
      final BasicAttribute attr = new BasicAttribute(getAttributeName(schemaElement));
      attr.add(getValueOnline(schemaElement));
      attr.add(getElementDefinition(schemaElement));
      final ModificationItem mod = new ModificationItem(DirContext.ADD_ATTRIBUTE, attr);
      getInfo().getDirContext().modifyAttributes(
          ConfigConstants.DN_DEFAULT_SCHEMA_ROOT, new ModificationItem[] { mod });
@@ -346,17 +348,12 @@
    });
  }
  private String getValueOnline(CommonSchemaElements element)
  {
    return element.toString();
  }
  private String getValueOffline(CommonSchemaElements element)
  {
    final Map<String, List<String>> props = element.getExtraProperties();
    List<String> previousValues = props.get(ServerConstants.SCHEMA_PROPERTY_FILENAME);
    setExtraProperty(element, ServerConstants.SCHEMA_PROPERTY_FILENAME, null);
    String attributeWithoutFileDefinition = element.toString();
    String attributeWithoutFileDefinition = getElementDefinition(element);
    if (previousValues != null && !previousValues.isEmpty())
    {
@@ -365,6 +362,162 @@
    return attributeWithoutFileDefinition;
  }
  private String getElementDefinition(CommonSchemaElements element)
  {
    final List<String> names = new ArrayList<>();
    for (final String name : element.getNormalizedNames())
    {
      names.add(name);
    }
    if (element instanceof AttributeType)
    {
      return getAttributeTypeDefinition((AttributeType) element, names);
    }
    else if (element instanceof ObjectClass)
    {
      return getObjectClassDefinition((ObjectClass) element, names);
    }
    else
    {
      throw new IllegalArgumentException("Unsupported schema element: " + element.getClass().getName());
    }
  }
  private String getAttributeTypeDefinition(final AttributeType attributeType, final List<String> names)
  {
    final StringBuilder buffer = new StringBuilder();
    buffer.append("( ").append(attributeType.getOID());
    appendCollection(buffer, "NAME", names);
    appendDescription(buffer, attributeType.getDescription());
    appendIfTrue(buffer, " OBSOLETE", attributeType.isObsolete());
    final AttributeType superiorType = attributeType.getSuperiorType();
    final String superiorTypeOID = superiorType != null ? superiorType.getOID() : null;
    appendIfNotNull(buffer, " SUP ", superiorTypeOID);
    addMatchingRuleIfNotNull(buffer, " EQUALITY ", attributeType.getEqualityMatchingRule());
    addMatchingRuleIfNotNull(buffer, " ORDERING ", attributeType.getOrderingMatchingRule());
    addMatchingRuleIfNotNull(buffer, " SUBSTR ", attributeType.getSubstringMatchingRule());
    appendIfNotNull(buffer, " SYNTAX ", attributeType.getSyntax().getOID());
    appendIfTrue(buffer, " SINGLE-VALUE", attributeType.isSingleValue());
    appendIfTrue(buffer, " COLLECTIVE", attributeType.isCollective());
    appendIfTrue(buffer, " NO-USER-MODIFICATION", attributeType.isNoUserModification());
    appendIfNotNull(buffer, " USAGE ", attributeType.getUsage());
    final MatchingRule approximateMatchingRule = attributeType.getApproximateMatchingRule();
    if (approximateMatchingRule != null)
    {
      buffer.append(" ").append(ServerConstants.SCHEMA_PROPERTY_APPROX_RULE).append(" '")
            .append(approximateMatchingRule.getOID()).append("'");
    }
    appendExtraProperties(buffer, attributeType.getExtraProperties());
    buffer.append(")");
    return buffer.toString();
  }
  private void addMatchingRuleIfNotNull(final StringBuilder buffer, final String label, final MatchingRule matchingRule)
  {
    if (matchingRule != null)
    {
      append(buffer, label, matchingRule.getOID());
    }
  }
  private String getObjectClassDefinition(final ObjectClass objectClass, final List<String> names)
  {
    final StringBuilder buffer = new StringBuilder();
    buffer.append("( ");
    buffer.append(objectClass.getOID());
    appendCollection(buffer, "NAME", names);
    appendDescription(buffer, objectClass.getDescription());
    appendIfTrue(buffer, " OBSOLETE", objectClass.isObsolete());
    appendOIDs(buffer, "SUP", objectClass.getSuperiorClasses());
    appendIfNotNull(buffer, " ", objectClass.getObjectClassType());
    appendOIDs(buffer, "MUST", objectClass.getRequiredAttributes());
    appendOIDs(buffer, "MAY", objectClass.getOptionalAttributes());
    appendExtraProperties(buffer, objectClass.getExtraProperties());
    buffer.append(")");
    return buffer.toString();
  }
  private <T extends CommonSchemaElements> void appendOIDs(final StringBuilder buffer, final String label,
      final Collection<T> schemaElements)
  {
    if (!schemaElements.isEmpty())
    {
      final Iterator<T> iterator = schemaElements.iterator();
      final String firstOID = iterator.next().getOID();
      buffer.append(" ").append(label).append(" ( ").append(firstOID);
      while (iterator.hasNext())
      {
        buffer.append(" $ ").append(iterator.next().getOID());
      }
      buffer.append(" )");
    }
  }
  private void appendIfTrue(final StringBuilder buffer, final String label, final boolean labelIsActive)
  {
    if (labelIsActive)
    {
      buffer.append(label);
    }
  }
  private void appendIfNotNull(final StringBuilder buffer, final String label, final Object value)
  {
    if (value != null)
    {
      append(buffer, label, value.toString());
    }
  }
  private void append(final StringBuilder buffer, final String label, final String value)
  {
    buffer.append(label).append(value);
  }
  private void appendDescription(final StringBuilder buffer, final String description)
  {
    if (description != null && !description.isEmpty())
    {
      buffer.append(" DESC '");
      buffer.append(description);
      buffer.append("'");
    }
  }
  private void appendExtraProperties(
      final StringBuilder buffer, final Map<String, List<String>> extraProperties)
  {
    for (final Map.Entry<String, List<String>> e : extraProperties.entrySet())
    {
      appendCollection(buffer, e.getKey(), e.getValue());
    }
  }
  private void appendCollection(final StringBuilder buffer, final String property, final Collection<String> values)
  {
    final Iterator<String> iterator = values.iterator();
    final boolean isMultiValued = values.size() > 1;
    if (iterator.hasNext())
    {
      final String first = iterator.next();
      buffer.append(" ").append(property);
      buffer.append(isMultiValued ? " ( '" : " '").append(first).append("' ");
      while (iterator.hasNext())
      {
        buffer.append("'").append(iterator.next()).append("' ");
      }
      if (isMultiValued)
      {
        buffer.append(")");
      }
    }
  }
  private void printEquivalentCommandLineToAddOnline(CommonSchemaElements element)
  {
    List<String> args = new ArrayList<>();
@@ -384,7 +537,7 @@
      .append("dn: cn=schema<br>")
      .append("changetype: modify<br>")
      .append("add: ").append(attName).append("<br>")
      .append(attName).append(": ").append(getValueOnline(element)).append("</b><br><br>");
      .append(attName).append(": ").append(getElementDefinition(element)).append("</b><br><br>");
    getProgressDialog().appendProgressHtml(Utilities.applyFont(sb.toString(), ColorAndFontConstants.progressFont));
  }
@@ -600,5 +753,4 @@
      throw new OfflineUpdateException(ERR_CTRL_PANEL_ERROR_UPDATING_SCHEMA.get(t), t);
    }
  }
}