/* OpenMBeanInfoSupport.java -- Open typed info about a bean.
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package javax.management.openmbean;

import java.util.Arrays;
import java.util.HashSet;

import javax.management.MBeanInfo;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;

/**
 * Describes an open management bean.
 *
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 * @since 1.5
 */
public class OpenMBeanInfoSupport
  extends MBeanInfo
  implements OpenMBeanInfo
{

  /**
   * Compatible with JDK 1.5
   */
  private static final long serialVersionUID = 4349395935420511492L;

  /**
   * The hash code of this instance.
   */
  private transient Integer hashCode;

  /**
   * The <code>toString()</code> result of this instance.
   */
  private transient String string;

  /**
   * Constructs a new {@link OpenMBeanInfo} using the supplied
   * class name and description with the given attributes,
   * operations, constructors and notifications.  The class
   * name does not have to actually specify a valid class that
   * can be loaded by the MBean server or class loader; it merely
   * has to be a syntactically correct class name.  Any of the
   * arrays may be <code>null</code>; this will be treated as if
   * an empty array was supplied.  A copy of the arrays is
   * taken, so later changes have no effect.
   *
   * @param name the name of the class this instance describes.
   * @param desc a description of the bean.
   * @param attribs the attribute descriptions for the bean,
   *                or <code>null</code>.
   * @param cons the constructor descriptions for the bean,
   *             or <code>null</code>.
   * @param ops the operation descriptions for the bean,
   *            or <code>null</code>.
   * @param notifs the notification descriptions for the bean,
   *               or <code>null</code>.
   * @throws ArrayStoreException if a members of an array
   *                             is not assignable to the equivalent
   *                             <code>MBeanXXXInfo</code> class.
   */
  public OpenMBeanInfoSupport(String name, String desc,
                              OpenMBeanAttributeInfo[] attribs,
                              OpenMBeanConstructorInfo[] cons,
                              OpenMBeanOperationInfo[] ops,
                              MBeanNotificationInfo[] notifs)
  {
    super(name, desc, (MBeanAttributeInfo[]) attribs,
          (MBeanConstructorInfo[]) cons,
          (MBeanOperationInfo[]) ops,
          notifs);
  }

  /**
   * Compares this attribute with the supplied object.  This returns
   * true iff the object is an instance of {@link OpenMBeanInfo}
   * with the same class name and equal instances of the info classes.
   *
   * @param obj the object to compare.
   * @return true if the object is a {@link OpenMBeanInfo}
   *         instance,
   *         <code>className.equals(object.getClassName())</code>
   *         and each info class has an equal in the other object.
   */
  public boolean equals(Object obj)
  {
    if (!(obj instanceof OpenMBeanInfo))
      return false;
    OpenMBeanInfo o = (OpenMBeanInfo) obj;
    return getClassName().equals(o.getClassName()) &&
      getAttributes().equals(o.getAttributes()) &&
      getConstructors().equals(o.getConstructors()) &&
      getNotifications().equals(o.getNotifications()) &&
      getOperations().equals(o.getOperations());
  }

  /**
   * <p>
   * Returns the hashcode of the bean information as the sum of the
   * hashcodes of the class name and each array (calculated using
   * java.util.HashSet(<code>java.util.Arrays.asList(signature)).hashCode()</code>).
   * </p>
   * <p>
   * As instances of this class are immutable, the return value
   * is computed just once for each instance and reused
   * throughout its life.
   * </p>
   *
   * @return the hashcode of the bean information.
   */
  public int hashCode()
  {
    if (hashCode == null)
      hashCode =
        Integer.valueOf(getClassName().hashCode() +
                        new HashSet<MBeanAttributeInfo>(Arrays.asList(getAttributes())).hashCode() +
                        new HashSet<MBeanConstructorInfo>(Arrays.asList(getConstructors())).hashCode() +
                        new HashSet<MBeanNotificationInfo>(Arrays.asList(getNotifications())).hashCode() +
                        new HashSet<MBeanOperationInfo>(Arrays.asList(getOperations())).hashCode());
    return hashCode.intValue();
  }

  /**
   * <p>
   * Returns a textual representation of this instance.  This
   * is constructed using the class name
   * (<code>javax.management.openmbean.OpenMBeanInfo</code>)
   * along with the class name and textual representations
   * of each array.
   * </p>
   * <p>
   * As instances of this class are immutable, the return value
   * is computed just once for each instance and reused
   * throughout its life.
   * </p>
   *
   * @return a @link{java.lang.String} instance representing
   *         the instance in textual form.
   */
  public String toString()
  {
    if (string == null)
      string = getClass().getName()
        + "[className=" + getClassName()
        + ",attributes=" + Arrays.toString(getAttributes())
        + ",constructors=" + Arrays.toString(getConstructors())
        + ",notifications=" + Arrays.toString(getNotifications())
        + ",operations=" + Arrays.toString(getOperations())
        + "]";
    return string;
  }

}
