/*
 * Copyright (c) 1999, 2006, 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.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.StreamCorruptedException;

/**
 * <p>Provides general information for an MBean descriptor object.
 * The feature described can be an attribute, an operation, a
 * parameter, or a notification.  Instances of this class are
 * immutable.  Subclasses may be mutable but this is not
 * recommended.</p>
 *
 * @since 1.5
 */
public class MBeanFeatureInfo implements Serializable, DescriptorRead {


    /* Serial version */
    static final long serialVersionUID = 3952882688968447265L;

    /**
     * The name of the feature.  It is recommended that subclasses call
     * {@link #getName} rather than reading this field, and that they
     * not change it.
     *
     * @serial The name of the feature.
     */
    protected String name;

    /**
     * The human-readable description of the feature.  It is
     * recommended that subclasses call {@link #getDescription} rather
     * than reading this field, and that they not change it.
     *
     * @serial The human-readable description of the feature.
     */
    protected String description;

    /**
     * @serial The Descriptor for this MBeanFeatureInfo.  This field
     * can be null, which is equivalent to an empty Descriptor.
     */
    private transient Descriptor descriptor;


    /**
     * Constructs an <CODE>MBeanFeatureInfo</CODE> object.  This
     * constructor is equivalent to {@code MBeanFeatureInfo(name,
     * description, (Descriptor) null}.
     *
     * @param name The name of the feature.
     * @param description A human readable description of the feature.
     */
    public MBeanFeatureInfo(String name, String description) {
        this(name, description, null);
    }

    /**
     * Constructs an <CODE>MBeanFeatureInfo</CODE> object.
     *
     * @param name The name of the feature.
     * @param description A human readable description of the feature.
     * @param descriptor The descriptor for the feature.  This may be null
     * which is equivalent to an empty descriptor.
     *
     * @since 1.6
     */
    public MBeanFeatureInfo(String name, String description,
                            Descriptor descriptor) {
        this.name = name;
        this.description = description;
        this.descriptor = descriptor;
    }

    /**
     * Returns the name of the feature.
     *
     * @return the name of the feature.
     */
    public String getName() {
        return name;
    }

    /**
     * Returns the human-readable description of the feature.
     *
     * @return the human-readable description of the feature.
     */
    public String getDescription() {
        return description;
    }

    /**
     * Returns the descriptor for the feature.  Changing the returned value
     * will have no affect on the original descriptor.
     *
     * @return a descriptor that is either immutable or a copy of the original.
     *
     * @since 1.6
     */
    public Descriptor getDescriptor() {
        return (Descriptor) ImmutableDescriptor.nonNullDescriptor(descriptor).clone();
    }

    /**
     * Compare this MBeanFeatureInfo to another.
     *
     * @param o the object to compare to.
     *
     * @return true if and only if <code>o</code> is an MBeanFeatureInfo such
     * that its {@link #getName()}, {@link #getDescription()}, and
     * {@link #getDescriptor()}
     * values are equal (not necessarily identical) to those of this
     * MBeanFeatureInfo.
     */
    public boolean equals(Object o) {
        if (o == this)
            return true;
        if (!(o instanceof MBeanFeatureInfo))
            return false;
        MBeanFeatureInfo p = (MBeanFeatureInfo) o;
        return (p.getName().equals(getName()) &&
                p.getDescription().equals(getDescription()) &&
                p.getDescriptor().equals(getDescriptor()));
    }

    public int hashCode() {
        return getName().hashCode() ^ getDescription().hashCode() ^
               getDescriptor().hashCode();
    }

    /**
     * Serializes an {@link MBeanFeatureInfo} to an {@link ObjectOutputStream}.
     * @serialData
     * For compatibility reasons, an object of this class is serialized as follows.
     * <ul>
     * The method {@link ObjectOutputStream#defaultWriteObject defaultWriteObject()}
     * is called first to serialize the object except the field {@code descriptor}
     * which is declared as transient. The field {@code descriptor} is serialized
     * as follows:
     *     <ul>
     *     <li>If {@code descriptor} is an instance of the class
     *        {@link ImmutableDescriptor}, the method {@link ObjectOutputStream#write
     *        write(int val)} is called to write a byte with the value {@code 1},
     *        then the method {@link ObjectOutputStream#writeObject writeObject(Object obj)}
     *        is called twice to serialize the field names and the field values of the
     *        {@code descriptor}, respectively as a {@code String[]} and an
     *        {@code Object[]};</li>
     *     <li>Otherwise, the method {@link ObjectOutputStream#write write(int val)}
     * is called to write a byte with the value {@code 0}, then the method
     * {@link ObjectOutputStream#writeObject writeObject(Object obj)} is called
     * to serialize directly the field {@code descriptor}.
     *     </ul>
     * </ul>
     * @since 1.6
     */
    private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();

        if (descriptor != null &&
            descriptor.getClass() == ImmutableDescriptor.class) {

            out.write(1);

            final String[] names = descriptor.getFieldNames();

            out.writeObject(names);
            out.writeObject(descriptor.getFieldValues(names));
        } else {
            out.write(0);

            out.writeObject(descriptor);
        }
    }

    /**
     * Deserializes an {@link MBeanFeatureInfo} from an {@link ObjectInputStream}.
     * @serialData
     * For compatibility reasons, an object of this class is deserialized as follows.
     * <ul>
     * The method {@link ObjectInputStream#defaultReadObject defaultReadObject()}
     * is called first to deserialize the object except the field
     * {@code descriptor}, which is not serialized in the default way. Then the method
     * {@link ObjectInputStream#read read()} is called to read a byte, the field
     * {@code descriptor} is deserialized according to the value of the byte value:
     *    <ul>
     *    <li>1. The method {@link ObjectInputStream#readObject readObject()}
     *       is called twice to obtain the field names (a {@code String[]}) and
     *       the field values (a {@code Object[]}) of the {@code descriptor}.
     *       The two obtained values then are used to construct
     *       an {@link ImmutableDescriptor} instance for the field
     *       {@code descriptor};</li>
     *    <li>0. The value for the field {@code descriptor} is obtained directly
     *       by calling the method {@link ObjectInputStream#readObject readObject()}.
     *       If the obtained value is null, the field {@code descriptor} is set to
     *       {@link ImmutableDescriptor#EMPTY_DESCRIPTOR EMPTY_DESCRIPTOR};</li>
     *    <li>-1. This means that there is no byte to read and that the object is from
     *       an earlier version of the JMX API. The field {@code descriptor} is set
     *       to {@link ImmutableDescriptor#EMPTY_DESCRIPTOR EMPTY_DESCRIPTOR}</li>
     *    <li>Any other value. A {@link StreamCorruptedException} is thrown.</li>
     *    </ul>
     * </ul>
     * @since 1.6
     */
    private void readObject(ObjectInputStream in)
        throws IOException, ClassNotFoundException {

        in.defaultReadObject();

        switch (in.read()) {
        case 1:
            final String[] names = (String[])in.readObject();

            if (names.length == 0) {
                descriptor = ImmutableDescriptor.EMPTY_DESCRIPTOR;
            } else {
                final Object[] values = (Object[])in.readObject();
                descriptor = new ImmutableDescriptor(names, values);
            }

            break;
        case 0:
            descriptor = (Descriptor)in.readObject();

            if (descriptor == null) {
                descriptor = ImmutableDescriptor.EMPTY_DESCRIPTOR;
            }

            break;
        case -1: // from an earlier version of the JMX API
            descriptor = ImmutableDescriptor.EMPTY_DESCRIPTOR;

            break;
        default:
            throw new StreamCorruptedException("Got unexpected byte.");
        }
    }
}
