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

Jean-Noel Rouvignac
25.51.2015 753aca913686d9efd13ba4cc3caf01cc9597fae7
Code cleanup


Entry.java:
In applyModification(), extracted methods applyModificationToObjectclass() and applyModificationToNonObjectclass().
In hasUserAttribute() and hasOperationalAttribute(), extracted method hasAttribute()
Used Attribute.isReal() to explicit code + merged if statements.


Attribute.java:
Added isReal() -> !isVirtual().

AbstractAttribute.java:
Implemented isReal().
In equals() extracted method valuesEqual().
In hasAllOptions() and optionsEqual(), extracted method hasAllOptions0().
3 files modified
447 ■■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/server/types/AbstractAttribute.java 124 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/types/Attribute.java 71 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/types/Entry.java 252 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/types/AbstractAttribute.java
@@ -35,10 +35,7 @@
import static org.opends.server.util.StaticUtils.*;
/**
 * An abstract base class for implementing new types of
 * {@link Attribute}.
 */
/** An abstract base class for implementing new types of {@link Attribute}. */
@org.opends.server.types.PublicAPI(
    stability = org.opends.server.types.StabilityLevel.UNCOMMITTED,
    mayInstantiate = false,
@@ -46,17 +43,12 @@
    mayInvoke = true)
public abstract class AbstractAttribute implements Attribute
{
  /**
   * Creates a new abstract attribute.
   */
  /** Creates a new abstract attribute. */
  protected AbstractAttribute()
  {
    // No implementation required.
  }
  /**
   * {@inheritDoc}
   * <p>
@@ -77,9 +69,6 @@
    return true;
  }
  /** {@inheritDoc} */
  @Override
  public final boolean equals(Object o)
  {
@@ -87,37 +76,33 @@
    {
      return true;
    }
    else if (o instanceof Attribute)
    {
      Attribute a = (Attribute) o;
      if (!getAttributeType().equals(a.getAttributeType()))
      {
        return false;
      }
      if (size() != a.size())
      {
        return false;
      }
      for (ByteString v : a)
      {
        if (!contains(v))
        {
          return false;
        }
      }
      return optionsEqual(a.getOptions());
    }
    else
    if (!(o instanceof Attribute))
    {
      return false;
    }
    Attribute a = (Attribute) o;
    return getAttributeType().equals(a.getAttributeType())
        && valuesEqual(a)
        && optionsEqual(a.getOptions());
  }
  private boolean valuesEqual(Attribute a)
  {
    if (size() != a.size())
    {
      return false;
    }
    for (ByteString v : a)
    {
      if (!contains(v))
      {
        return false;
      }
    }
    return true;
  }
  /**
   * {@inheritDoc}
@@ -132,8 +117,6 @@
    return getAttributeType().getNameOrOID();
  }
  /**
   * {@inheritDoc}
   * <p>
@@ -149,21 +132,17 @@
    {
      return getName();
    }
    else
    StringBuilder buffer = new StringBuilder();
    buffer.append(getName());
    for (String option : getOptions())
    {
      StringBuilder buffer = new StringBuilder();
      buffer.append(getName());
      for (String option : getOptions())
      {
        buffer.append(';');
        buffer.append(option);
      }
      return buffer.toString();
      buffer.append(';');
      buffer.append(option);
    }
    return buffer.toString();
  }
  /**
   * {@inheritDoc}
   * <p>
@@ -183,25 +162,13 @@
      return true;
    }
    if (!hasOptions())
    if (hasOptions())
    {
      return false;
      return hasAllOptions0(options);
    }
    for (String option : options)
    {
      if (!hasOption(option))
      {
        return false;
      }
    }
    return true;
    return false;
  }
  /** {@inheritDoc} */
  @Override
  public int hashCode()
  {
@@ -221,8 +188,6 @@
    return hashCode;
  }
  /**
   * {@inheritDoc}
   * <p>
@@ -249,8 +214,6 @@
    return false;
  }
  /**
   * {@inheritDoc}
   * <p>
@@ -263,8 +226,6 @@
    return !getOptions().isEmpty();
  }
  /**
   * {@inheritDoc}
   * <p>
@@ -277,7 +238,11 @@
    return size() == 0;
  }
  @Override
  public boolean isReal()
  {
    return !isVirtual();
  }
  /**
   * {@inheritDoc}
@@ -299,12 +264,16 @@
      return !hasOptions();
    }
    if (getOptions().size() != options.size())
    if (getOptions().size() == options.size())
    {
      return false;
      return hasAllOptions0(options);
    }
    return false;
  }
    // Cannot use Set.containsAll() because the set of options are not normalized.
  /** Cannot use Set.containsAll() because the set of options are not normalized. */
  private boolean hasAllOptions0(Collection<String> options)
  {
    for (String option : options)
    {
      if (!hasOption(option))
@@ -315,9 +284,6 @@
    return true;
  }
  /** {@inheritDoc} */
  @Override
  public final String toString()
  {
opendj-server-legacy/src/main/java/org/opends/server/types/Attribute.java
@@ -22,7 +22,7 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions Copyright 2014 ForgeRock AS
 *      Portions Copyright 2014-2015 ForgeRock AS
 */
package org.opends.server.types;
@@ -41,14 +41,12 @@
 * Attributes are immutable and therefore any attempts to modify them
 * will result in an {@link UnsupportedOperationException}.
 * <p>
 * There are two types of attribute: real attributes and virtual
 * attributes. Real attributes can be created using the
 * {@link AttributeBuilder} class or by using the various static
 * factory methods in the {@link Attributes} class, whereas virtual
 * attributes are represented using the {@link VirtualAttribute}
 * class. New attribute implementations can be implemented by either
 * implementing this interface or by extending
 * {@link AbstractAttribute}.
 * There are two types of attribute: real attributes and virtual attributes.
 * Real attributes can be created using the {@link AttributeBuilder} class
 * or by using the various static factory methods in the {@link Attributes} class,
 * whereas virtual attributes are represented using the {@link VirtualAttribute} class.
 * New attribute implementations can be implemented by either implementing this interface
 * or by extending {@link AbstractAttribute}.
 */
@org.opends.server.types.PublicAPI(
    stability = org.opends.server.types.StabilityLevel.UNCOMMITTED,
@@ -57,7 +55,6 @@
    mayInvoke = true)
public interface Attribute extends Iterable<ByteString>
{
  /**
   * Indicates whether this attribute has any value(s) that are
   * approximately equal to the provided value.
@@ -71,8 +68,6 @@
   */
  ConditionResult approximatelyEqualTo(ByteString assertionValue);
  /**
   * Indicates whether this attribute contains the specified value.
   *
@@ -83,8 +78,6 @@
   */
  boolean contains(ByteString value);
  /**
   * Indicates whether this attribute contains all the values in the
   * collection.
@@ -97,8 +90,6 @@
   */
  boolean containsAll(Collection<ByteString> values);
  /**
   * Indicates whether this attribute matches the specified assertion value.
   *
@@ -109,8 +100,6 @@
   */
  ConditionResult matchesEqualityAssertion(ByteString assertionValue);
  /**
   * Indicates whether the provided object is an attribute that is
   * equal to this attribute. It will be considered equal if the
@@ -125,8 +114,6 @@
  @Override
  boolean equals(Object o);
  /**
   * Retrieves the attribute type for this attribute.
   *
@@ -134,8 +121,6 @@
   */
  AttributeType getAttributeType();
  /**
   * Retrieves the user-provided name for this attribute.
   *
@@ -143,8 +128,6 @@
   */
  String getName();
  /**
   * Retrieves the user-provided name of this attribute, along with
   * any options that might have been provided.
@@ -154,8 +137,6 @@
   */
  String getNameWithOptions();
  /**
   * Retrieves the unmodifiable set of attribute options for this
   * attribute. The returned set of options are not normalized.
@@ -165,8 +146,6 @@
   */
  Set<String> getOptions();
  /**
   * Indicates whether this attribute has any value(s) that are
   * greater than or equal to the provided value.
@@ -180,8 +159,6 @@
   */
  ConditionResult greaterThanOrEqualTo(ByteString assertionValue);
  /**
   * Indicates whether this attribute has all of the options in the
   * provided collection.
@@ -195,8 +172,6 @@
   */
  boolean hasAllOptions(Collection<String> options);
  /**
   * Retrieves the hash code for this attribute. It will be calculated
   * as the sum of the hash code for the attribute type and all
@@ -207,8 +182,6 @@
  @Override
  int hashCode();
  /**
   * Indicates whether this attribute has the specified option.
   *
@@ -219,8 +192,6 @@
   */
  boolean hasOption(String option);
  /**
   * Indicates whether this attribute has any options at all.
   *
@@ -229,8 +200,6 @@
   */
  boolean hasOptions();
  /**
   * Returns <code>true</code> if this attribute contains no
   * attribute values.
@@ -240,18 +209,22 @@
   */
  boolean isEmpty();
  /**
   * Indicates whether this is a real attribute (persisted) rather than a virtual attribute
   * (dynamically computed).
   *
   * @return {@code true} if this is a real attribute.
   */
  boolean isReal();
  /**
   * Indicates whether this is a virtual attribute rather than a real
   * attribute.
   * Indicates whether this is a virtual attribute (dynamically computed) rather than a real
   * attribute (persisted).
   *
   * @return {@code true} if this is a virtual attribute.
   */
  boolean isVirtual();
  /**
   * Returns an iterator over the attribute values in this attribute.
   * The attribute values are returned in the order in which they were
@@ -263,8 +236,6 @@
  @Override
  Iterator<ByteString> iterator();
  /**
   * Indicates whether this attribute has any value(s) that are less
   * than or equal to the provided value.
@@ -278,8 +249,6 @@
   */
  ConditionResult lessThanOrEqualTo(ByteString assertionValue);
  /**
   * Indicates whether this attribute has any value(s) that match the
   * provided substring.
@@ -298,8 +267,6 @@
  ConditionResult matchesSubstring(ByteString subInitial,
      List<ByteString> subAny, ByteString subFinal);
  /**
   * Indicates whether this attribute has exactly the specified set of
   * options.
@@ -312,8 +279,6 @@
   */
  boolean optionsEqual(Set<String> options);
  /**
   * Returns the number of attribute values in this attribute.
   *
@@ -321,8 +286,6 @@
   */
  int size();
  /**
   * Retrieves a one-line string representation of this attribute.
   *
@@ -331,8 +294,6 @@
  @Override
  String toString();
  /**
   * Appends a one-line string representation of this attribute to the
   * provided buffer.
opendj-server-legacy/src/main/java/org/opends/server/types/Entry.java
@@ -429,9 +429,7 @@
   * @return <CODE>true</CODE> if this entry contains the specified
   *         attribute, or <CODE>false</CODE> if not.
   */
  public boolean hasAttribute(
      AttributeType attributeType,
      Set<String> options)
  public boolean hasAttribute(AttributeType attributeType, Set<String> options)
  {
    return hasAttribute(attributeType, options, true);
  }
@@ -498,9 +496,8 @@
        {
          for (Attribute attribute : attributes)
          {
            // It's possible that there could be an attribute without
            // any values, which we should treat as not having the
            // requested attribute.
            // It's possible that there could be an attribute without any values,
            // which we should treat as not having the requested attribute.
            if (!attribute.isEmpty() && attribute.hasAllOptions(options))
            {
              return true;
@@ -881,23 +878,7 @@
   */
  public boolean hasUserAttribute(AttributeType attributeType)
  {
    if (userAttributes.containsKey(attributeType))
    {
      return true;
    }
    if (attributeType.mayHaveSubordinateTypes())
    {
      for (AttributeType at : schema.getSubTypes(attributeType))
      {
        if (userAttributes.containsKey(at))
        {
          return true;
        }
      }
    }
    return false;
    return hasAttribute(userAttributes, attributeType);
  }
@@ -1040,7 +1021,12 @@
   */
  public boolean hasOperationalAttribute(AttributeType attributeType)
  {
    if (operationalAttributes.containsKey(attributeType))
    return hasAttribute(operationalAttributes, attributeType);
  }
  private boolean hasAttribute(Map<AttributeType, List<Attribute>> attributes, AttributeType attributeType)
  {
    if (attributes.containsKey(attributeType))
    {
      return true;
    }
@@ -1049,7 +1035,7 @@
    {
      for (AttributeType at : schema.getSubTypes(attributeType))
      {
        if (operationalAttributes.containsKey(at))
        if (attributes.containsKey(at))
        {
          return true;
        }
@@ -1498,103 +1484,113 @@
    Attribute     a = mod.getAttribute();
    AttributeType t = a.getAttributeType();
    // We'll need to handle changes to the objectclass attribute in a
    // special way.
    if (t.isObjectClass())
    {
      Map<ObjectClass, String> ocs = new LinkedHashMap<>();
      for (ByteString v : a)
      {
        String ocName    = v.toString();
        String lowerName = toLowerCase(ocName);
        ObjectClass oc   =
             DirectoryServer.getObjectClass(lowerName, true);
        ocs.put(oc, ocName);
      }
      applyModificationToObjectclass(mod, relaxConstraints);
    }
    else
    {
      applyModificationToNonObjectclass(mod, relaxConstraints);
    }
  }
      switch (mod.getModificationType().asEnum())
      {
        case ADD:
          for (ObjectClass oc : ocs.keySet())
          {
            if (objectClasses.containsKey(oc))
            {
              if (!relaxConstraints)
              {
                LocalizableMessage message = ERR_ENTRY_DUPLICATE_VALUES.get(a.getName());
                throw new DirectoryException(ATTRIBUTE_OR_VALUE_EXISTS,message);
              }
            }
            else
            {
              objectClasses.put(oc, ocs.get(oc));
            }
          }
          objectClassAttribute = null;
          break;
  private void applyModificationToObjectclass(Modification mod, boolean relaxConstraints) throws DirectoryException
  {
    Attribute a = mod.getAttribute();
        case DELETE:
          for (ObjectClass oc : ocs.keySet())
          {
            if (objectClasses.remove(oc) == null && !relaxConstraints)
            {
              LocalizableMessage message = ERR_ENTRY_NO_SUCH_VALUE.get(a.getName());
              throw new DirectoryException(NO_SUCH_ATTRIBUTE, message);
            }
          }
          objectClassAttribute = null;
          break;
        case REPLACE:
          objectClasses = ocs;
          objectClassAttribute = null;
          break;
        case INCREMENT:
          LocalizableMessage message = ERR_ENTRY_OC_INCREMENT_NOT_SUPPORTED.get();
          throw new DirectoryException(CONSTRAINT_VIOLATION, message);
        default:
          message = ERR_ENTRY_UNKNOWN_MODIFICATION_TYPE.get(mod.getModificationType());
          throw new DirectoryException(UNWILLING_TO_PERFORM, message);
      }
      return;
    Map<ObjectClass, String> ocs = new LinkedHashMap<>();
    for (ByteString v : a)
    {
      String ocName = v.toString();
      String lowerName = toLowerCase(ocName);
      ObjectClass oc = DirectoryServer.getObjectClass(lowerName, true);
      ocs.put(oc, ocName);
    }
    switch (mod.getModificationType().asEnum())
    {
      case ADD:
        List<ByteString> duplicateValues = new LinkedList<>();
        addAttribute(a, duplicateValues);
        if (!duplicateValues.isEmpty() && !relaxConstraints)
    case ADD:
      for (ObjectClass oc : ocs.keySet())
      {
        if (objectClasses.containsKey(oc))
        {
          LocalizableMessage message = ERR_ENTRY_DUPLICATE_VALUES.get(a.getName());
          throw new DirectoryException(ATTRIBUTE_OR_VALUE_EXISTS, message);
          if (!relaxConstraints)
          {
            LocalizableMessage message = ERR_ENTRY_DUPLICATE_VALUES.get(a.getName());
            throw new DirectoryException(ATTRIBUTE_OR_VALUE_EXISTS, message);
          }
        }
        break;
        else
        {
          objectClasses.put(oc, ocs.get(oc));
        }
      }
      objectClassAttribute = null;
      break;
      case DELETE:
        List<ByteString> missingValues = new LinkedList<>();
        removeAttribute(a, missingValues);
        if (!missingValues.isEmpty() && !relaxConstraints)
    case DELETE:
      for (ObjectClass oc : ocs.keySet())
      {
        if (objectClasses.remove(oc) == null && !relaxConstraints)
        {
          LocalizableMessage message = ERR_ENTRY_NO_SUCH_VALUE.get(a.getName());
          throw new DirectoryException(NO_SUCH_ATTRIBUTE, message);
        }
        break;
      }
      objectClassAttribute = null;
      break;
      case REPLACE:
        replaceAttribute(a);
        break;
    case REPLACE:
      objectClasses = ocs;
      objectClassAttribute = null;
      break;
      case INCREMENT:
        incrementAttribute(a);
        break;
    case INCREMENT:
      LocalizableMessage message = ERR_ENTRY_OC_INCREMENT_NOT_SUPPORTED.get();
      throw new DirectoryException(CONSTRAINT_VIOLATION, message);
      default:
        LocalizableMessage message = ERR_ENTRY_UNKNOWN_MODIFICATION_TYPE.get(mod.getModificationType());
        throw new DirectoryException(UNWILLING_TO_PERFORM, message);
    default:
      message = ERR_ENTRY_UNKNOWN_MODIFICATION_TYPE.get(mod.getModificationType());
      throw new DirectoryException(UNWILLING_TO_PERFORM, message);
    }
  }
  private void applyModificationToNonObjectclass(Modification mod, boolean relaxConstraints) throws DirectoryException
  {
    Attribute a = mod.getAttribute();
    switch (mod.getModificationType().asEnum())
    {
    case ADD:
      List<ByteString> duplicateValues = new LinkedList<>();
      addAttribute(a, duplicateValues);
      if (!duplicateValues.isEmpty() && !relaxConstraints)
      {
        LocalizableMessage message = ERR_ENTRY_DUPLICATE_VALUES.get(a.getName());
        throw new DirectoryException(ATTRIBUTE_OR_VALUE_EXISTS, message);
      }
      break;
    case DELETE:
      List<ByteString> missingValues = new LinkedList<>();
      removeAttribute(a, missingValues);
      if (!missingValues.isEmpty() && !relaxConstraints)
      {
        LocalizableMessage message = ERR_ENTRY_NO_SUCH_VALUE.get(a.getName());
        throw new DirectoryException(NO_SUCH_ATTRIBUTE, message);
      }
      break;
    case REPLACE:
      replaceAttribute(a);
      break;
    case INCREMENT:
      incrementAttribute(a);
      break;
    default:
      LocalizableMessage message = ERR_ENTRY_UNKNOWN_MODIFICATION_TYPE.get(mod.getModificationType());
      throw new DirectoryException(UNWILLING_TO_PERFORM, message);
    }
  }
@@ -2553,15 +2549,9 @@
      for (Attribute a : sourceList)
      {
        if (omitReal && !a.isVirtual())
        {
          continue;
        }
        else if (omitVirtual && a.isVirtual())
        {
          continue;
        }
        else if (omitEmpty && a.isEmpty())
        if ((omitReal && a.isReal())
            || (omitVirtual && a.isVirtual())
            || (omitEmpty && a.isEmpty()))
        {
          continue;
        }
@@ -2573,9 +2563,8 @@
        if (!targetList.isEmpty() && mergeDuplicates)
        {
          // Ensure that there is only one attribute with the same
          // type and options. This is not very efficient but will
          // occur very rarely.
          // Ensure that there is only one attribute with the same type and options.
          // This is not very efficient but will occur very rarely.
          boolean found = false;
          for (int i = 0; i < targetList.size(); i++)
          {
@@ -2608,9 +2597,8 @@
  /**
   * Indicates whether this entry meets the criteria to consider it a
   * referral (e.g., it contains the "referral" objectclass and a
   * "ref" attribute).
   * Indicates whether this entry meets the criteria to consider it a referral
   * (e.g., it contains the "referral" objectclass and a "ref" attribute).
   *
   * @return  <CODE>true</CODE> if this entry meets the criteria to
   *          consider it a referral, or <CODE>false</CODE> if not.
@@ -4813,19 +4801,10 @@
    for (Attribute attribute : sourceList)
    {
      if (attribute.isEmpty())
      {
        continue;
      }
      else if (omitReal && !attribute.isVirtual())
      {
        continue;
      }
      else if (omitVirtual && attribute.isVirtual())
      {
        continue;
      }
      else if (!attribute.hasAllOptions(options))
      if (attribute.isEmpty()
          || (omitReal && attribute.isReal())
          || (omitVirtual && attribute.isVirtual())
          || !attribute.hasAllOptions(options))
      {
        continue;
      }
@@ -4847,12 +4826,11 @@
          // want to rename "name" to "cn".
          if (attrName == null || !subAttrType.equals(attrType))
          {
            builder.setAttributeType(attribute.getAttributeType(),
                attribute.getName());
            builder.setAttributeType(subAttrType, attribute.getName());
          }
          else
          {
            builder.setAttributeType(attribute.getAttributeType(), attrName);
            builder.setAttributeType(subAttrType, attrName);
          }
          if (options != null)
@@ -4895,8 +4873,7 @@
          // This may occur in two cases:
          //
          // 1) The attribute is identified by more than one attribute
          //    type description in the attribute list (e.g. in a
          //    wildcard).
          //    type description in the attribute list (e.g. in a wildcard).
          //
          // 2) The attribute has both a real and virtual component.
          //
@@ -4924,4 +4901,3 @@
    }
  }
}