/*
 * Copyright (c) 1999, 2008, 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.management;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>Represents a list of values for attributes of an MBean.  See the
 * {@link MBeanServerConnection#getAttributes getAttributes} and
 * {@link MBeanServerConnection#setAttributes setAttributes} methods of
 * {@link MBeanServer} and {@link MBeanServerConnection}.</p>
 *
 * <p id="type-safe">For compatibility reasons, it is possible, though
 * highly discouraged, to add objects to an {@code AttributeList} that are
 * not instances of {@code Attribute}.  However, an {@code AttributeList}
 * can be made <em>type-safe</em>, which means that an attempt to add
 * an object that is not an {@code Attribute} will produce an {@code
 * IllegalArgumentException}.  An {@code AttributeList} becomes type-safe
 * when the method {@link #asList()} is called on it.</p>
 *
 * @since 1.5
 */
/* We cannot extend ArrayList<Attribute> because our legacy
   add(Attribute) method would then override add(E) in ArrayList<E>,
   and our return value is void whereas ArrayList.add(E)'s is boolean.
   Likewise for set(int,Attribute).  Grrr.  We cannot use covariance
   to override the most important methods and have them return
   Attribute, either, because that would break subclasses that
   override those methods in turn (using the original return type
   of Object).  Finally, we cannot implement Iterable<Attribute>
   so you could write
       for (Attribute a : attributeList)
   because ArrayList<> implements Iterable<> and the same class cannot
   implement two versions of a generic interface.  Instead we provide
   the asList() method so you can write
       for (Attribute a : attributeList.asList())
*/
public class AttributeList extends ArrayList<Object> {

    private transient volatile boolean typeSafe;
    private transient volatile boolean tainted;

    /* Serial version */
    private static final long serialVersionUID = -4077085769279709076L;

    /**
     * Constructs an empty <CODE>AttributeList</CODE>.
     */
    public AttributeList() {
        super();
    }

    /**
     * Constructs an empty <CODE>AttributeList</CODE> with
     * the initial capacity specified.
     *
     * @param initialCapacity the initial capacity of the
     * <code>AttributeList</code>, as specified by {@link
     * ArrayList#ArrayList(int)}.
     */
    public AttributeList(int initialCapacity) {
        super(initialCapacity);
    }

    /**
     * Constructs an <CODE>AttributeList</CODE> containing the
     * elements of the <CODE>AttributeList</CODE> specified, in the
     * order in which they are returned by the
     * <CODE>AttributeList</CODE>'s iterator.  The
     * <CODE>AttributeList</CODE> instance has an initial capacity of
     * 110% of the size of the <CODE>AttributeList</CODE> specified.
     *
     * @param list the <code>AttributeList</code> that defines the initial
     * contents of the new <code>AttributeList</code>.
     *
     * @see ArrayList#ArrayList(java.util.Collection)
     */
    public AttributeList(AttributeList list) {
        super(list);
    }

    /**
     * Constructs an {@code AttributeList} containing the elements of the
     * {@code List} specified, in the order in which they are returned by
     * the {@code List}'s iterator.
     *
     * @param list the {@code List} that defines the initial contents of
     * the new {@code AttributeList}.
     *
     * @exception IllegalArgumentException if the {@code list} parameter
     * is {@code null} or if the {@code list} parameter contains any
     * non-Attribute objects.
     *
     * @see ArrayList#ArrayList(java.util.Collection)
     *
     * @since 1.6
     */
    public AttributeList(List<Attribute> list) {
        // Check for null parameter
        //
        if (list == null)
            throw new IllegalArgumentException("Null parameter");

        // Check for non-Attribute objects
        //
        adding(list);

        // Build the List<Attribute>
        //
        super.addAll(list);
    }

    /**
     * Return a view of this list as a {@code List<Attribute>}.
     * Changes to the returned value are reflected by changes
     * to the original {@code AttributeList} and vice versa.
     *
     * @return a {@code List<Attribute>} whose contents
     * reflect the contents of this {@code AttributeList}.
     *
     * <p>If this method has ever been called on a given
     * {@code AttributeList} instance, a subsequent attempt to add
     * an object to that instance which is not an {@code Attribute}
     * will fail with a {@code IllegalArgumentException}. For compatibility
     * reasons, an {@code AttributeList} on which this method has never
     * been called does allow objects other than {@code Attribute}s to
     * be added.</p>
     *
     * @throws IllegalArgumentException if this {@code AttributeList} contains
     * an element that is not an {@code Attribute}.
     *
     * @since 1.6
     */
    @SuppressWarnings("unchecked")
    public List<Attribute> asList() {
        typeSafe = true;
        if (tainted)
            adding((Collection<?>) this);  // will throw IllegalArgumentException
        return (List<Attribute>) (List<?>) this;
    }

    /**
     * Adds the {@code Attribute} specified as the last element of the list.
     *
     * @param object  The attribute to be added.
     */
    public void add(Attribute object)  {
        super.add(object);
    }

    /**
     * Inserts the attribute specified as an element at the position specified.
     * Elements with an index greater than or equal to the current position are
     * shifted up. If the index is out of range (index < 0 || index >
     * size()) a RuntimeOperationsException should be raised, wrapping the
     * java.lang.IndexOutOfBoundsException thrown.
     *
     * @param object  The <CODE>Attribute</CODE> object to be inserted.
     * @param index The position in the list where the new {@code Attribute}
     * object is to be inserted.
     */
    public void add(int index, Attribute object)  {
        try {
            super.add(index, object);
        }
        catch (IndexOutOfBoundsException e) {
            throw new RuntimeOperationsException(e,
                "The specified index is out of range");
        }
    }

    /**
     * Sets the element at the position specified to be the attribute specified.
     * The previous element at that position is discarded. If the index is
     * out of range (index < 0 || index > size() a RuntimeOperationsException
     * should be raised, wrapping the java.lang.IndexOutOfBoundsException thrown.
     *
     * @param object  The value to which the attribute element should be set.
     * @param index  The position specified.
     */
    public void set(int index, Attribute object)  {
        try {
            super.set(index, object);
        }
        catch (IndexOutOfBoundsException e) {
            throw new RuntimeOperationsException(e,
                "The specified index is out of range");
        }
    }

    /**
     * Appends all the elements in the <CODE>AttributeList</CODE> specified to
     * the end of the list, in the order in which they are returned by the
     * Iterator of the <CODE>AttributeList</CODE> specified.
     *
     * @param list  Elements to be inserted into the list.
     *
     * @return true if this list changed as a result of the call.
     *
     * @see ArrayList#addAll(java.util.Collection)
     */
    public boolean addAll(AttributeList list)  {
        return (super.addAll(list));
    }

    /**
     * Inserts all of the elements in the <CODE>AttributeList</CODE> specified
     * into this list, starting at the specified position, in the order in which
     * they are returned by the Iterator of the {@code AttributeList} specified.
     * If the index is out of range (index < 0 || index > size() a
     * RuntimeOperationsException should be raised, wrapping the
     * java.lang.IndexOutOfBoundsException thrown.
     *
     * @param list  Elements to be inserted into the list.
     * @param index  Position at which to insert the first element from the
     * <CODE>AttributeList</CODE> specified.
     *
     * @return true if this list changed as a result of the call.
     *
     * @see ArrayList#addAll(int, java.util.Collection)
     */
    public boolean addAll(int index, AttributeList list)  {
        try {
            return super.addAll(index, list);
        } catch (IndexOutOfBoundsException e) {
            throw new RuntimeOperationsException(e,
                "The specified index is out of range");
        }
    }

    /*
     * Override all of the methods from ArrayList<Object> that might add
     * a non-Attribute to the List, and disallow that if asList has ever
     * been called on this instance.
     */

    /**
     * {@inheritDoc}
     * @throws IllegalArgumentException if this {@code AttributeList} is
     * <a href="#type-safe">type-safe</a> and {@code element} is not an
     * {@code Attribute}.
     */
    @Override
    public boolean add(Object element) {
        adding(element);
        return super.add(element);
    }

    /**
     * {@inheritDoc}
     * @throws IllegalArgumentException if this {@code AttributeList} is
     * <a href="#type-safe">type-safe</a> and {@code element} is not an
     * {@code Attribute}.
     */
    @Override
    public void add(int index, Object element) {
        adding(element);
        super.add(index, element);
    }

    /**
     * {@inheritDoc}
     * @throws IllegalArgumentException if this {@code AttributeList} is
     * <a href="#type-safe">type-safe</a> and {@code c} contains an
     * element that is not an {@code Attribute}.
     */
    @Override
    public boolean addAll(Collection<?> c) {
        adding(c);
        return super.addAll(c);
    }

    /**
     * {@inheritDoc}
     * @throws IllegalArgumentException if this {@code AttributeList} is
     * <a href="#type-safe">type-safe</a> and {@code c} contains an
     * element that is not an {@code Attribute}.
     */
    @Override
    public boolean addAll(int index, Collection<?> c) {
        adding(c);
        return super.addAll(index, c);
    }

    /**
     * {@inheritDoc}
     * @throws IllegalArgumentException if this {@code AttributeList} is
     * <a href="#type-safe">type-safe</a> and {@code element} is not an
     * {@code Attribute}.
     */
    @Override
    public Object set(int index, Object element) {
        adding(element);
        return super.set(index, element);
    }

    private void adding(Object x) {
        if (x == null || x instanceof Attribute)
            return;
        if (typeSafe)
            throw new IllegalArgumentException("Not an Attribute: " + x);
        else
            tainted = true;
    }

    private void adding(Collection<?> c) {
        for (Object x : c)
            adding(x);
    }
}
