mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			551 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			551 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Java
		
	
	
	
/* Translator.java -- Performs MXBean data type translation.
 | 
						|
   Copyright (C) 2007 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 gnu.javax.management;
 | 
						|
 | 
						|
import java.lang.reflect.Array;
 | 
						|
import java.lang.reflect.Method;
 | 
						|
import java.lang.reflect.Modifier;
 | 
						|
import java.lang.reflect.ParameterizedType;
 | 
						|
import java.lang.reflect.Proxy;
 | 
						|
import java.lang.reflect.Type;
 | 
						|
 | 
						|
import java.util.ArrayList;
 | 
						|
import java.util.Collection;
 | 
						|
import java.util.HashMap;
 | 
						|
import java.util.Iterator;
 | 
						|
import java.util.List;
 | 
						|
import java.util.Map;
 | 
						|
import java.util.Set;
 | 
						|
import java.util.SortedMap;
 | 
						|
import java.util.SortedSet;
 | 
						|
 | 
						|
import javax.management.JMX;
 | 
						|
import javax.management.MBeanServerInvocationHandler;
 | 
						|
 | 
						|
import javax.management.openmbean.ArrayType;
 | 
						|
import javax.management.openmbean.CompositeData;
 | 
						|
import javax.management.openmbean.CompositeDataSupport;
 | 
						|
import javax.management.openmbean.CompositeType;
 | 
						|
import javax.management.openmbean.OpenDataException;
 | 
						|
import javax.management.openmbean.OpenMBeanParameterInfo;
 | 
						|
import javax.management.openmbean.OpenMBeanParameterInfoSupport;
 | 
						|
import javax.management.openmbean.OpenType;
 | 
						|
import javax.management.openmbean.SimpleType;
 | 
						|
import javax.management.openmbean.TabularData;
 | 
						|
import javax.management.openmbean.TabularDataSupport;
 | 
						|
import javax.management.openmbean.TabularType;
 | 
						|
 | 
						|
/**
 | 
						|
 * Translates Java data types to their equivalent
 | 
						|
 * open data type, and vice versa, according to the
 | 
						|
 * {@link javax.management.MXBean} rules.
 | 
						|
 *
 | 
						|
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 | 
						|
 */
 | 
						|
public final class Translator
 | 
						|
{
 | 
						|
 | 
						|
  /**
 | 
						|
   * Translates the input Java data types to the equivalent
 | 
						|
   * open data types.
 | 
						|
   *
 | 
						|
   * @param jtypes the Java types supplied as parameters.
 | 
						|
   * @param method the method that was called.
 | 
						|
   * @return the equivalent open types required by the {@link MXBean}.
 | 
						|
   * @throws Throwable if an exception is thrown in performing the
 | 
						|
   *                   conversion.
 | 
						|
   */
 | 
						|
  public static final Object[] fromJava(Object[] jtypes, Method method)
 | 
						|
    throws Throwable
 | 
						|
  {
 | 
						|
    Type[] gtypes = method.getGenericParameterTypes();
 | 
						|
    Object[] otypes = new Object[jtypes.length];
 | 
						|
    for (int a = 0; a < jtypes.length; ++a)
 | 
						|
      otypes[a] = fromJava(jtypes[a], gtypes[a]);
 | 
						|
    return otypes;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Translates the input Java data type to the equivalent
 | 
						|
   * open data type.
 | 
						|
   *
 | 
						|
   * @param jtype the Java type supplied as a parameter.
 | 
						|
   * @param type the type of the parameter.
 | 
						|
   * @return the equivalent open type required by the {@link MXBean}.
 | 
						|
   * @throws Throwable if an exception is thrown in performing the
 | 
						|
   *                   conversion.
 | 
						|
   */
 | 
						|
  public static final Object fromJava(Object jtype, Type type)
 | 
						|
    throws Throwable
 | 
						|
  {
 | 
						|
    if (jtype == null)
 | 
						|
      return null;
 | 
						|
    Class<?> jclass = jtype.getClass();
 | 
						|
    if (OpenType.ALLOWED_CLASSNAMES_LIST.contains(jclass.getName()))
 | 
						|
      return jtype;
 | 
						|
    if (jclass.isArray())
 | 
						|
      {
 | 
						|
        Class<?> ctype = jclass.getComponentType();
 | 
						|
        if (ctype.isPrimitive())
 | 
						|
          return jtype;
 | 
						|
        if (OpenType.ALLOWED_CLASSNAMES_LIST.contains(ctype.getName()))
 | 
						|
          return jtype;
 | 
						|
        Object[] elems = (Object[]) jtype;
 | 
						|
        Object[] celems = new Object[elems.length];
 | 
						|
        for (int a = 0; a < elems.length; ++a)
 | 
						|
          celems[a] = fromJava(elems[a], elems[a].getClass());
 | 
						|
        return makeArraySpecific(celems);
 | 
						|
      }
 | 
						|
    String tName = getTypeName(type);
 | 
						|
    if (jtype instanceof List || jtype instanceof Set ||
 | 
						|
        jtype instanceof SortedSet)
 | 
						|
      {
 | 
						|
        if (jtype instanceof SortedSet)
 | 
						|
          {
 | 
						|
            ParameterizedType ptype = (ParameterizedType) type;
 | 
						|
            Class<?> elemClass = (Class<?>) ptype.getActualTypeArguments()[0];
 | 
						|
            if (!Comparable.class.isAssignableFrom(elemClass))
 | 
						|
              throw new IllegalArgumentException(jtype + " has a " +
 | 
						|
                                                 "non-comparable element " +
 | 
						|
                                                 "type, " + elemClass);
 | 
						|
            if (((SortedSet<?>) jtype).comparator() != null)
 | 
						|
              throw new IllegalArgumentException(jtype + " does not " +
 | 
						|
                                                 "use natural ordering.");
 | 
						|
          }
 | 
						|
        Collection<?> elems = (Collection<?>) jtype;
 | 
						|
        int numElems = elems.size();
 | 
						|
        Object[] celems = new Object[numElems];
 | 
						|
        Iterator<?> i = elems.iterator();
 | 
						|
        for (int a = 0; a < numElems; ++a)
 | 
						|
          {
 | 
						|
            Object elem = i.next();
 | 
						|
            celems[a] = fromJava(elem, elem.getClass());
 | 
						|
          }
 | 
						|
        return makeArraySpecific(celems);
 | 
						|
      }
 | 
						|
    if (jtype instanceof Enum)
 | 
						|
      return ((Enum<?>) jtype).name();
 | 
						|
    if (jtype instanceof Map || jtype instanceof SortedMap)
 | 
						|
      {
 | 
						|
        int lparam = tName.indexOf("<");
 | 
						|
        int comma = tName.indexOf(",", lparam);
 | 
						|
        int rparam = tName.indexOf(">", comma);
 | 
						|
        String key = tName.substring(lparam + 1, comma).trim();
 | 
						|
        String value = tName.substring(comma + 1, rparam).trim();
 | 
						|
        String typeName = null;
 | 
						|
        if (jtype instanceof Map)
 | 
						|
          typeName = "java.util.Map" + tName.substring(lparam);
 | 
						|
        else
 | 
						|
          {
 | 
						|
            Class<?> keyClass = Class.forName(key);
 | 
						|
            if (!Comparable.class.isAssignableFrom(keyClass))
 | 
						|
              throw new IllegalArgumentException(jtype + " has a " +
 | 
						|
                                                 "non-comparable element " +
 | 
						|
                                                 "type, " + keyClass);
 | 
						|
            if (((SortedMap<?,?>) jtype).comparator() != null)
 | 
						|
              throw new IllegalArgumentException(jtype + " does not " +
 | 
						|
                                                 "use natural ordering.");
 | 
						|
            typeName = "java.util.SortedMap" + tName.substring(lparam);
 | 
						|
          }
 | 
						|
        OpenType<?> k = translate(key).getOpenType();
 | 
						|
        OpenType<?> v = translate(value).getOpenType();
 | 
						|
        CompositeType rowType = new CompositeType(typeName, typeName,
 | 
						|
                                                  new String[] { "key", "value" },
 | 
						|
                                                  new String[] { "Map key", "Map value"},
 | 
						|
                                                  new OpenType[] {k,v});
 | 
						|
        TabularType tabType = new TabularType(typeName, typeName, rowType,
 | 
						|
                                              new String[]{"key"});
 | 
						|
        TabularData data = new TabularDataSupport(tabType);
 | 
						|
        for (Map.Entry<?,?> entry : ((Map<?,?>) jtype).entrySet())
 | 
						|
          {
 | 
						|
            try
 | 
						|
              {
 | 
						|
                data.put(new CompositeDataSupport(rowType,
 | 
						|
                                                  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;
 | 
						|
      }
 | 
						|
    if (JMX.isMXBeanInterface(jclass))
 | 
						|
      {
 | 
						|
        try
 | 
						|
          {
 | 
						|
            MBeanServerInvocationHandler ih = (MBeanServerInvocationHandler)
 | 
						|
              Proxy.getInvocationHandler(jtype);
 | 
						|
            return ih.getObjectName();
 | 
						|
          }
 | 
						|
        catch (IllegalArgumentException e)
 | 
						|
          {
 | 
						|
            throw new IllegalArgumentException("For a MXBean to be translated " +
 | 
						|
                                               "to an open type, it must be a " +
 | 
						|
                                               "proxy.", e);
 | 
						|
          }
 | 
						|
        catch (ClassCastException e)
 | 
						|
          {
 | 
						|
            throw new IllegalArgumentException("For a MXBean to be translated " +
 | 
						|
                                               "to an open type, it must have a " +
 | 
						|
                                               "MBeanServerInvocationHandler.", e);
 | 
						|
          }
 | 
						|
      }
 | 
						|
    /* FIXME: Handle other types */
 | 
						|
    throw new IllegalArgumentException("The type, " + jtype +
 | 
						|
                                       ", is not convertible.");
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Translates the returned open data type to the value
 | 
						|
   * required by the interface.
 | 
						|
   *
 | 
						|
   * @param otype the open type returned by the method call.
 | 
						|
   * @param method the method that was called.
 | 
						|
   * @return the equivalent return type required by the interface.
 | 
						|
   * @throws Throwable if an exception is thrown in performing the
 | 
						|
   *                   conversion.
 | 
						|
   */
 | 
						|
  public static final Object toJava(Object otype, Method method)
 | 
						|
    throws Throwable
 | 
						|
  {
 | 
						|
    Class<?> returnType = method.getReturnType();
 | 
						|
    if (returnType.isEnum())
 | 
						|
      {
 | 
						|
        String ename = (String) otype;
 | 
						|
        Enum<?>[] constants = (Enum[]) returnType.getEnumConstants();
 | 
						|
        for (Enum<?> c : constants)
 | 
						|
          if (c.name().equals(ename))
 | 
						|
            return c;
 | 
						|
      }
 | 
						|
    if (List.class.isAssignableFrom(returnType))
 | 
						|
      {
 | 
						|
        Object[] elems = (Object[]) otype;
 | 
						|
        List<Object> l = new ArrayList<Object>(elems.length);
 | 
						|
        for (Object elem : elems)
 | 
						|
          l.add(elem);
 | 
						|
        return l;
 | 
						|
      }
 | 
						|
    if (Map.class.isAssignableFrom(returnType))
 | 
						|
      {
 | 
						|
        TabularData data = (TabularData) otype;
 | 
						|
        Map<Object,Object> m = new HashMap<Object,Object>(data.size());
 | 
						|
        for (Object val : data.values())
 | 
						|
          {
 | 
						|
            CompositeData vals = (CompositeData) val;
 | 
						|
            m.put(vals.get("key"), vals.get("value"));
 | 
						|
          }
 | 
						|
        return m;
 | 
						|
      }
 | 
						|
    try
 | 
						|
      {
 | 
						|
        Method m = returnType.getMethod("from",
 | 
						|
                                        new Class[]
 | 
						|
          { CompositeData.class });
 | 
						|
        return m.invoke(null, (CompositeData) otype);
 | 
						|
      }
 | 
						|
    catch (NoSuchMethodException e)
 | 
						|
      {
 | 
						|
        /* Ignored; we expect this if this
 | 
						|
           isn't a from(CompositeData) class */
 | 
						|
      }
 | 
						|
    return otype;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Creates a new array which has the specific type
 | 
						|
   * used by the elements of the original {@link Object}
 | 
						|
   * array supplied.
 | 
						|
   *
 | 
						|
   * @param arr a series of elements in an {@link Object}
 | 
						|
   *            array.
 | 
						|
   * @return the same elements in a new array of the specific
 | 
						|
   *         type.
 | 
						|
   */
 | 
						|
  private static final Object[] makeArraySpecific(Object[] arr)
 | 
						|
  {
 | 
						|
    Object[] rcelems = (Object[]) Array.newInstance(arr[0].getClass(),
 | 
						|
                                                    arr.length);
 | 
						|
    System.arraycopy(arr, 0, rcelems, 0, arr.length);
 | 
						|
    return rcelems;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Translates the name of a type into an equivalent
 | 
						|
   * {@link javax.management.openmbean.OpenMBeanParameterInfo}
 | 
						|
   * that describes it.
 | 
						|
   *
 | 
						|
   * @param type the type to describe.
 | 
						|
   * @return an instance of
 | 
						|
   * {@link javax.management.openmbean.OpenMBeanParameterInfo},
 | 
						|
   * describing the translated type and limits of the given type.
 | 
						|
   * @throws OpenDataException if a type is not open.
 | 
						|
   */
 | 
						|
  public static final OpenMBeanParameterInfo translate(String type)
 | 
						|
    throws OpenDataException
 | 
						|
  {
 | 
						|
    if (type.equals("boolean") || type.equals(Boolean.class.getName()))
 | 
						|
      return new OpenMBeanParameterInfoSupport("TransParam",
 | 
						|
                                               "Translated parameter",
 | 
						|
                                               SimpleType.BOOLEAN,
 | 
						|
                                               null,
 | 
						|
                                               new Boolean[] {
 | 
						|
                                                 Boolean.TRUE,
 | 
						|
                                                 Boolean.FALSE
 | 
						|
                                               });
 | 
						|
    if (type.equals("byte") || type.equals(Byte.class.getName()))
 | 
						|
      return new OpenMBeanParameterInfoSupport("TransParam",
 | 
						|
                                               "Translated parameter",
 | 
						|
                                               SimpleType.BYTE,
 | 
						|
                                               null,
 | 
						|
                                               Byte.valueOf(Byte.MIN_VALUE),
 | 
						|
                                               Byte.valueOf(Byte.MAX_VALUE));
 | 
						|
    if (type.equals("char") || type.equals(Character.class.getName()))
 | 
						|
      return new OpenMBeanParameterInfoSupport("TransParam",
 | 
						|
                                               "Translated parameter",
 | 
						|
                                               SimpleType.CHARACTER,
 | 
						|
                                               null,
 | 
						|
                                               Character.valueOf(Character.MIN_VALUE),
 | 
						|
                                               Character.valueOf(Character.MAX_VALUE));
 | 
						|
    if (type.equals("double") || type.equals(Double.class.getName()))
 | 
						|
      return new OpenMBeanParameterInfoSupport("TransParam",
 | 
						|
                                               "Translated parameter",
 | 
						|
                                               SimpleType.DOUBLE,
 | 
						|
                                               null,
 | 
						|
                                               Double.valueOf(Double.MIN_VALUE),
 | 
						|
                                               Double.valueOf(Double.MAX_VALUE));
 | 
						|
    if (type.equals("float") || type.equals(Float.class.getName()))
 | 
						|
      return new OpenMBeanParameterInfoSupport("TransParam",
 | 
						|
                                               "Translated parameter",
 | 
						|
                                               SimpleType.FLOAT,
 | 
						|
                                               null,
 | 
						|
                                               Float.valueOf(Float.MIN_VALUE),
 | 
						|
                                               Float.valueOf(Float.MAX_VALUE));
 | 
						|
    if (type.equals("int") || type.equals(Integer.class.getName()))
 | 
						|
      return new OpenMBeanParameterInfoSupport("TransParam",
 | 
						|
                                               "Translated parameter",
 | 
						|
                                               SimpleType.INTEGER,
 | 
						|
                                               null,
 | 
						|
                                               Integer.valueOf(Integer.MIN_VALUE),
 | 
						|
                                               Integer.valueOf(Integer.MAX_VALUE));
 | 
						|
    if (type.equals("long") || type.equals(Long.class.getName()))
 | 
						|
      return new OpenMBeanParameterInfoSupport("TransParam",
 | 
						|
                                               "Translated parameter",
 | 
						|
                                               SimpleType.LONG,
 | 
						|
                                               null,
 | 
						|
                                               Long.valueOf(Long.MIN_VALUE),
 | 
						|
                                               Long.valueOf(Long.MAX_VALUE));
 | 
						|
    if (type.equals("short") || type.equals(Short.class.getName()))
 | 
						|
      return new OpenMBeanParameterInfoSupport("TransParam",
 | 
						|
                                               "Translated parameter",
 | 
						|
                                               SimpleType.SHORT,
 | 
						|
                                               null,
 | 
						|
                                               Short.valueOf(Short.MIN_VALUE),
 | 
						|
                                               Short.valueOf(Short.MAX_VALUE));
 | 
						|
    if (type.equals(String.class.getName()))
 | 
						|
      return new OpenMBeanParameterInfoSupport("TransParam",
 | 
						|
                                               "Translated parameter",
 | 
						|
                                               SimpleType.STRING);
 | 
						|
    if (type.equals("void"))
 | 
						|
      return new OpenMBeanParameterInfoSupport("TransParam",
 | 
						|
                                               "Translated parameter",
 | 
						|
                                               SimpleType.VOID);
 | 
						|
    if (type.startsWith("java.util.Map"))
 | 
						|
      {
 | 
						|
        int lparam = type.indexOf("<");
 | 
						|
        int comma = type.indexOf(",", lparam);
 | 
						|
        int rparam = type.indexOf(">", comma);
 | 
						|
        String key = type.substring(lparam + 1, comma).trim();
 | 
						|
        OpenType<?> k = translate(key).getOpenType();
 | 
						|
        OpenType<?> v = translate(type.substring(comma + 1, rparam).trim()).getOpenType();
 | 
						|
        CompositeType ctype = new CompositeType(Map.class.getName(), Map.class.getName(),
 | 
						|
                                                new String[] { "key", "value" },
 | 
						|
                                                new String[] { "Map key", "Map value"},
 | 
						|
                                                new OpenType[] { k, v});
 | 
						|
        TabularType ttype = new TabularType(key, key, ctype,
 | 
						|
                                            new String[] { "key" });
 | 
						|
        return new OpenMBeanParameterInfoSupport("TransParam",
 | 
						|
                                                 "Translated parameter",
 | 
						|
                                                 ttype);
 | 
						|
      }
 | 
						|
    if (type.startsWith("java.util.List"))
 | 
						|
      {
 | 
						|
        int lparam = type.indexOf("<");
 | 
						|
        int rparam = type.indexOf(">");
 | 
						|
        OpenType<?> e = translate(type.substring(lparam + 1, rparam).trim()).getOpenType();
 | 
						|
        return new OpenMBeanParameterInfoSupport("TransParam",
 | 
						|
                                                 "Translated parameter",
 | 
						|
                                                 new ArrayType<OpenType<?>>(1, e)
 | 
						|
                                                 );
 | 
						|
      }
 | 
						|
    Class<?> c;
 | 
						|
    try
 | 
						|
      {
 | 
						|
        c = Class.forName(type);
 | 
						|
      }
 | 
						|
    catch (ClassNotFoundException e)
 | 
						|
      {
 | 
						|
        throw (InternalError)
 | 
						|
          (new InternalError("The class for a type used in a management bean " +
 | 
						|
                             "could not be loaded.").initCause(e));
 | 
						|
      }
 | 
						|
    if (c.isEnum())
 | 
						|
      {
 | 
						|
        Object[] values = c.getEnumConstants();
 | 
						|
        String[] names = new String[values.length];
 | 
						|
        for (int a = 0; a < values.length; ++a)
 | 
						|
          names[a] = values[a].toString();
 | 
						|
        return new OpenMBeanParameterInfoSupport("TransParam",
 | 
						|
                                                 "Translated parameter",
 | 
						|
                                                 SimpleType.STRING,
 | 
						|
                                                 null, names);
 | 
						|
      }
 | 
						|
    if (c.isArray())
 | 
						|
      {
 | 
						|
        int depth;
 | 
						|
        for (depth = 0; c.getName().charAt(depth) == '['; ++depth)
 | 
						|
          ;
 | 
						|
        OpenType<?> ot = getTypeFromClass(c.getComponentType());
 | 
						|
        return new OpenMBeanParameterInfoSupport("TransParam",
 | 
						|
                                                 "Translated parameter",
 | 
						|
                                                 new ArrayType<OpenType<?>>(depth, ot)
 | 
						|
                                                 );
 | 
						|
      }
 | 
						|
    Method[] methods = c.getDeclaredMethods();
 | 
						|
    List<String> names = new ArrayList<String>();
 | 
						|
    List<OpenType<?>> types = new ArrayList<OpenType<?>>();
 | 
						|
    for (int a = 0; a < methods.length; ++a)
 | 
						|
      {
 | 
						|
        String name = methods[a].getName();
 | 
						|
        if (Modifier.isPublic(methods[a].getModifiers()))
 | 
						|
          {
 | 
						|
            if (name.startsWith("get"))
 | 
						|
              {
 | 
						|
                names.add(name.substring(3));
 | 
						|
                types.add(getTypeFromClass(methods[a].getReturnType()));
 | 
						|
              }
 | 
						|
            else if (name.startsWith("is"))
 | 
						|
              {
 | 
						|
                names.add(name.substring(2));
 | 
						|
                types.add(getTypeFromClass(methods[a].getReturnType()));
 | 
						|
              }
 | 
						|
          }
 | 
						|
      }
 | 
						|
    if (names.isEmpty())
 | 
						|
      throw new OpenDataException("The type used does not have an open type translation.");
 | 
						|
    String[] fields = names.toArray(new String[names.size()]);
 | 
						|
    CompositeType ctype = new CompositeType(c.getName(), c.getName(),
 | 
						|
                                            fields, fields,
 | 
						|
                                            types.toArray(new OpenType[types.size()]));
 | 
						|
    return new OpenMBeanParameterInfoSupport("TransParam",
 | 
						|
                                             "Translated parameter",
 | 
						|
                                             ctype);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Obtains the {@link javax.management.openmbean.OpenType}
 | 
						|
   * for a particular class.
 | 
						|
   *
 | 
						|
   * @param c the class to obtain the type for.
 | 
						|
   * @return the appropriate instance.
 | 
						|
   * @throws OpenDataException if the type is not open.
 | 
						|
   */
 | 
						|
  private static final OpenType<?> getTypeFromClass(Class<?> c)
 | 
						|
    throws OpenDataException
 | 
						|
  {
 | 
						|
    return Translator.translate(c.getName()).getOpenType();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * <p>
 | 
						|
   * Returns the type name according to the rules described
 | 
						|
   * in {@link javax.management.MXBean}.  Namely, for a type,
 | 
						|
   * {@code T}, {@code typename(T)} is computed as follows:
 | 
						|
   * </p>
 | 
						|
   * <ul>
 | 
						|
   * <li>If T is non-generic and not an array, then the value
 | 
						|
   * of {@link java.lang.Class#getName()} is returned.</li>
 | 
						|
   * <li>If T is an array type, {@code{E[]}, then the type name
 | 
						|
   * is {@code typename(E)} followed by an occurrence
 | 
						|
   * of {@code '[]'} for each dimension.</li>
 | 
						|
   * <li>If T is a generic or parameterized type, the type name
 | 
						|
   * is composed of {@code typename(P)}, where {@code P} is the
 | 
						|
   * parameterized type name, followed by {@code '<'}, the resulting
 | 
						|
   * list of type names of the parameters after applying {@code typename}
 | 
						|
   * to each, separated by commas, and {@code '>'}.</li>
 | 
						|
   * </ul>
 | 
						|
   *
 | 
						|
   * @param type the type to return the type name of.
 | 
						|
   * @return the type name computed according to the rules above.
 | 
						|
   */
 | 
						|
  private static final String getTypeName(Type type)
 | 
						|
  {
 | 
						|
    if (type instanceof Class)
 | 
						|
      {
 | 
						|
        Class<?> c = (Class<?>) type;
 | 
						|
        if (c.isArray())
 | 
						|
          {
 | 
						|
            StringBuilder b =
 | 
						|
              new StringBuilder(c.getComponentType().getName());
 | 
						|
            String normName = c.getName();
 | 
						|
            for (int a = 0; a < normName.length(); ++a)
 | 
						|
              {
 | 
						|
                if (normName.charAt(a) == '[')
 | 
						|
                  b.append("[]");
 | 
						|
                else
 | 
						|
                  break;
 | 
						|
              }
 | 
						|
            return b.toString();
 | 
						|
          }
 | 
						|
        return c.getName();
 | 
						|
      }
 | 
						|
    return type.toString();
 | 
						|
  }
 | 
						|
 | 
						|
}
 |