From 8d673dd2b125d0b974eb1e8376e053731c628354 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Wed, 19 Sep 2012 22:52:22 +0000
Subject: [PATCH] Fix OPENDJ-157: Make methods like Entry.getAttribute(String) more user friendly
---
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Attributes.java | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 213 insertions(+), 7 deletions(-)
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Attributes.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Attributes.java
index ff43d3d..49360e3 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Attributes.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Attributes.java
@@ -30,6 +30,8 @@
import java.util.Collection;
import java.util.Iterator;
+import org.forgerock.i18n.LocalizedIllegalArgumentException;
+
import com.forgerock.opendj.util.Iterators;
import com.forgerock.opendj.util.Validator;
@@ -97,7 +99,6 @@
private static final class RenamedAttribute implements Attribute {
private final Attribute attribute;
-
private final AttributeDescription attributeDescription;
private RenamedAttribute(final Attribute attribute,
@@ -106,31 +107,38 @@
this.attributeDescription = attributeDescription;
}
+ @Override
public boolean add(final ByteString value) {
return attribute.add(value);
}
+ @Override
public boolean add(final Object firstValue, final Object... remainingValues) {
return attribute.add(firstValue, remainingValues);
}
+ @Override
public boolean addAll(final Collection<? extends ByteString> values) {
return attribute.addAll(values);
}
+ @Override
public boolean addAll(final Collection<? extends ByteString> values,
final Collection<? super ByteString> duplicateValues) {
return attribute.addAll(values, duplicateValues);
}
+ @Override
public void clear() {
attribute.clear();
}
+ @Override
public boolean contains(final Object value) {
return attribute.contains(value);
}
+ @Override
public boolean containsAll(final Collection<?> values) {
return attribute.containsAll(values);
}
@@ -140,18 +148,22 @@
return AbstractAttribute.equals(this, object);
}
+ @Override
public ByteString firstValue() {
return attribute.firstValue();
}
+ @Override
public String firstValueAsString() {
return attribute.firstValueAsString();
}
+ @Override
public AttributeDescription getAttributeDescription() {
return attributeDescription;
}
+ @Override
public String getAttributeDescriptionAsString() {
return attributeDescription.toString();
}
@@ -161,48 +173,59 @@
return AbstractAttribute.hashCode(this);
}
- public AttributeParser parse() {
- return attribute.parse();
- }
-
+ @Override
public boolean isEmpty() {
return attribute.isEmpty();
}
+ @Override
public Iterator<ByteString> iterator() {
return attribute.iterator();
}
+ @Override
+ public AttributeParser parse() {
+ return attribute.parse();
+ }
+
+ @Override
public boolean remove(final Object value) {
return attribute.remove(value);
}
+ @Override
public boolean removeAll(final Collection<?> values) {
return attribute.removeAll(values);
}
+ @Override
public <T> boolean removeAll(final Collection<T> values,
final Collection<? super T> missingValues) {
return attribute.removeAll(values, missingValues);
}
+ @Override
public boolean retainAll(final Collection<?> values) {
return attribute.retainAll(values);
}
+ @Override
public <T> boolean retainAll(final Collection<T> values,
final Collection<? super T> missingValues) {
return attribute.retainAll(values, missingValues);
}
+ @Override
public int size() {
return attribute.size();
}
+ @Override
public ByteString[] toArray() {
return attribute.toArray();
}
+ @Override
public <T> T[] toArray(final T[] array) {
return attribute.toArray(array);
}
@@ -215,6 +238,72 @@
}
/**
+ * Singleton attribute.
+ */
+ private static final class SingletonAttribute extends AbstractAttribute {
+
+ private final AttributeDescription attributeDescription;
+ private ByteString normalizedValue;
+ private final ByteString value;
+
+ private SingletonAttribute(final AttributeDescription attributeDescription,
+ final Object value) {
+ this.attributeDescription = attributeDescription;
+ this.value = ByteString.valueOf(value);
+ }
+
+ @Override
+ public boolean add(final ByteString value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean contains(final Object value) {
+ final ByteString normalizedValue = normalizeValue(this, ByteString.valueOf(value));
+ return normalizedSingleValue().equals(normalizedValue);
+ }
+
+ @Override
+ public AttributeDescription getAttributeDescription() {
+ return attributeDescription;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ @Override
+ public Iterator<ByteString> iterator() {
+ return Iterators.singletonIterator(value);
+ }
+
+ @Override
+ public boolean remove(final Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int size() {
+ return 1;
+ }
+
+ // Lazily computes the normalized single value.
+ private ByteString normalizedSingleValue() {
+ if (normalizedValue == null) {
+ normalizedValue = normalizeValue(this, value);
+ }
+ return normalizedValue;
+ }
+
+ }
+
+ /**
* Unmodifiable attribute.
*/
private static final class UnmodifiableAttribute implements Attribute {
@@ -225,31 +314,38 @@
this.attribute = attribute;
}
+ @Override
public boolean add(final ByteString value) {
throw new UnsupportedOperationException();
}
+ @Override
public boolean add(final Object firstValue, final Object... remainingValues) {
throw new UnsupportedOperationException();
}
+ @Override
public boolean addAll(final Collection<? extends ByteString> values) {
throw new UnsupportedOperationException();
}
+ @Override
public boolean addAll(final Collection<? extends ByteString> values,
final Collection<? super ByteString> duplicateValues) {
throw new UnsupportedOperationException();
}
+ @Override
public void clear() {
throw new UnsupportedOperationException();
}
+ @Override
public boolean contains(final Object value) {
return attribute.contains(value);
}
+ @Override
public boolean containsAll(final Collection<?> values) {
return attribute.containsAll(values);
}
@@ -259,18 +355,22 @@
return (object == this || attribute.equals(object));
}
+ @Override
public ByteString firstValue() {
return attribute.firstValue();
}
+ @Override
public String firstValueAsString() {
return attribute.firstValueAsString();
}
+ @Override
public AttributeDescription getAttributeDescription() {
return attribute.getAttributeDescription();
}
+ @Override
public String getAttributeDescriptionAsString() {
return attribute.getAttributeDescriptionAsString();
}
@@ -280,48 +380,59 @@
return attribute.hashCode();
}
+ @Override
public boolean isEmpty() {
return attribute.isEmpty();
}
+ @Override
public Iterator<ByteString> iterator() {
return Iterators.unmodifiableIterator(attribute.iterator());
}
+ @Override
public AttributeParser parse() {
return attribute.parse();
}
+ @Override
public boolean remove(final Object value) {
throw new UnsupportedOperationException();
}
+ @Override
public boolean removeAll(final Collection<?> values) {
throw new UnsupportedOperationException();
}
+ @Override
public <T> boolean removeAll(final Collection<T> values,
final Collection<? super T> missingValues) {
throw new UnsupportedOperationException();
}
+ @Override
public boolean retainAll(final Collection<?> values) {
throw new UnsupportedOperationException();
}
+ @Override
public <T> boolean retainAll(final Collection<T> values,
final Collection<? super T> missingValues) {
throw new UnsupportedOperationException();
}
+ @Override
public int size() {
return attribute.size();
}
+ @Override
public ByteString[] toArray() {
return attribute.toArray();
}
+ @Override
public <T> T[] toArray(final T[] array) {
return attribute.toArray(array);
}
@@ -330,12 +441,13 @@
public String toString() {
return attribute.toString();
}
-
}
/**
* Returns a read-only empty attribute having the specified attribute
- * description.
+ * description. Attempts to modify the returned attribute either directly,
+ * or indirectly via an iterator, result in an
+ * {@code UnsupportedOperationException}.
*
* @param attributeDescription
* The attribute description.
@@ -348,6 +460,26 @@
}
/**
+ * Returns a read-only empty attribute having the specified attribute
+ * description. The attribute description will be decoded using the default
+ * schema. Attempts to modify the returned attribute either directly, or
+ * indirectly via an iterator, result in an
+ * {@code UnsupportedOperationException}.
+ *
+ * @param attributeDescription
+ * The attribute description.
+ * @return The empty attribute.
+ * @throws LocalizedIllegalArgumentException
+ * If {@code attributeDescription} could not be decoded using
+ * the default schema.
+ * @throws NullPointerException
+ * If {@code attributeDescription} was {@code null}.
+ */
+ public static final Attribute emptyAttribute(final String attributeDescription) {
+ return emptyAttribute(AttributeDescription.valueOf(attributeDescription));
+ }
+
+ /**
* Returns a view of {@code attribute} having a different attribute
* description. All operations on the returned attribute "pass-through" to
* the underlying attribute.
@@ -368,6 +500,80 @@
}
/**
+ * Returns a view of {@code attribute} having a different attribute
+ * description. All operations on the returned attribute "pass-through" to
+ * the underlying attribute. The attribute description will be decoded using
+ * the default schema.
+ *
+ * @param attribute
+ * The attribute to be renamed.
+ * @param attributeDescription
+ * The new attribute description for {@code attribute}.
+ * @return A renamed view of {@code attribute}.
+ * @throws LocalizedIllegalArgumentException
+ * If {@code attributeDescription} could not be decoded using
+ * the default schema.
+ * @throws NullPointerException
+ * If {@code attribute} or {@code attributeDescription} was
+ * {@code null}.
+ */
+ public static final Attribute renameAttribute(final Attribute attribute,
+ final String attributeDescription) {
+ Validator.ensureNotNull(attribute, attributeDescription);
+ return renameAttribute(attribute, AttributeDescription.valueOf(attributeDescription));
+ }
+
+ /**
+ * Returns a read-only single-valued attribute having the specified
+ * attribute description and value. Attempts to modify the returned
+ * attribute either directly, or indirectly via an iterator, result in an
+ * {@code UnsupportedOperationException}.
+ * <p>
+ * If {@code value} is not an instance of {@code ByteString} then it will be
+ * converted using the {@link ByteString#valueOf(Object)} method.
+ *
+ * @param attributeDescription
+ * The attribute description.
+ * @param value
+ * The single attribute value.
+ * @return The single-valued attribute.
+ * @throws NullPointerException
+ * If {@code attributeDescription} or {@code value} was
+ * {@code null}.
+ */
+ public static final Attribute singletonAttribute(
+ final AttributeDescription attributeDescription, final Object value) {
+ return new SingletonAttribute(attributeDescription, value);
+ }
+
+ /**
+ * Returns a read-only single-valued attribute having the specified
+ * attribute description. The attribute description will be decoded using
+ * the default schema. Attempts to modify the returned attribute either
+ * directly, or indirectly via an iterator, result in an
+ * {@code UnsupportedOperationException}.
+ * <p>
+ * If {@code value} is not an instance of {@code ByteString} then it will be
+ * converted using the {@link ByteString#valueOf(Object)} method.
+ *
+ * @param attributeDescription
+ * The attribute description.
+ * @param value
+ * The single attribute value.
+ * @return The single-valued attribute.
+ * @throws LocalizedIllegalArgumentException
+ * If {@code attributeDescription} could not be decoded using
+ * the default schema.
+ * @throws NullPointerException
+ * If {@code attributeDescription} or {@code value} was
+ * {@code null}.
+ */
+ public static final Attribute singletonAttribute(final String attributeDescription,
+ final Object value) {
+ return singletonAttribute(AttributeDescription.valueOf(attributeDescription), value);
+ }
+
+ /**
* Returns a read-only view of {@code attribute}. Query operations on the
* returned attribute "read-through" to the underlying attribute, and
* attempts to modify the returned attribute either directly or indirectly
--
Gitblit v1.10.0