/* BeanImpl.java - A common superclass for bean implementations.
   Copyright (C) 2006 Free Software Foundation

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 gnu.java.lang.management;

import gnu.javax.management.Translator;

import java.lang.management.ManagementPermission;

import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.management.AttributeNotFoundException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.NotCompliantMBeanException;
import javax.management.ReflectionException;
import javax.management.StandardMBean;

import javax.management.openmbean.ArrayType;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.OpenDataException;
import javax.management.openmbean.OpenMBeanAttributeInfo;
import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
import javax.management.openmbean.OpenMBeanConstructorInfo;
import javax.management.openmbean.OpenMBeanConstructorInfoSupport;
import javax.management.openmbean.OpenMBeanInfo;
import javax.management.openmbean.OpenMBeanInfoSupport;
import javax.management.openmbean.OpenMBeanOperationInfo;
import javax.management.openmbean.OpenMBeanOperationInfoSupport;
import javax.management.openmbean.OpenMBeanParameterInfo;
import javax.management.openmbean.OpenMBeanParameterInfoSupport;
import javax.management.openmbean.OpenType;
import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;

/**
 * A common superclass for bean implementations.
 *
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 * @since 1.5
 */
public class BeanImpl
  extends StandardMBean
{

  /**
   * Cached open bean information.
   */
  private OpenMBeanInfo openInfo;

  /**
   * Constructs a new <code>BeanImpl</code>.
   *
   * @param iface the bean interface being implemented.
   * @throws NotCompliantMBeanException if this class doesn't implement
   *                                    the interface or a method appears
   *                                    in the interface that doesn't comply
   *                                    with the naming conventions.
   */
  protected BeanImpl(Class iface)
    throws NotCompliantMBeanException
  {
    super(iface);
  }

  protected void cacheMBeanInfo(MBeanInfo info)
  {
    if (info == null)
      return;
    try
      {
        MBeanAttributeInfo[] oldA = info.getAttributes();
        OpenMBeanAttributeInfo[] attribs =
          new OpenMBeanAttributeInfoSupport[oldA.length];
        for (int a = 0; a < oldA.length; ++a)
          {
            OpenMBeanParameterInfo param = Translator.translate(oldA[a].getType());
            if (param.getMinValue() == null)
              {
                Object[] lv;
                if (param.getLegalValues() == null)
                  lv = null;
                else
                  lv = param.getLegalValues().toArray();
                attribs[a] = new OpenMBeanAttributeInfoSupport(oldA[a].getName(),
                                                               oldA[a].getDescription(),
                                                               ((OpenType<Object>)
                                                                param.getOpenType()),
                                                               oldA[a].isReadable(),
                                                               oldA[a].isWritable(),
                                                               oldA[a].isIs(),
                                                               param.getDefaultValue(),
                                                               lv);
              }
            else
              attribs[a] = new OpenMBeanAttributeInfoSupport(oldA[a].getName(),
                                                             oldA[a].getDescription(),
                                                             ((OpenType<Object>)
                                                              param.getOpenType()),
                                                             oldA[a].isReadable(),
                                                             oldA[a].isWritable(),
                                                             oldA[a].isIs(),
                                                             param.getDefaultValue(),
                                                             ((Comparable<Object>)
                                                               param.getMinValue()),
                                                             ((Comparable<Object>)
                                                               param.getMaxValue()));
          }
        MBeanConstructorInfo[] oldC = info.getConstructors();
        OpenMBeanConstructorInfo[] cons = new OpenMBeanConstructorInfoSupport[oldC.length];
        for (int a = 0; a < oldC.length; ++a)
          cons[a] =
            new OpenMBeanConstructorInfoSupport(oldC[a].getName(),
                                                oldC[a].getDescription(),
                                                translateSignature(oldC[a].getSignature()));
        MBeanOperationInfo[] oldO = info.getOperations();
        OpenMBeanOperationInfo[] ops = new OpenMBeanOperationInfoSupport[oldO.length];
        for (int a = 0; a < oldO.length; ++a)
          ops[a] =
        new OpenMBeanOperationInfoSupport(oldO[a].getName(),
                                          oldO[a].getDescription(),
                                          translateSignature(oldO[a].getSignature()),
                                          Translator.translate(oldO[a].getReturnType()).getOpenType(),
                                          oldO[a].getImpact());
        openInfo = new OpenMBeanInfoSupport(info.getClassName(), info.getDescription(),
                                            attribs, cons, ops, info.getNotifications());
      }
    catch (OpenDataException e)
      {
        throw (InternalError) (new InternalError("A problem occurred creating the open type " +
                                                 "descriptors.").initCause(e));
      }
  }

  protected void checkMonitorPermissions()
  {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkPermission(new ManagementPermission("monitor"));
  }

  protected void checkControlPermissions()
  {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkPermission(new ManagementPermission("control"));
  }

  public Object getAttribute(String attribute)
    throws AttributeNotFoundException, MBeanException,
           ReflectionException
  {
    Object value = super.getAttribute(attribute);
    if (value instanceof Enum)
      return ((Enum) value).name();
    Class vClass = value.getClass();
    if (vClass.isArray())
      vClass = vClass.getComponentType();
    String cName = vClass.getName();
    String[] allowedTypes = OpenType.ALLOWED_CLASSNAMES;
    for (int a = 0; a < allowedTypes.length; ++a)
      if (cName.equals(allowedTypes[a]))
        return value;
    OpenMBeanInfo info = (OpenMBeanInfo) getMBeanInfo();
    MBeanAttributeInfo[] attribs =
      (MBeanAttributeInfo[]) info.getAttributes();
    OpenType type = null;
    for (int a = 0; a < attribs.length; ++a)
      if (attribs[a].getName().equals(attribute))
        type = ((OpenMBeanAttributeInfo) attribs[a]).getOpenType();
    if (value instanceof List)
      {
        try
          {
            Class e =
              Class.forName(((ArrayType) type).getElementOpenType().getClassName());
            List l = (List) value;
            Object[] array = (Object[]) Array.newInstance(e, l.size());
            return l.toArray(array);
          }
        catch (ClassNotFoundException e)
          {
            throw (InternalError) (new InternalError("The class of the list " +
                                                     "element type could not " +
                                                     "be created").initCause(e));
          }
      }
    if (value instanceof Map)
      {
        TabularType ttype = (TabularType) type;
        TabularData data = new TabularDataSupport(ttype);
        Iterator it = ((Map) value).entrySet().iterator();
        while (it.hasNext())
          {
            Map.Entry entry = (Map.Entry) it.next();
            try
              {
                data.put(new CompositeDataSupport(ttype.getRowType(),
                                                  new String[] {
                                                    "key",
                                                    "value"
                                                  },
                                                  new Object[] {
                                                    entry.getKey(),
                                                    entry.getValue()
                                                  }));
              }
            catch (OpenDataException e)
              {
                throw (InternalError) (new InternalError("A problem occurred " +
                                                         "converting the map " +
                                                         "to a composite data " +
                                                         "structure.").initCause(e));
              }
          }
        return data;
      }
    CompositeType cType = (CompositeType) type;
    Set names = cType.keySet();
    Iterator it = names.iterator();
    List values = new ArrayList(names.size());
    while (it.hasNext())
      {
        String field = (String) it.next();
        Method getter = null;
        try
          {
            getter = vClass.getMethod("get" + field);
          }
        catch (NoSuchMethodException e)
          {
            /* Ignored; the type tells us it's there. */
          }
        try
          {
            values.add(getter.invoke(value));
          }
        catch (IllegalAccessException e)
          {
            throw new ReflectionException(e, "Failed to retrieve " + field);
          }
        catch (IllegalArgumentException e)
          {
            throw new ReflectionException(e, "Failed to retrieve " + field);
          }
        catch (InvocationTargetException e)
          {
            throw new MBeanException((Exception) e.getCause(),
                                     "The getter of " + field +
                                     " threw an exception");
          }
      }
    try
      {
        return new CompositeDataSupport(cType,
                                        (String[])
                                        names.toArray(new String[names.size()]),
                                        values.toArray());
      }
    catch (OpenDataException e)
      {
        throw (InternalError) (new InternalError("A problem occurred " +
                                                 "converting the value " +
                                                 "to a composite data " +
                                                 "structure.").initCause(e));
      }
  }

  protected MBeanInfo getCachedMBeanInfo()
  {
    return (MBeanInfo) openInfo;
  }

  /**
   * Override this method so as to prevent the description of a constructor's
   * parameter being @code{null}.  Open MBeans can not have @code{null} descriptions,
   * but one will occur as the names of parameters aren't stored for reflection.
   *
   * @param constructor the constructor whose parameter needs describing.
   * @param parameter the parameter to be described.
   * @param sequenceNo the number of the parameter to describe.
   * @return a description of the constructor's parameter.
   */
  protected String getDescription(MBeanConstructorInfo constructor,
                                  MBeanParameterInfo parameter,
                                  int sequenceNo)
  {
    String desc = parameter.getDescription();
    if (desc == null)
      return "param" + sequenceNo;
    else
      return desc;
  }

  /**
   * Override this method so as to prevent the description of an operation's
   * parameter being @code{null}.  Open MBeans can not have @code{null} descriptions,
   * but one will occur as the names of parameters aren't stored for reflection.
   *
   * @param operation the operation whose parameter needs describing.
   * @param parameter the parameter to be described.
   * @param sequenceNo the number of the parameter to describe.
   * @return a description of the operation's parameter.
   */
  protected String getDescription(MBeanOperationInfo operation,
                                  MBeanParameterInfo parameter,
                                  int sequenceNo)
  {
    String desc = parameter.getDescription();
    if (desc == null)
      return "param" + sequenceNo;
    else
      return desc;
  }

  /**
   * Override this method so as to prevent the name of a constructor's
   * parameter being @code{null}.  Open MBeans can not have @code{null} names,
   * but one will occur as the names of parameters aren't stored for reflection.
   *
   * @param constructor the constructor whose parameter needs a name.
   * @param parameter the parameter to be named.
   * @param sequenceNo the number of the parameter to name.
   * @return a description of the constructor's parameter.
   */
  protected String getParameterName(MBeanConstructorInfo constructor,
                                    MBeanParameterInfo parameter,
                                    int sequenceNo)
  {
    String name = parameter.getName();
    if (name == null)
      return "param" + sequenceNo;
    else
      return name;
  }

  /**
   * Override this method so as to prevent the name of an operation's
   * parameter being @code{null}.  Open MBeans can not have @code{null} names,
   * but one will occur as the names of parameters aren't stored for reflection.
   *
   * @param operation the operation whose parameter needs a name.
   * @param parameter the parameter to be named.
   * @param sequenceNo the number of the parameter to name.
   * @return a description of the operation's parameter.
   */
  protected String getParameterName(MBeanOperationInfo operation,
                                    MBeanParameterInfo parameter,
                                    int sequenceNo)
  {
    String name = parameter.getName();
    if (name == null)
      return "param" + sequenceNo;
    else
      return name;
  }

  public MBeanInfo getMBeanInfo()
  {
    super.getMBeanInfo();
    return getCachedMBeanInfo();
  }

  private OpenMBeanParameterInfo[] translateSignature(MBeanParameterInfo[] oldS)
    throws OpenDataException
  {
    OpenMBeanParameterInfo[] sig = new OpenMBeanParameterInfoSupport[oldS.length];
    for (int a = 0; a < oldS.length; ++a)
      {
        OpenMBeanParameterInfo param = Translator.translate(oldS[a].getType());
        if (param.getMinValue() == null)
          {
            Object[] lv;
            if (param.getLegalValues() == null)
              lv = null;
            else
              lv = param.getLegalValues().toArray();
            sig[a] = new OpenMBeanParameterInfoSupport(oldS[a].getName(),
                                                       oldS[a].getDescription(),
                                                       ((OpenType<Object>)
                                                        param.getOpenType()),
                                                       param.getDefaultValue(),
                                                       lv);
          }
        else
          sig[a] = new OpenMBeanParameterInfoSupport(oldS[a].getName(),
                                                     oldS[a].getDescription(),
                                                     ((OpenType<Object>)
                                                      param.getOpenType()),
                                                     param.getDefaultValue(),
                                                     ((Comparable<Object>)
                                                      param.getMinValue()),
                                                     ((Comparable<Object>)
                                                      param.getMaxValue()));
      }
    return sig;
  }


}
