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 @@ } } }