/*
 * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package javax.naming.directory;

import java.util.Vector;
import java.util.Enumeration;
import java.util.NoSuchElementException;
import java.lang.reflect.Array;

import javax.naming.NamingException;
import javax.naming.NamingEnumeration;
import javax.naming.OperationNotSupportedException;

/**
  * This class provides a basic implementation of the <tt>Attribute</tt> interface.
  *<p>
  * This implementation does not support the schema methods
  * <tt>getAttributeDefinition()</tt> and <tt>getAttributeSyntaxDefinition()</tt>.
  * They simply throw <tt>OperationNotSupportedException</tt>.
  * Subclasses of <tt>BasicAttribute</tt> should override these methods if they
  * support them.
  *<p>
  * The <tt>BasicAttribute</tt> class by default uses <tt>Object.equals()</tt> to
  * determine equality of attribute values when testing for equality or
  * when searching for values, <em>except</em> when the value is an array.
  * For an array, each element of the array is checked using <tt>Object.equals()</tt>.
  * Subclasses of <tt>BasicAttribute</tt> can make use of schema information
  * when doing similar equality checks by overriding methods
  * in which such use of schema is meaningful.
  * Similarly, the <tt>BasicAttribute</tt> class by default returns the values passed to its
  * constructor and/or manipulated using the add/remove methods.
  * Subclasses of <tt>BasicAttribute</tt> can override <tt>get()</tt> and <tt>getAll()</tt>
  * to get the values dynamically from the directory (or implement
  * the <tt>Attribute</tt> interface directly instead of subclassing <tt>BasicAttribute</tt>).
  *<p>
  * Note that updates to <tt>BasicAttribute</tt> (such as adding or removing a value)
  * does not affect the corresponding representation of the attribute
  * in the directory.  Updates to the directory can only be effected
  * using operations in the <tt>DirContext</tt> interface.
  *<p>
  * A <tt>BasicAttribute</tt> instance is not synchronized against concurrent
  * multithreaded access. Multiple threads trying to access and modify a
  * <tt>BasicAttribute</tt> should lock the object.
  *
  * @author Rosanna Lee
  * @author Scott Seligman
  * @since 1.3
  */
public class BasicAttribute implements Attribute {
    /**
     * Holds the attribute's id. It is initialized by the public constructor and
     * cannot be null unless methods in BasicAttribute that use attrID
     * have been overridden.
     * @serial
     */
    protected String attrID;

    /**
     * Holds the attribute's values. Initialized by public constructors.
     * Cannot be null unless methods in BasicAttribute that use
     * values have been overridden.
     */
    protected transient Vector<Object> values;

    /**
     * A flag for recording whether this attribute's values are ordered.
     * @serial
     */
    protected boolean ordered = false;

    public Object clone() {
        BasicAttribute attr;
        try {
            attr = (BasicAttribute)super.clone();
        } catch (CloneNotSupportedException e) {
            attr = new BasicAttribute(attrID, ordered);
        }
        attr.values = (Vector)values.clone();
        return attr;
    }

    /**
      * Determines whether obj is equal to this attribute.
      * Two attributes are equal if their attribute-ids, syntaxes
      * and values are equal.
      * If the attribute values are unordered, the order that the values were added
      * are irrelevant. If the attribute values are ordered, then the
      * order the values must match.
      * If obj is null or not an Attribute, false is returned.
      *<p>
      * By default <tt>Object.equals()</tt> is used when comparing the attribute
      * id and its values except when a value is an array. For an array,
      * each element of the array is checked using <tt>Object.equals()</tt>.
      * A subclass may override this to make
      * use of schema syntax information and matching rules,
      * which define what it means for two attributes to be equal.
      * How and whether a subclass makes
      * use of the schema information is determined by the subclass.
      * If a subclass overrides <tt>equals()</tt>, it should also override
      * <tt>hashCode()</tt>
      * such that two attributes that are equal have the same hash code.
      *
      * @param obj      The possibly null object to check.
      * @return true if obj is equal to this attribute; false otherwise.
      * @see #hashCode
      * @see #contains
      */
    public boolean equals(Object obj) {
        if ((obj != null) && (obj instanceof Attribute)) {
            Attribute target = (Attribute)obj;

            // Check order first
            if (isOrdered() != target.isOrdered()) {
                return false;
            }
            int len;
            if (attrID.equals(target.getID()) &&
                (len=size()) == target.size()) {
                try {
                    if (isOrdered()) {
                        // Go through both list of values
                        for (int i = 0; i < len; i++) {
                            if (!valueEquals(get(i), target.get(i))) {
                                return false;
                            }
                        }
                    } else {
                        // order is not relevant; check for existence
                        Enumeration theirs = target.getAll();
                        while (theirs.hasMoreElements()) {
                            if (find(theirs.nextElement()) < 0)
                                return false;
                        }
                    }
                } catch (NamingException e) {
                    return false;
                }
                return true;
            }
        }
        return false;
    }

    /**
      * Calculates the hash code of this attribute.
      *<p>
      * The hash code is computed by adding the hash code of
      * the attribute's id and that of all of its values except for
      * values that are arrays.
      * For an array, the hash code of each element of the array is summed.
      * If a subclass overrides <tt>hashCode()</tt>, it should override
      * <tt>equals()</tt>
      * as well so that two attributes that are equal have the same hash code.
      *
      * @return an int representing the hash code of this attribute.
      * @see #equals
      */
    public int hashCode() {
        int hash = attrID.hashCode();
        int num = values.size();
        Object val;
        for (int i = 0; i < num; i ++) {
            val = values.elementAt(i);
            if (val != null) {
                if (val.getClass().isArray()) {
                    Object it;
                    int len = Array.getLength(val);
                    for (int j = 0 ; j < len ; j++) {
                        it = Array.get(val, j);
                        if (it != null) {
                            hash += it.hashCode();
                        }
                    }
                } else {
                    hash += val.hashCode();
                }
            }
        }
        return hash;
    }

    /**
      * Generates the string representation of this attribute.
      * The string consists of the attribute's id and its values.
      * This string is meant for debugging and not meant to be
      * interpreted programmatically.
      * @return The non-null string representation of this attribute.
      */
    public String toString() {
        StringBuffer answer = new StringBuffer(attrID + ": ");
        if (values.size() == 0) {
            answer.append("No values");
        } else {
            boolean start = true;
            for (Enumeration e = values.elements(); e.hasMoreElements(); ) {
                if (!start)
                    answer.append(", ");
                answer.append(e.nextElement());
                start = false;
            }
        }
        return answer.toString();
    }

    /**
      * Constructs a new instance of an unordered attribute with no value.
      *
      * @param id The attribute's id. It cannot be null.
      */
    public BasicAttribute(String id) {
        this(id, false);
    }

    /**
      * Constructs a new instance of an unordered attribute with a single value.
      *
      * @param id The attribute's id. It cannot be null.
      * @param value The attribute's value. If null, a null
      *        value is added to the attribute.
      */
    public BasicAttribute(String id, Object value) {
        this(id, value, false);
    }

    /**
      * Constructs a new instance of a possibly ordered attribute with no value.
      *
      * @param id The attribute's id. It cannot be null.
      * @param ordered true means the attribute's values will be ordered;
      * false otherwise.
      */
    public BasicAttribute(String id, boolean ordered) {
        attrID = id;
        values = new Vector();
        this.ordered = ordered;
    }

    /**
      * Constructs a new instance of a possibly ordered attribute with a
      * single value.
      *
      * @param id The attribute's id. It cannot be null.
      * @param value The attribute's value. If null, a null
      *        value is added to the attribute.
      * @param ordered true means the attribute's values will be ordered;
      * false otherwise.
      */
    public BasicAttribute(String id, Object value, boolean ordered) {
        this(id, ordered);
        values.addElement(value);
    }

    /**
      * Retrieves an enumeration of this attribute's values.
      *<p>
      * By default, the values returned are those passed to the
      * constructor and/or manipulated using the add/replace/remove methods.
      * A subclass may override this to retrieve the values dynamically
      * from the directory.
      */
    public NamingEnumeration<?> getAll() throws NamingException {
      return new ValuesEnumImpl();
    }

    /**
      * Retrieves one of this attribute's values.
      *<p>
      * By default, the value returned is one of those passed to the
      * constructor and/or manipulated using the add/replace/remove methods.
      * A subclass may override this to retrieve the value dynamically
      * from the directory.
      */
    public Object get() throws NamingException {
        if (values.size() == 0) {
            throw new
        NoSuchElementException("Attribute " + getID() + " has no value");
        } else {
            return values.elementAt(0);
        }
    }

    public int size() {
      return values.size();
    }

    public String getID() {
        return attrID;
    }

    /**
      * Determines whether a value is in this attribute.
      *<p>
      * By default,
      * <tt>Object.equals()</tt> is used when comparing <tt>attrVal</tt>
      * with this attribute's values except when <tt>attrVal</tt> is an array.
      * For an array, each element of the array is checked using
      * <tt>Object.equals()</tt>.
      * A subclass may use schema information to determine equality.
      */
    public boolean contains(Object attrVal) {
        return (find(attrVal) >= 0);
    }

    // For finding first element that has a null in JDK1.1 Vector.
    // In the Java 2 platform, can just replace this with Vector.indexOf(target);
    private int find(Object target) {
        Class cl;
        if (target == null) {
            int ct = values.size();
            for (int i = 0 ; i < ct ; i++) {
                if (values.elementAt(i) == null)
                    return i;
            }
        } else if ((cl=target.getClass()).isArray()) {
            int ct = values.size();
            Object it;
            for (int i = 0 ; i < ct ; i++) {
                it = values.elementAt(i);
                if (it != null && cl == it.getClass()
                    && arrayEquals(target, it))
                    return i;
            }
        } else {
            return values.indexOf(target, 0);
        }
        return -1;  // not found
    }

    /**
     * Determines whether two attribute values are equal.
     * Use arrayEquals for arrays and <tt>Object.equals()</tt> otherwise.
     */
    private static boolean valueEquals(Object obj1, Object obj2) {
        if (obj1 == obj2) {
            return true; // object references are equal
        }
        if (obj1 == null) {
            return false; // obj2 was not false
        }
        if (obj1.getClass().isArray() &&
            obj2.getClass().isArray()) {
            return arrayEquals(obj1, obj2);
        }
        return (obj1.equals(obj2));
    }

    /**
     * Determines whether two arrays are equal by comparing each of their
     * elements using <tt>Object.equals()</tt>.
     */
    private static boolean arrayEquals(Object a1, Object a2) {
        int len;
        if ((len = Array.getLength(a1)) != Array.getLength(a2))
            return false;

        for (int j = 0; j < len; j++) {
            Object i1 = Array.get(a1, j);
            Object i2 = Array.get(a2, j);
            if (i1 == null || i2 == null) {
                if (i1 != i2)
                    return false;
            } else if (!i1.equals(i2)) {
                return false;
            }
        }
        return true;
    }

    /**
      * Adds a new value to this attribute.
      *<p>
      * By default, <tt>Object.equals()</tt> is used when comparing <tt>attrVal</tt>
      * with this attribute's values except when <tt>attrVal</tt> is an array.
      * For an array, each element of the array is checked using
      * <tt>Object.equals()</tt>.
      * A subclass may use schema information to determine equality.
      */
    public boolean add(Object attrVal) {
        if (isOrdered() || (find(attrVal) < 0)) {
            values.addElement(attrVal);
            return true;
        } else {
            return false;
        }
    }

    /**
      * Removes a specified value from this attribute.
      *<p>
      * By default, <tt>Object.equals()</tt> is used when comparing <tt>attrVal</tt>
      * with this attribute's values except when <tt>attrVal</tt> is an array.
      * For an array, each element of the array is checked using
      * <tt>Object.equals()</tt>.
      * A subclass may use schema information to determine equality.
      */
    public boolean remove(Object attrval) {
        // For the Java 2 platform, can just use "return removeElement(attrval);"
        // Need to do the following to handle null case

        int i = find(attrval);
        if (i >= 0) {
            values.removeElementAt(i);
            return true;
        }
        return false;
    }

    public void clear() {
        values.setSize(0);
    }

//  ---- ordering methods

    public boolean isOrdered() {
        return ordered;
    }

    public Object get(int ix) throws NamingException {
        return values.elementAt(ix);
    }

    public Object remove(int ix) {
        Object answer = values.elementAt(ix);
        values.removeElementAt(ix);
        return answer;
    }

    public void add(int ix, Object attrVal) {
        if (!isOrdered() && contains(attrVal)) {
            throw new IllegalStateException(
                "Cannot add duplicate to unordered attribute");
        }
        values.insertElementAt(attrVal, ix);
    }

    public Object set(int ix, Object attrVal) {
        if (!isOrdered() && contains(attrVal)) {
            throw new IllegalStateException(
                "Cannot add duplicate to unordered attribute");
        }

        Object answer = values.elementAt(ix);
        values.setElementAt(attrVal, ix);
        return answer;
    }

// ----------------- Schema methods

    /**
      * Retrieves the syntax definition associated with this attribute.
      *<p>
      * This method by default throws OperationNotSupportedException. A subclass
      * should override this method if it supports schema.
      */
    public DirContext getAttributeSyntaxDefinition() throws NamingException {
            throw new OperationNotSupportedException("attribute syntax");
    }

    /**
      * Retrieves this attribute's schema definition.
      *<p>
      * This method by default throws OperationNotSupportedException. A subclass
      * should override this method if it supports schema.
      */
    public DirContext getAttributeDefinition() throws NamingException {
        throw new OperationNotSupportedException("attribute definition");
    }


//  ---- serialization methods

    /**
     * Overridden to avoid exposing implementation details
     * @serialData Default field (the attribute ID -- a String),
     * followed by the number of values (an int), and the
     * individual values.
     */
    private void writeObject(java.io.ObjectOutputStream s)
            throws java.io.IOException {
        s.defaultWriteObject(); // write out the attrID
        s.writeInt(values.size());
        for (int i = 0; i < values.size(); i++) {
            s.writeObject(values.elementAt(i));
        }
    }

    /**
     * Overridden to avoid exposing implementation details.
     */
    private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
        s.defaultReadObject();  // read in the attrID
        int n = s.readInt();    // number of values
        values = new Vector(n);
        while (--n >= 0) {
            values.addElement(s.readObject());
        }
    }


    class ValuesEnumImpl implements NamingEnumeration<Object> {
    Enumeration list;

    ValuesEnumImpl() {
        list = values.elements();
    }

    public boolean hasMoreElements() {
        return list.hasMoreElements();
    }

    public Object nextElement() {
        return(list.nextElement());
    }

    public Object next() throws NamingException {
        return list.nextElement();
    }

    public boolean hasMore() throws NamingException {
        return list.hasMoreElements();
    }

    public void close() throws NamingException {
        list = null;
    }
    }

    /**
     * Use serialVersionUID from JNDI 1.1.1 for interoperability.
     */
    private static final long serialVersionUID = 6743528196119291326L;
}
