You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ml...@apache.org on 2006/06/01 13:01:47 UTC

svn commit: r410834 [1/3] - /incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/

Author: mloenko
Date: Thu Jun  1 04:01:47 2006
New Revision: 410834

URL: http://svn.apache.org/viewvc?rev=410834&view=rev
Log:
fixes for HARMONY-545
javax.naming.directory generifications

Modified:
    incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/Attribute.java
    incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/Attributes.java
    incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/BasicAttribute.java
    incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/BasicAttributes.java
    incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/BasicNamingEnumeration.java
    incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/DirContext.java
    incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/InitialDirContext.java

Modified: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/Attribute.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/Attribute.java?rev=410834&r1=410833&r2=410834&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/Attribute.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/Attribute.java Thu Jun  1 04:01:47 2006
@@ -11,283 +11,283 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- */
-
-
-package javax.naming.directory;
-
-import java.io.Serializable;
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.directory.DirContext;
-
-/**
- * This interface defines the valid operations on a particular attribute of a
- * directory entry.
- * <p>
- * An attribute can have zero or more values. The value may be null.</p>
- * <p>
- * When there are multiple values for a particular attribute, the collection of
- * values may be specifically ordered or unordered. This interface provides a
- * method for determining whether the order is maintained.</p>
- * <p>
- * If the values of an attribute are ordered, then duplicates are allowed. If
- * the values are unordered then duplicates are not allowed.</p>
- * <p>
- * If the values are unordered then the indexed operations work as if the values
- * added previously to the attribute had been done using ordered semantics. For
- * example, if the values "a", "b" and "c" were previously added to an unordered
- * attribute using "<code>add("a"); add("b"); add("c");</code>", it is 
- * equivalent to adding the same objects to an ordered attribute using 
- * "<code>add(0,"a"); add(1,"b"); add(2,"c");</code>". In this case, if we do 
- * "<code>remove(1)</code>" on the unordered list, the value "b" is removed, 
- * changing the index of "c" to 1.</p> 
- * <p>
- * Multiple null values can be added to an attribute. It is not the same as
- * having no values on an attribute. If a null value is added to an unordered
- * attribute which already has a null value, the <code>add</code> method has no
- * effect.</p>
- * <p>
- * A directory may optionally provide information about the syntax of an
- * attribute's value via a schema. The methods <code>getAttributeDefinition</code>
- * and <code>getAttributeSyntaxDefinition</code> return the schema definitions
- * if they exist.</p>
- * <p>
- * Note that updates to the attribute via ths interface do not affect the
- * directory directly. The only mechanism for modifying the directory is
- * through the {@link DirContext}.</p>
- * <p>
- * Concrete implementations of this <code>Attribute</code> interface may be 
- * either static or dynamic, and this interface does not make any distinction
- * between the two types. A static attribute implementation retrieves its value
- * from the directory once and stores it locally, a dynamic attribute 
- * implementation will go back to the directory for each request.</p>    
- *
- * 
- */
-public interface Attribute extends Cloneable, Serializable {
-
-    /*
-     * -------------------------------------------------------------------
-     * Constants
-     * -------------------------------------------------------------------
-     */
-
-    /* 
-     * This constant is used during deserialization to check the J2SE version which
-     * created the serialized object.
-     */
-    static final long serialVersionUID = 0x78d7ee3675a55244L; //J2SE 1.4.2
-
-    /*
-     * -------------------------------------------------------------------
-     * Methods
-     * -------------------------------------------------------------------
-     */
-
-    /**
-     * Adds a value at the specified index.
-     * The index is only meaningful if the values are ordered. If there are 
-     * already values at this index and above, they are moved up one position.
-     * <p>
-     * It is permissible to use this method when the values are not ordered but
-     * in this case, if a value equals to <code>val</code> already exists then 
-     * this method throws an <code>IllegalStateException</code> because 
-     * duplicates are not allowed.</p>
-     * <p>
-     * The permitted range for index is 0 &lt;= index &lt;= <code>size()</code>. 
-     * The range allows the list to grow by one. If the index is outside this 
-     * range this method throws an <code>IndexOutOfBoundsException</code>.</p>
-     * 
-     * @param index             the position index
-     * @param val               a new value to be added which may be null
-     * @throws IllegalStateException
-     *                          If the new value equals to an existing value in
-     *                          an unordered <code>Attribute</code>.
-     * @throws IndexOutOfBoundsException
-     *                          If the index is invalid.
-     */
-    void add(int index, Object val);
-
-    /**
-     * Adds a value to this attribute.
-     * For unordered attribute values this method adds the new value unless the
-     * value is already present. If the new value is already present in 
-     * unordered attribute values, the method has no effect.
-     * <p>
-     * For ordered attribute values, the new value is added at the end of list 
-     * of values.</p>
-     * <p>
-     * This method returns true or false to indicate whether a value was added.</p>
-     *
-     * @param val               a new value to be added which may be null
-     * @return                  true if a value was added, otherwise false
-     */
-    boolean add(Object val);
-
-    /**
-     * Clears all values of this attribute.
-     */
-    void clear();
-
-    /**
-     * Returns a deep copy of the attribute containing all the same values.
-     * The values are not cloned.
-     * 
-     * @return                  a deep clone of this attribute
-     */
-    Object clone();
-
-    /**
-     * Inidicates whether the specified value is one of the attribute's values.
-     * 
-     * @param val               the value which may be null
-     * @return                  true if this attribute contains the value, 
-     *                          otherwise false
-     */
-    boolean contains(Object val);
-
-    /**
-     * Gets a value of this attribute.
-     * For unordered values, returns any of the values. For ordered values, 
-     * returns the first. <code>null</code> is a valid value.
-     * <p>
-     * If the attribute has no values this method throws 
-     * <code>NoSuchElementException</code>.</p>
-    
-     * @return                  a value of this attribute
-     * @throws NamingException  If the attribute has no value.
-     */
-    Object get() throws NamingException;
-
-    /**
-     * Returns the value at the specified index, even for unordered values.
-     * This method throws <code>IndexOutOfBoundsException</code> if the index is
-     * outside the valid range 0 &lt;= index &lt; <code>size()</code>.
-     * 
-     * <p>
-     * If the attribute has no values this method throws 
-     * <code>NoSuchElementException</code>.</p>
-     *
-     * @param index             the position index
-     * @return                  the value at the specified index
-     * @throws IndexOutOfBoundsException
-     *                          If the index is invalid.
-     * @throws NamingException  If the attribute has no value.
-     */
-    Object get(int index) throws NamingException;
-
-    /**
-     * Returns an enumeration of all the attribute's values.
-     * The enumeration is ordered if the values are.
-     * <p>
-     * The effect on the returned enumeration of adding or removing values of
-     * the attribute is not specified.</p>
-     * <p>
-     * This method will throw any <code>NamingException</code> that occurs.</p>
-     *
-     * @return                  an enumeration of all values of the attribute
-     * @throws NamingException  If any <code>NamingException</code> occurs.
-     */
-    NamingEnumeration getAll() throws NamingException;
-
-    /**
-     * Returns the attribute's schema definition. 
-     * If this operation is not supported, an <code>
-     * OperationNotSupportedException</code> is thrown. If the implementation 
-     * supports schemas but no schema is set, it is valid to return null.
-     * <p>
-     * This method will throw any <code>NamingException</code> that occurs.</p>
-     *
-     * @return                  the schema definitions if they exist
-     * @throws NamingException  If any <code>NamingException</code> occurs.
-     */
-    DirContext getAttributeDefinition() throws NamingException;
-
-    /**
-     * Returns the attribute's syntax definition. 
-     * If this operation is not supported, an <code>
-     * OperationNotSupportedException</code> is thrown. If the implementation 
-     * supports syntax definitions but no syntax definition is set, it is valid
-     * to return null.
-     * <p>
-     * This method will throw any <code>NamingException</code> that occurs.</p>
-     *
-     * @return                  the syntax definitions if they exist
-     * @throws NamingException  If any <code>NamingException</code> occurs.
-     */
-    DirContext getAttributeSyntaxDefinition() throws NamingException;
-
-    /**
-     * Returns the identity of this attribute.
-     * This method is not expected to return null.
-     *
-     * @return                  the ID of this attribute
-     */
-    String getID();
-
-    /**
-     * Indicates whether the values of this attribute are ordered or not.
-     * 
-     * @return                  true if the values of this attribute are 
-     *                          ordered, otherwise false
-     */
-    boolean isOrdered();
-
-    /**
-     * Removes the values at the specified index, even for unordered values.
-     * Values at higher indexes move one position lower.
-     * <p>
-     * If the index is outside the valid range 0 &lt;= index &lt; <code>size()</code>
-     * this method throws an <code>IndexOutOfBoundsException</code>.</p>
-     * 
-     * @param index             the position index
-     * @return                  the removed value
-     * @throws IndexOutOfBoundsException
-     *                          If the index is invalid.
-     */
-    Object remove(int index);
-
-    /**
-     * Removes a value that is equal to the given value.
-     * There may be more than one match in ordered value, in which case the
-     * equal value with the lowest index is removed. After an ordered value is
-     * removed, values at higher indexes move one position lower.
-     * <p>
-     * Returns true if a value is removed. If there is no value equal to <code>
-     * val</code> this method simply returns false.</p>
-     *
-     * @param val               the value to be removed
-     * @return                  true if the value is removed, otherwise false
-     */
-    boolean remove(Object val);
-
-    /**
-     * Replaces the value at the specified index with the given value.
-     * The old value (which may be null) is returned.
-     * <p>
-     * If the values are unordered and the given value is already present this
-     * method throws an <code>IllegalStateException</code>.</p>
-     * <p>
-     * The valid range for the index is 0 &lt;= index &lt; <code>size()</code>.
-     * This method throws an <code>IndexOutOfBoundsException</code> if the index
-     * is outside this range.</p>
-     *
-     * @param index             the position index
-     * @param val               the new value
-     * @return                  the original value at the specified index
-     * @throws IndexOutOfBoundsException
-     *                          If the index is invalid.
-     */
-    Object set(int index, Object val);
-
-    /**
-     * Gets the count of the values in this attribute.
-     * 
-     * @return                  the count of the values in this attribute
-     */
-    int size();
-
-}
-
-
+ */
+
+
+package javax.naming.directory;
+
+import java.io.Serializable;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+
+/**
+ * This interface defines the valid operations on a particular attribute of a
+ * directory entry.
+ * <p>
+ * An attribute can have zero or more values. The value may be null.</p>
+ * <p>
+ * When there are multiple values for a particular attribute, the collection of
+ * values may be specifically ordered or unordered. This interface provides a
+ * method for determining whether the order is maintained.</p>
+ * <p>
+ * If the values of an attribute are ordered, then duplicates are allowed. If
+ * the values are unordered then duplicates are not allowed.</p>
+ * <p>
+ * If the values are unordered then the indexed operations work as if the values
+ * added previously to the attribute had been done using ordered semantics. For
+ * example, if the values "a", "b" and "c" were previously added to an unordered
+ * attribute using "<code>add("a"); add("b"); add("c");</code>", it is 
+ * equivalent to adding the same objects to an ordered attribute using 
+ * "<code>add(0,"a"); add(1,"b"); add(2,"c");</code>". In this case, if we do 
+ * "<code>remove(1)</code>" on the unordered list, the value "b" is removed, 
+ * changing the index of "c" to 1.</p> 
+ * <p>
+ * Multiple null values can be added to an attribute. It is not the same as
+ * having no values on an attribute. If a null value is added to an unordered
+ * attribute which already has a null value, the <code>add</code> method has no
+ * effect.</p>
+ * <p>
+ * A directory may optionally provide information about the syntax of an
+ * attribute's value via a schema. The methods <code>getAttributeDefinition</code>
+ * and <code>getAttributeSyntaxDefinition</code> return the schema definitions
+ * if they exist.</p>
+ * <p>
+ * Note that updates to the attribute via ths interface do not affect the
+ * directory directly. The only mechanism for modifying the directory is
+ * through the {@link DirContext}.</p>
+ * <p>
+ * Concrete implementations of this <code>Attribute</code> interface may be 
+ * either static or dynamic, and this interface does not make any distinction
+ * between the two types. A static attribute implementation retrieves its value
+ * from the directory once and stores it locally, a dynamic attribute 
+ * implementation will go back to the directory for each request.</p>    
+ *
+ * 
+ */
+public interface Attribute extends Cloneable, Serializable {
+
+    /*
+     * -------------------------------------------------------------------
+     * Constants
+     * -------------------------------------------------------------------
+     */
+
+    /* 
+     * This constant is used during deserialization to check the J2SE version which
+     * created the serialized object.
+     */
+    static final long serialVersionUID = 0x78d7ee3675a55244L; //J2SE 1.4.2
+
+    /*
+     * -------------------------------------------------------------------
+     * Methods
+     * -------------------------------------------------------------------
+     */
+
+    /**
+     * Adds a value at the specified index.
+     * The index is only meaningful if the values are ordered. If there are 
+     * already values at this index and above, they are moved up one position.
+     * <p>
+     * It is permissible to use this method when the values are not ordered but
+     * in this case, if a value equals to <code>val</code> already exists then 
+     * this method throws an <code>IllegalStateException</code> because 
+     * duplicates are not allowed.</p>
+     * <p>
+     * The permitted range for index is 0 &lt;= index &lt;= <code>size()</code>. 
+     * The range allows the list to grow by one. If the index is outside this 
+     * range this method throws an <code>IndexOutOfBoundsException</code>.</p>
+     * 
+     * @param index             the position index
+     * @param val               a new value to be added which may be null
+     * @throws IllegalStateException
+     *                          If the new value equals to an existing value in
+     *                          an unordered <code>Attribute</code>.
+     * @throws IndexOutOfBoundsException
+     *                          If the index is invalid.
+     */
+    void add(int index, Object val);
+
+    /**
+     * Adds a value to this attribute.
+     * For unordered attribute values this method adds the new value unless the
+     * value is already present. If the new value is already present in 
+     * unordered attribute values, the method has no effect.
+     * <p>
+     * For ordered attribute values, the new value is added at the end of list 
+     * of values.</p>
+     * <p>
+     * This method returns true or false to indicate whether a value was added.</p>
+     *
+     * @param val               a new value to be added which may be null
+     * @return                  true if a value was added, otherwise false
+     */
+    boolean add(Object val);
+
+    /**
+     * Clears all values of this attribute.
+     */
+    void clear();
+
+    /**
+     * Returns a deep copy of the attribute containing all the same values.
+     * The values are not cloned.
+     * 
+     * @return                  a deep clone of this attribute
+     */
+    Object clone();
+
+    /**
+     * Inidicates whether the specified value is one of the attribute's values.
+     * 
+     * @param val               the value which may be null
+     * @return                  true if this attribute contains the value, 
+     *                          otherwise false
+     */
+    boolean contains(Object val);
+
+    /**
+     * Gets a value of this attribute.
+     * For unordered values, returns any of the values. For ordered values, 
+     * returns the first. <code>null</code> is a valid value.
+     * <p>
+     * If the attribute has no values this method throws 
+     * <code>NoSuchElementException</code>.</p>
+    
+     * @return                  a value of this attribute
+     * @throws NamingException  If the attribute has no value.
+     */
+    Object get() throws NamingException;
+
+    /**
+     * Returns the value at the specified index, even for unordered values.
+     * This method throws <code>IndexOutOfBoundsException</code> if the index is
+     * outside the valid range 0 &lt;= index &lt; <code>size()</code>.
+     * 
+     * <p>
+     * If the attribute has no values this method throws 
+     * <code>NoSuchElementException</code>.</p>
+     *
+     * @param index             the position index
+     * @return                  the value at the specified index
+     * @throws IndexOutOfBoundsException
+     *                          If the index is invalid.
+     * @throws NamingException  If the attribute has no value.
+     */
+    Object get(int index) throws NamingException;
+
+    /**
+     * Returns an enumeration of all the attribute's values.
+     * The enumeration is ordered if the values are.
+     * <p>
+     * The effect on the returned enumeration of adding or removing values of
+     * the attribute is not specified.</p>
+     * <p>
+     * This method will throw any <code>NamingException</code> that occurs.</p>
+     *
+     * @return                  an enumeration of all values of the attribute
+     * @throws NamingException  If any <code>NamingException</code> occurs.
+     */
+    NamingEnumeration<?> getAll() throws NamingException;
+
+    /**
+     * Returns the attribute's schema definition. 
+     * If this operation is not supported, an <code>
+     * OperationNotSupportedException</code> is thrown. If the implementation 
+     * supports schemas but no schema is set, it is valid to return null.
+     * <p>
+     * This method will throw any <code>NamingException</code> that occurs.</p>
+     *
+     * @return                  the schema definitions if they exist
+     * @throws NamingException  If any <code>NamingException</code> occurs.
+     */
+    DirContext getAttributeDefinition() throws NamingException;
+
+    /**
+     * Returns the attribute's syntax definition. 
+     * If this operation is not supported, an <code>
+     * OperationNotSupportedException</code> is thrown. If the implementation 
+     * supports syntax definitions but no syntax definition is set, it is valid
+     * to return null.
+     * <p>
+     * This method will throw any <code>NamingException</code> that occurs.</p>
+     *
+     * @return                  the syntax definitions if they exist
+     * @throws NamingException  If any <code>NamingException</code> occurs.
+     */
+    DirContext getAttributeSyntaxDefinition() throws NamingException;
+
+    /**
+     * Returns the identity of this attribute.
+     * This method is not expected to return null.
+     *
+     * @return                  the ID of this attribute
+     */
+    String getID();
+
+    /**
+     * Indicates whether the values of this attribute are ordered or not.
+     * 
+     * @return                  true if the values of this attribute are 
+     *                          ordered, otherwise false
+     */
+    boolean isOrdered();
+
+    /**
+     * Removes the values at the specified index, even for unordered values.
+     * Values at higher indexes move one position lower.
+     * <p>
+     * If the index is outside the valid range 0 &lt;= index &lt; <code>size()</code>
+     * this method throws an <code>IndexOutOfBoundsException</code>.</p>
+     * 
+     * @param index             the position index
+     * @return                  the removed value
+     * @throws IndexOutOfBoundsException
+     *                          If the index is invalid.
+     */
+    Object remove(int index);
+
+    /**
+     * Removes a value that is equal to the given value.
+     * There may be more than one match in ordered value, in which case the
+     * equal value with the lowest index is removed. After an ordered value is
+     * removed, values at higher indexes move one position lower.
+     * <p>
+     * Returns true if a value is removed. If there is no value equal to <code>
+     * val</code> this method simply returns false.</p>
+     *
+     * @param val               the value to be removed
+     * @return                  true if the value is removed, otherwise false
+     */
+    boolean remove(Object val);
+
+    /**
+     * Replaces the value at the specified index with the given value.
+     * The old value (which may be null) is returned.
+     * <p>
+     * If the values are unordered and the given value is already present this
+     * method throws an <code>IllegalStateException</code>.</p>
+     * <p>
+     * The valid range for the index is 0 &lt;= index &lt; <code>size()</code>.
+     * This method throws an <code>IndexOutOfBoundsException</code> if the index
+     * is outside this range.</p>
+     *
+     * @param index             the position index
+     * @param val               the new value
+     * @return                  the original value at the specified index
+     * @throws IndexOutOfBoundsException
+     *                          If the index is invalid.
+     */
+    Object set(int index, Object val);
+
+    /**
+     * Gets the count of the values in this attribute.
+     * 
+     * @return                  the count of the values in this attribute
+     */
+    int size();
+
+}
+
+

Modified: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/Attributes.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/Attributes.java?rev=410834&r1=410833&r2=410834&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/Attributes.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/Attributes.java Thu Jun  1 04:01:47 2006
@@ -11,135 +11,135 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- */
-
-
-package javax.naming.directory;
-
-import java.io.Serializable;
-import javax.naming.NamingEnumeration;
-
-/**
- * This is the interface to a collection of attributes associated with a directory
- * entry.
- * <p>
- * This interface defines the methods that are implemented by a collection of a
- * particular directory entry's attributes.</p>
- * <p>
- * A directory entry can have zero or more attributes comprising its attributes
- * collection. The attributes are unordered within the collection.  The
- * attributes can be identified by name. The names of attributes are either
- * case sensitive or case insensitive as indicated by the <code>isCaseIgnored</code>
- * method. Method names refer to attribute ID (identity) rather than name, 
- * for brevity.</p>
- * <p>
- * The attribute collection is created when the directory entry is created.</p>
- *
- * 
- */
-public interface Attributes extends Cloneable, Serializable {
-
-    /*
-     * -------------------------------------------------------------------
-     * Methods
-     * -------------------------------------------------------------------
-     */
-
-    /**
-     * Returns a deep copy of this <code>Attributes</code> instance. 
-     * The attribute objects are not cloned.
-     *
-     * @return              a deep copy of this <code>Attributes</code> instance
-     */
-    Object clone();
-
-    /**
-     * Returns the attribute with the specified name (ID).
-     * The name is case insensitive if <code>isCaseIgnored()</code> is true. The
-     * return value is <code>null</code> if no match is found.
-     *
-     * @param id            attribute name (ID)
-     * @return              the attribute with the specified name (ID)
-     */
-    Attribute get(String id);
-
-    /**
-     * Returns an enumeration containing the zero or more attributes in the
-     * collection.
-     * The behaviour of the enumeration is not specified if the attribute 
-     * collection is changed.
-     *
-     * @return              an enumeration of all contained attributes
-     *
-     */
-    NamingEnumeration getAll();
-
-    /**
-     * Returns an enumeration containing the zero or more names (IDs) of the
-     * attributes in the collection.
-     * The behaviour of the enumeration is not specified if the attribute 
-     * collection is changed.
-     *
-     * @return              an enumeration of the IDs of all contained attributes
-     */
-    NamingEnumeration getIDs();
-
-    /**
-     * Indicates whether case is ignored in the names of the attributes.
-     *
-     * @return              true if case is ignored, otherwise false
-     */
-    boolean isCaseIgnored();
-
-    /**
-     * Places a non-null attribute in the attribute collection.
-     * If there is already an attribute with the same ID as the new attribute,
-     * the old one is removed from the collection and is returned by this 
-     * method. If there was no attribute with the same ID the return value is
-     * <code>null</code>.
-     *
-     * @param attribute     the attribute to be put
-     * @return              the old attribute with the same ID, if exists;
-     *                      otherwise <code>null</code>
-     */
-    Attribute put(Attribute attribute);
-
-    /**
-     * Places a new attribuet with the supplied ID and value into the attribute 
-     * collection. 
-     * If there is already an attribute with the same ID, the old one is removed
-     * from the collection and is returned by this method. If there was no 
-     * attribute with the same ID the return value is <code>null</code>. The 
-     * case of the ID is ignored if <code>isCaseIgnored()</code> is true.
-     *
-     * This method provides a mechanism to put an attribute with a <code>null</code>
-     * value: the value of <code>obj</code> may be <code>null</code>.
-     *
-     * @param id            the ID of the new attribute to be put
-     * @param obj           the value of the new attribute to be put
-     * @return              the old attribute with the same ID, if exists;
-     *                      otherwise <code>null</code>
-     */
-    Attribute put(String id, Object obj);
-
-    /**
-     * Removes the attribute with the specified ID.
-     * The removed attribute is returned by this method. If there is no 
-     * attribute with the specified ID, the return value is <code>null</code>. 
-     * The case of the ID is ignored if <code>isCaseIgnored()</code> is true.
-     * 
-     * @param id            the ID of the attribute to be removed
-     * @return              the removed attribute, if exists; otherwise <code>null</code>
-     */
-    Attribute remove(String id);
-
-    /**
-     * Returns the number of attributes.
-     * 
-     * @return              the number of attributes
-     */
-    int size();
-
-}
-
-
+ */
+
+
+package javax.naming.directory;
+
+import java.io.Serializable;
+import javax.naming.NamingEnumeration;
+
+/**
+ * This is the interface to a collection of attributes associated with a directory
+ * entry.
+ * <p>
+ * This interface defines the methods that are implemented by a collection of a
+ * particular directory entry's attributes.</p>
+ * <p>
+ * A directory entry can have zero or more attributes comprising its attributes
+ * collection. The attributes are unordered within the collection.  The
+ * attributes can be identified by name. The names of attributes are either
+ * case sensitive or case insensitive as indicated by the <code>isCaseIgnored</code>
+ * method. Method names refer to attribute ID (identity) rather than name, 
+ * for brevity.</p>
+ * <p>
+ * The attribute collection is created when the directory entry is created.</p>
+ *
+ * 
+ */
+public interface Attributes extends Cloneable, Serializable {
+
+    /*
+     * -------------------------------------------------------------------
+     * Methods
+     * -------------------------------------------------------------------
+     */
+
+    /**
+     * Returns a deep copy of this <code>Attributes</code> instance. 
+     * The attribute objects are not cloned.
+     *
+     * @return              a deep copy of this <code>Attributes</code> instance
+     */
+    Object clone();
+
+    /**
+     * Returns the attribute with the specified name (ID).
+     * The name is case insensitive if <code>isCaseIgnored()</code> is true. The
+     * return value is <code>null</code> if no match is found.
+     *
+     * @param id            attribute name (ID)
+     * @return              the attribute with the specified name (ID)
+     */
+    Attribute get(String id);
+
+    /**
+     * Returns an enumeration containing the zero or more attributes in the
+     * collection.
+     * The behaviour of the enumeration is not specified if the attribute 
+     * collection is changed.
+     *
+     * @return              an enumeration of all contained attributes
+     *
+     */
+    NamingEnumeration<? extends javax.naming.directory.Attribute> getAll();
+
+    /**
+     * Returns an enumeration containing the zero or more names (IDs) of the
+     * attributes in the collection.
+     * The behaviour of the enumeration is not specified if the attribute 
+     * collection is changed.
+     *
+     * @return              an enumeration of the IDs of all contained attributes
+     */
+    NamingEnumeration<String> getIDs();
+
+    /**
+     * Indicates whether case is ignored in the names of the attributes.
+     *
+     * @return              true if case is ignored, otherwise false
+     */
+    boolean isCaseIgnored();
+
+    /**
+     * Places a non-null attribute in the attribute collection.
+     * If there is already an attribute with the same ID as the new attribute,
+     * the old one is removed from the collection and is returned by this 
+     * method. If there was no attribute with the same ID the return value is
+     * <code>null</code>.
+     *
+     * @param attribute     the attribute to be put
+     * @return              the old attribute with the same ID, if exists;
+     *                      otherwise <code>null</code>
+     */
+    Attribute put(Attribute attribute);
+
+    /**
+     * Places a new attribuet with the supplied ID and value into the attribute 
+     * collection. 
+     * If there is already an attribute with the same ID, the old one is removed
+     * from the collection and is returned by this method. If there was no 
+     * attribute with the same ID the return value is <code>null</code>. The 
+     * case of the ID is ignored if <code>isCaseIgnored()</code> is true.
+     *
+     * This method provides a mechanism to put an attribute with a <code>null</code>
+     * value: the value of <code>obj</code> may be <code>null</code>.
+     *
+     * @param id            the ID of the new attribute to be put
+     * @param obj           the value of the new attribute to be put
+     * @return              the old attribute with the same ID, if exists;
+     *                      otherwise <code>null</code>
+     */
+    Attribute put(String id, Object obj);
+
+    /**
+     * Removes the attribute with the specified ID.
+     * The removed attribute is returned by this method. If there is no 
+     * attribute with the specified ID, the return value is <code>null</code>. 
+     * The case of the ID is ignored if <code>isCaseIgnored()</code> is true.
+     * 
+     * @param id            the ID of the attribute to be removed
+     * @return              the removed attribute, if exists; otherwise <code>null</code>
+     */
+    Attribute remove(String id);
+
+    /**
+     * Returns the number of attributes.
+     * 
+     * @return              the number of attributes
+     */
+    int size();
+
+}
+
+

Modified: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/BasicAttribute.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/BasicAttribute.java?rev=410834&r1=410833&r2=410834&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/BasicAttribute.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/directory/BasicAttribute.java Thu Jun  1 04:01:47 2006
@@ -11,512 +11,512 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- */
-
-
-package javax.naming.directory;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.lang.reflect.Array;
-import java.util.Enumeration;
-import java.util.NoSuchElementException;
-import java.util.Vector;
-
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.OperationNotSupportedException;
-
-/**
- * A simple attribute of a directory entry.
- * <p>
- * A basic attribute does not have any schema associated with it, and attempts
- * to get the schema result in an <code>OperationNotSupportedException</code>
- * being thrown.</p>
- * <p>
- * The definition of <code>equals</code> for an attribute is simply <code>
- * Object.equals</code> on the value, except for values that are collections 
- * where the definition of <code>equals</code> is an equivalence test (i.e. the 
- * collection contains the same number of elements, and each has an equal 
- * element in the other collection). For an array, <code>Object.equals</code>
- * is used on each array element.</p>
- * <p>
- * Note that updates to a basic attribute do not update the directory itself --
- * updates to a directory are only possible through the {@link DirContext}
- * interface. <code>BasicAttribute</code> does not get its values dynamically 
- * from the directory. It uses the values passed to the constructor or add and
- * remove methods.</p>
- * 
- * @see Attribute
- * 
- */
-public class BasicAttribute implements Attribute {
-
-    /*
-     * -------------------------------------------------------------------
-     * Constants
-     * -------------------------------------------------------------------
-     */
-
-    /*
-     * This constant is used during deserialization to check the J2SE version
-     * which created the serialized object.
-     */
-    static final long serialVersionUID = 0x5d95d32a668565beL; //J2SE 1.4.2
-
-    /*
-     * -------------------------------------------------------------------
-     * Instance variables
-     * -------------------------------------------------------------------
-     */
-
-    /**
-     * The attribute identifier. 
-     * It is initialized by the public constructors and is required to be not
-     * null.
-     * 
-     * @serial
-     */
-    protected String attrID;
-
-    /**
-     * Flag showing whether the values of the attribute are ordered.
-     * 
-     * @serial 
-     */
-    protected boolean ordered;
-
-    /**
-     * <code>Vector</code> containing the attribute's values. 
-     * This is initialized by the public constructor and is required to be not 
-     * null.
-     */
-    protected transient Vector values = new Vector();
-
-    /*
-     * -------------------------------------------------------------------
-     * Constructors
-     * -------------------------------------------------------------------
-     */
-
-    /**
-     * Constructs an unordered <code>BasicAttribute</code> instance with the 
-     * supplied identifier and no values.
-     * 
-     * @param id            the attribute ID
-     */
-    public BasicAttribute(String id) {
-        this(id, false);
-    }
-
-    /**
-     * Constructs a <code>BasicAttribute</code> instance with the supplied 
-     * identifier and no values. 
-     * The supplied flag controls whether the values will be ordered or not.
-     * 
-     * @param id            the attribute ID
-     * @param flag          Indicates whether the values are ordered or not.
-     */
-    public BasicAttribute(String id, boolean flag) {
-        attrID = id;
-        ordered = flag;
-    }
-
-    /**
-     * Constructs an unordered <code>BasicAttribute</code> instance with the 
-     * supplied identifier and one value.
-     *  
-     * @param id            the attribute ID
-     * @param val           the first attribute value
-     */
-    public BasicAttribute(String id, Object val) {
-        this(id, val, false);
-    }
-
-    /**
-     * Constructs a <code>BasicAttribute</code> instance with the supplied 
-     * identifier and one value. 
-     * The supplied flag controls whether the values will be ordered or not.
-     * 
-     * @param id            the attribute ID
-     * @param val           the first attribute value
-     * @param flag          Indicates whether the values are ordered or not.
-     */
-    public BasicAttribute(String id, Object val, boolean flag) {
-        this(id, flag);
-        values.add(val);
-    }
-
-    /*
-     * -------------------------------------------------------------------
-     * Methods
-     * -------------------------------------------------------------------
-     */
-
-    /*
-     * Determine whether two values belonging to the two array classes
-     * respectively are possible to be equal.
-     */
-    private boolean compareValueClasses(Class c1, Class c2) {
-        if ((c1.getName().startsWith("[L") || c1.getName().startsWith("[[")) && //$NON-NLS-1$ //$NON-NLS-2$
-            (c2.getName().startsWith("[L") || c2.getName().startsWith("[["))) { //$NON-NLS-1$ //$NON-NLS-2$
-            /*
-             * If both Class are array of Object or array of array, the compare 
-             * result is true, even if their class name may not be the same.
-             */
-            return true;
-        } else if (c1.getName().equals(c2.getName())){
-            /*
-             * Otherwise, at least one of them must be array of basic types. If
-             * both Class have the same Class name, the compare result is true.
-             */
-            return true;
-        } else {
-            /*
-             * Otherwise, the compare result is false
-             */
-            return false;
-        }
-    }
-
-    /*
-     * Determine whether the two valuess are equal with each other, considering
-     * the possibility that they might be both arrays so that each element of 
-     * them has to be compared. 
-     */
-    private boolean compareValues(Object obj1, Object obj2) {
-        if (null == obj1 && null == obj2) {
-            // If both are null, they are considered equal.
-            return true;
-        } else if (null != obj1 && null != obj2) {
-            if (obj1.getClass().isArray() && obj2.getClass().isArray()) {
-                /*
-                 * If both are array, compare each element if it is possible
-                 * that they might be equal.
-                 */ 
-                if (compareValueClasses(obj1.getClass(), obj2.getClass())) {
-                    int i = Array.getLength(obj1);
-                    Object val1;
-                    Object val2;
-                                        
-                    // Compare each element of the two arrays
-                    if (Array.getLength(obj2) == i) {
-                        // Do the compare only if their lengths are equal
-                        for (i--; i >= 0; i--) {
-                            val1 = Array.get(obj1, i);
-                            val2 = Array.get(obj2, i);
-                            if (null == val1
-                                ? null != val2
-                                : !val1.equals(val2)) {
-                                /*
-                                 * If any of their elements at the same position
-                                 * are not equal,they are not equal.
-                                 */
-                                return false;
-                            }
-                        }
-                        // If all elements are equal, they are equal
-                        return true;
-                    }
-					// Not equal if different length
-					return false;
-                }
-				// Not equal if this can be inferred from their class names
-				return false;
-            }
-			// If not both of them are array, do a normal "equals"
-			return obj1.equals(obj2);
-        } else {
-            // Not equal if only one of them is null
-            return false;
-        }
-    }
-
-    /*
-     * Get the hash code of an attribute value, which might be an array whose 
-     * hash code is the sum of all its element. Base types are converted into
-     * corresponding wrapper class objects.     
-     */
-    private int hashCodeOfValue(Object obj) {
-        int hashcode = 0;
-
-        if (null != obj) {
-            // If the object is an array, sum up the hashcode of all elements.
-            if (obj.getClass().isArray()) {
-                Object element = null;
-                // Sum up the hashcode of all elements
-                for (int i = Array.getLength(obj) - 1; i >= 0; i--) {
-                    element = Array.get(obj, i);
-                    if (null != element) {
-                        hashcode += element.hashCode();
-                    }
-                }
-            } else {
-                // Otherwise, simply get the hashcode of the given object.
-                hashcode = obj.hashCode();
-            }
-        }
-
-        return hashcode;
-    }
-
-    /*
-     * -------------------------------------------------------------------
-     * Methods of Interface Attribute
-     * -------------------------------------------------------------------
-     */
-
-    public void add(int index, Object val) {
-        if (ordered) {
-            values.add(index, val);
-        } else {
-            if (contains(val)) {
-                throw new IllegalStateException("Value already exists."); //$NON-NLS-1$
-            }
-			values.add(index, val);
-        }
-    }
-
-    public boolean add(Object val) {
-        if (ordered) {
-            return values.add(val); // always true
-        }
-		if (contains(val)) {
-		    return false;
-		}
-		return values.add(val); // always true
-    }
-
-    public void clear() {
-        values.clear();
-    }
-
-    public Object clone() {
-        try {
-            BasicAttribute attr = (BasicAttribute) super.clone();
-            attr.values = (Vector) this.values.clone();
-            return attr;
-        } catch (CloneNotSupportedException e) {
-            throw new InternalError("Failed to clone object of BasicAttribute class."); //$NON-NLS-1$
-        }
-    }
-
-    public boolean contains(Object val) {
-        Enumeration e = this.values.elements();
-
-        while (e.hasMoreElements()) {
-            if (compareValues(e.nextElement(), val)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public Object get() throws NamingException {
-        if (0 == values.size()) {
-            throw new NoSuchElementException("No values available."); //$NON-NLS-1$
-        }
-		return values.get(0);
-    }
-
-    public Object get(int index) throws NamingException {
-        return values.get(index);
-    }
-
-    public NamingEnumeration getAll() throws NamingException {
-        return new BasicNamingEnumeration(values.elements());
-    }
-
-    public DirContext getAttributeDefinition() throws NamingException {
-        throw new OperationNotSupportedException("BasicAttribute does not support this operation."); //$NON-NLS-1$
-    }
-
-    public DirContext getAttributeSyntaxDefinition() throws NamingException {
-        throw new OperationNotSupportedException("BasicAttribute does not support this operation."); //$NON-NLS-1$
-    }
-
-    public String getID() {
-        return attrID;
-    }
-
-    public boolean isOrdered() {
-        return ordered;
-    }
-
-    public Object remove(int index) {
-        return values.remove(index);
-    }
-
-    public boolean remove(Object val) {
-        int total = this.values.size();
-
-        for (int i = 0; i < total; i++) {
-            if (compareValues(this.values.get(i), val)) {
-                this.values.remove(i);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public Object set(int index, Object val) {
-        if (!ordered && contains(val)) {
-            throw new IllegalStateException("Value already exists."); //$NON-NLS-1$
-        }
-        return values.set(index, val);
-    }
-
-    public int size() {
-        return values.size();
-    }
-
-    /*
-     * -------------------------------------------------------------------
-     * Methods override parent class Object
-     * -------------------------------------------------------------------
-     */
-
-    /*
-     * Serialization of the <code>BasicAttribute</code> class is as follows:
-     *      attribute identifier (String)
-     *      ordered flag (boolean)
-     *      number of values (int)
-     *      list of value objects
-     */
-    private void readObject(ObjectInputStream ois)
-        throws IOException, ClassNotFoundException {
-        int size;
-
-        ois.defaultReadObject();
-        size = ois.readInt();
-        this.values = new Vector();
-        for (int i = 0; i < size; i++) {
-            this.values.add(ois.readObject());
-        }
-    }
-
-    /*
-     * Serialization of the <code>BasicAttribute</code> class is as follows:
-     *      attribute identifier (String)
-     *      ordered flag (boolean)
-     *      number of values (int)
-     *      list of value objects
-     */
-    private void writeObject(ObjectOutputStream oos) throws IOException {
-        oos.defaultWriteObject();
-        oos.writeInt(this.values.size());
-        for (Enumeration e = this.values.elements(); e.hasMoreElements();) {
-            oos.writeObject(e.nextElement());
-        }
-    }
-
-    /**
-     * Returns true if this <code>BasicAttribute</code> instance is equal to the
-     * supplied object <code>obj</code>.
-     * Two attributes are considered equal if they have equal identifiers, 
-     * schemas and values. BasicAttribute uses no schema.
-     * <p>
-     * <code>Object.equals</code> is used to test equality of identifiers and 
-     * values. For array values <code>Object.equals</code> is called on every 
-     * array element.</p>
-     *
-     * @param obj           the object to be compared with
-     * @return              true if this object is equal to <code>obj</code>,
-     *                      otherwise false
-     */
-    public boolean equals(Object obj) {
-        if (obj instanceof BasicAttribute) {
-            BasicAttribute a = (BasicAttribute) obj;
-
-            if (!this.attrID.equals(a.attrID)) {
-                // Not equal if different ID
-                return false;
-            } else if (this.ordered != a.ordered) {
-                // Not equal if different order definition
-                return false;
-            } else if (this.values.size() != a.values.size()) {
-                // Not equal if different numbers of values
-                return false;
-            } else if (this.ordered) {
-                // Otherwise, if both ordered, compare each value
-                Enumeration e1 = this.values.elements();
-                Enumeration e2 = a.values.elements();
-
-                while (e1.hasMoreElements()) {
-                    if (!compareValues(e1.nextElement(), e2.nextElement())) {
-                        // Not equal if one of the values are not equal
-                        return false;
-                    }
-                }
-                // Equal only if all the values are equal
-                return true;
-            } else {
-                /*
-                 * Otherwise (i.e., both unordered), see whether containing the
-                 * equal set of values.
-                 */
-                Enumeration e = this.values.elements();
-
-                while (e.hasMoreElements()) {
-                    if (!a.contains(e.nextElement())) {
-                        return false;
-                    }
-                }
-                return true;
-            }
-        }
-        // Not equal if not instance of BasicAttribute
-        return false;
-    }
-
-    /**
-     * Returns the hashcode for this <code>BasicAttribute</code> instance.
-     * The result is calculated by summing the hashcodes for the identifier
-     * and each of the values, except for array values, where the hashcodes
-     * for each array element are summed.
-     * 
-     * @return              the hashcode of this <code>BasicAttribute</code>
-     *                      instance
-     */
-    public int hashCode() {
-        Object o;
-        int i = attrID.hashCode();
-        Enumeration e = this.values.elements();
-
-        while (e.hasMoreElements()) {
-            o = e.nextElement();
-            if (null != o) {
-                i += hashCodeOfValue(o);
-            }
-        }
-
-        return i;
-    }
-
-    /**
-     * Returns the string representation of this <code>BasicAttribute</code>
-     * instance.
-     * The result contains the ID and the string representation of each value.
-     * 
-     * @return              the string representation of this object
-     */
-    public String toString() {
-        Enumeration e = this.values.elements();
-        String s = "Attribute ID: " + this.attrID; //$NON-NLS-1$
-        s += "\nAttribute values: "; //$NON-NLS-1$
-
-        if (!e.hasMoreElements()) {
-            s += "This Attribute does not have any values."; //$NON-NLS-1$
-        } else {
-            s += e.nextElement();
-            while (e.hasMoreElements()) {
-                s += "," + e.nextElement(); //$NON-NLS-1$
-            }
-        }
-        return s + "\n"; //$NON-NLS-1$
-    }
-
-}
-
-
+ */
+
+
+package javax.naming.directory;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Array;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+import java.util.Vector;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.OperationNotSupportedException;
+
+/**
+ * A simple attribute of a directory entry.
+ * <p>
+ * A basic attribute does not have any schema associated with it, and attempts
+ * to get the schema result in an <code>OperationNotSupportedException</code>
+ * being thrown.</p>
+ * <p>
+ * The definition of <code>equals</code> for an attribute is simply <code>
+ * Object.equals</code> on the value, except for values that are collections 
+ * where the definition of <code>equals</code> is an equivalence test (i.e. the 
+ * collection contains the same number of elements, and each has an equal 
+ * element in the other collection). For an array, <code>Object.equals</code>
+ * is used on each array element.</p>
+ * <p>
+ * Note that updates to a basic attribute do not update the directory itself --
+ * updates to a directory are only possible through the {@link DirContext}
+ * interface. <code>BasicAttribute</code> does not get its values dynamically 
+ * from the directory. It uses the values passed to the constructor or add and
+ * remove methods.</p>
+ * 
+ * @see Attribute
+ * 
+ */
+public class BasicAttribute implements Attribute {
+
+    /*
+     * -------------------------------------------------------------------
+     * Constants
+     * -------------------------------------------------------------------
+     */
+
+    /*
+     * This constant is used during deserialization to check the J2SE version
+     * which created the serialized object.
+     */
+    static final long serialVersionUID = 0x5d95d32a668565beL; //J2SE 1.4.2
+
+    /*
+     * -------------------------------------------------------------------
+     * Instance variables
+     * -------------------------------------------------------------------
+     */
+
+    /**
+     * The attribute identifier. 
+     * It is initialized by the public constructors and is required to be not
+     * null.
+     * 
+     * @serial
+     */
+    protected String attrID;
+
+    /**
+     * Flag showing whether the values of the attribute are ordered.
+     * 
+     * @serial 
+     */
+    protected boolean ordered;
+
+    /**
+     * <code>Vector</code> containing the attribute's values. 
+     * This is initialized by the public constructor and is required to be not 
+     * null.
+     */
+    protected transient Vector<Object> values = new Vector<Object>();
+
+    /*
+     * -------------------------------------------------------------------
+     * Constructors
+     * -------------------------------------------------------------------
+     */
+
+    /**
+     * Constructs an unordered <code>BasicAttribute</code> instance with the 
+     * supplied identifier and no values.
+     * 
+     * @param id            the attribute ID
+     */
+    public BasicAttribute(String id) {
+        this(id, false);
+    }
+
+    /**
+     * Constructs a <code>BasicAttribute</code> instance with the supplied 
+     * identifier and no values. 
+     * The supplied flag controls whether the values will be ordered or not.
+     * 
+     * @param id            the attribute ID
+     * @param flag          Indicates whether the values are ordered or not.
+     */
+    public BasicAttribute(String id, boolean flag) {
+        attrID = id;
+        ordered = flag;
+    }
+
+    /**
+     * Constructs an unordered <code>BasicAttribute</code> instance with the 
+     * supplied identifier and one value.
+     *  
+     * @param id            the attribute ID
+     * @param val           the first attribute value
+     */
+    public BasicAttribute(String id, Object val) {
+        this(id, val, false);
+    }
+
+    /**
+     * Constructs a <code>BasicAttribute</code> instance with the supplied 
+     * identifier and one value. 
+     * The supplied flag controls whether the values will be ordered or not.
+     * 
+     * @param id            the attribute ID
+     * @param val           the first attribute value
+     * @param flag          Indicates whether the values are ordered or not.
+     */
+    public BasicAttribute(String id, Object val, boolean flag) {
+        this(id, flag);
+        values.add(val);
+    }
+
+    /*
+     * -------------------------------------------------------------------
+     * Methods
+     * -------------------------------------------------------------------
+     */
+
+    /*
+     * Determine whether two values belonging to the two array classes
+     * respectively are possible to be equal.
+     */
+    private boolean compareValueClasses(Class c1, Class c2) {
+        if ((c1.getName().startsWith("[L") || c1.getName().startsWith("[[")) && //$NON-NLS-1$ //$NON-NLS-2$
+            (c2.getName().startsWith("[L") || c2.getName().startsWith("[["))) { //$NON-NLS-1$ //$NON-NLS-2$
+            /*
+             * If both Class are array of Object or array of array, the compare 
+             * result is true, even if their class name may not be the same.
+             */
+            return true;
+        } else if (c1.getName().equals(c2.getName())){
+            /*
+             * Otherwise, at least one of them must be array of basic types. If
+             * both Class have the same Class name, the compare result is true.
+             */
+            return true;
+        } else {
+            /*
+             * Otherwise, the compare result is false
+             */
+            return false;
+        }
+    }
+
+    /*
+     * Determine whether the two valuess are equal with each other, considering
+     * the possibility that they might be both arrays so that each element of 
+     * them has to be compared. 
+     */
+    private boolean compareValues(Object obj1, Object obj2) {
+        if (null == obj1 && null == obj2) {
+            // If both are null, they are considered equal.
+            return true;
+        } else if (null != obj1 && null != obj2) {
+            if (obj1.getClass().isArray() && obj2.getClass().isArray()) {
+                /*
+                 * If both are array, compare each element if it is possible
+                 * that they might be equal.
+                 */ 
+                if (compareValueClasses(obj1.getClass(), obj2.getClass())) {
+                    int i = Array.getLength(obj1);
+                    Object val1;
+                    Object val2;
+                                        
+                    // Compare each element of the two arrays
+                    if (Array.getLength(obj2) == i) {
+                        // Do the compare only if their lengths are equal
+                        for (i--; i >= 0; i--) {
+                            val1 = Array.get(obj1, i);
+                            val2 = Array.get(obj2, i);
+                            if (null == val1
+                                ? null != val2
+                                : !val1.equals(val2)) {
+                                /*
+                                 * If any of their elements at the same position
+                                 * are not equal,they are not equal.
+                                 */
+                                return false;
+                            }
+                        }
+                        // If all elements are equal, they are equal
+                        return true;
+                    }
+					// Not equal if different length
+					return false;
+                }
+				// Not equal if this can be inferred from their class names
+				return false;
+            }
+			// If not both of them are array, do a normal "equals"
+			return obj1.equals(obj2);
+        } else {
+            // Not equal if only one of them is null
+            return false;
+        }
+    }
+
+    /*
+     * Get the hash code of an attribute value, which might be an array whose 
+     * hash code is the sum of all its element. Base types are converted into
+     * corresponding wrapper class objects.     
+     */
+    private int hashCodeOfValue(Object obj) {
+        int hashcode = 0;
+
+        if (null != obj) {
+            // If the object is an array, sum up the hashcode of all elements.
+            if (obj.getClass().isArray()) {
+                Object element = null;
+                // Sum up the hashcode of all elements
+                for (int i = Array.getLength(obj) - 1; i >= 0; i--) {
+                    element = Array.get(obj, i);
+                    if (null != element) {
+                        hashcode += element.hashCode();
+                    }
+                }
+            } else {
+                // Otherwise, simply get the hashcode of the given object.
+                hashcode = obj.hashCode();
+            }
+        }
+
+        return hashcode;
+    }
+
+    /*
+     * -------------------------------------------------------------------
+     * Methods of Interface Attribute
+     * -------------------------------------------------------------------
+     */
+
+    public void add(int index, Object val) {
+        if (ordered) {
+            values.add(index, val);
+        } else {
+            if (contains(val)) {
+                throw new IllegalStateException("Value already exists."); //$NON-NLS-1$
+            }
+			values.add(index, val);
+        }
+    }
+
+    public boolean add(Object val) {
+        if (ordered) {
+            return values.add(val); // always true
+        }
+		if (contains(val)) {
+		    return false;
+		}
+		return values.add(val); // always true
+    }
+
+    public void clear() {
+        values.clear();
+    }
+
+    public Object clone() {
+        try {
+            BasicAttribute attr = (BasicAttribute) super.clone();
+            attr.values = (Vector<Object>) this.values.clone();
+            return attr;
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError("Failed to clone object of BasicAttribute class."); //$NON-NLS-1$
+        }
+    }
+
+    public boolean contains(Object val) {
+        Enumeration<Object> e = this.values.elements();
+
+        while (e.hasMoreElements()) {
+            if (compareValues(e.nextElement(), val)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public Object get() throws NamingException {
+        if (0 == values.size()) {
+            throw new NoSuchElementException("No values available."); //$NON-NLS-1$
+        }
+		return values.get(0);
+    }
+
+    public Object get(int index) throws NamingException {
+        return values.get(index);
+    }
+
+    public NamingEnumeration<?> getAll() throws NamingException {
+        return new BasicNamingEnumeration(values.elements());
+    }
+
+    public DirContext getAttributeDefinition() throws NamingException {
+        throw new OperationNotSupportedException("BasicAttribute does not support this operation."); //$NON-NLS-1$
+    }
+
+    public DirContext getAttributeSyntaxDefinition() throws NamingException {
+        throw new OperationNotSupportedException("BasicAttribute does not support this operation."); //$NON-NLS-1$
+    }
+
+    public String getID() {
+        return attrID;
+    }
+
+    public boolean isOrdered() {
+        return ordered;
+    }
+
+    public Object remove(int index) {
+        return values.remove(index);
+    }
+
+    public boolean remove(Object val) {
+        int total = this.values.size();
+
+        for (int i = 0; i < total; i++) {
+            if (compareValues(this.values.get(i), val)) {
+                this.values.remove(i);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public Object set(int index, Object val) {
+        if (!ordered && contains(val)) {
+            throw new IllegalStateException("Value already exists."); //$NON-NLS-1$
+        }
+        return values.set(index, val);
+    }
+
+    public int size() {
+        return values.size();
+    }
+
+    /*
+     * -------------------------------------------------------------------
+     * Methods override parent class Object
+     * -------------------------------------------------------------------
+     */
+
+    /*
+     * Serialization of the <code>BasicAttribute</code> class is as follows:
+     *      attribute identifier (String)
+     *      ordered flag (boolean)
+     *      number of values (int)
+     *      list of value objects
+     */
+    private void readObject(ObjectInputStream ois)
+        throws IOException, ClassNotFoundException {
+        int size;
+
+        ois.defaultReadObject();
+        size = ois.readInt();
+        this.values = new Vector<Object>();
+        for (int i = 0; i < size; i++) {
+            this.values.add(ois.readObject());
+        }
+    }
+
+    /*
+     * Serialization of the <code>BasicAttribute</code> class is as follows:
+     *      attribute identifier (String)
+     *      ordered flag (boolean)
+     *      number of values (int)
+     *      list of value objects
+     */
+    private void writeObject(ObjectOutputStream oos) throws IOException {
+        oos.defaultWriteObject();
+        oos.writeInt(this.values.size());
+        for (Enumeration<Object> e = this.values.elements(); e.hasMoreElements();) {
+            oos.writeObject(e.nextElement());
+        }
+    }
+
+    /**
+     * Returns true if this <code>BasicAttribute</code> instance is equal to the
+     * supplied object <code>obj</code>.
+     * Two attributes are considered equal if they have equal identifiers, 
+     * schemas and values. BasicAttribute uses no schema.
+     * <p>
+     * <code>Object.equals</code> is used to test equality of identifiers and 
+     * values. For array values <code>Object.equals</code> is called on every 
+     * array element.</p>
+     *
+     * @param obj           the object to be compared with
+     * @return              true if this object is equal to <code>obj</code>,
+     *                      otherwise false
+     */
+    public boolean equals(Object obj) {
+        if (obj instanceof BasicAttribute) {
+            BasicAttribute a = (BasicAttribute) obj;
+
+            if (!this.attrID.equals(a.attrID)) {
+                // Not equal if different ID
+                return false;
+            } else if (this.ordered != a.ordered) {
+                // Not equal if different order definition
+                return false;
+            } else if (this.values.size() != a.values.size()) {
+                // Not equal if different numbers of values
+                return false;
+            } else if (this.ordered) {
+                // Otherwise, if both ordered, compare each value
+                Enumeration e1 = this.values.elements();
+                Enumeration e2 = a.values.elements();
+
+                while (e1.hasMoreElements()) {
+                    if (!compareValues(e1.nextElement(), e2.nextElement())) {
+                        // Not equal if one of the values are not equal
+                        return false;
+                    }
+                }
+                // Equal only if all the values are equal
+                return true;
+            } else {
+                /*
+                 * Otherwise (i.e., both unordered), see whether containing the
+                 * equal set of values.
+                 */
+                Enumeration<Object> e = this.values.elements();
+
+                while (e.hasMoreElements()) {
+                    if (!a.contains(e.nextElement())) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+        }
+        // Not equal if not instance of BasicAttribute
+        return false;
+    }
+
+    /**
+     * Returns the hashcode for this <code>BasicAttribute</code> instance.
+     * The result is calculated by summing the hashcodes for the identifier
+     * and each of the values, except for array values, where the hashcodes
+     * for each array element are summed.
+     * 
+     * @return              the hashcode of this <code>BasicAttribute</code>
+     *                      instance
+     */
+    public int hashCode() {
+        Object o;
+        int i = attrID.hashCode();
+        Enumeration<Object> e = this.values.elements();
+
+        while (e.hasMoreElements()) {
+            o = e.nextElement();
+            if (null != o) {
+                i += hashCodeOfValue(o);
+            }
+        }
+
+        return i;
+    }
+
+    /**
+     * Returns the string representation of this <code>BasicAttribute</code>
+     * instance.
+     * The result contains the ID and the string representation of each value.
+     * 
+     * @return              the string representation of this object
+     */
+    public String toString() {
+        Enumeration<Object> e = this.values.elements();
+        String s = "Attribute ID: " + this.attrID; //$NON-NLS-1$
+        s += "\nAttribute values: "; //$NON-NLS-1$
+
+        if (!e.hasMoreElements()) {
+            s += "This Attribute does not have any values."; //$NON-NLS-1$
+        } else {
+            s += e.nextElement();
+            while (e.hasMoreElements()) {
+                s += "," + e.nextElement(); //$NON-NLS-1$
+            }
+        }
+        return s + "\n"; //$NON-NLS-1$
+    }
+
+}
+
+