Mega Code Archive

 
Categories / Java / Development Class
 

Several utility functions for the JMX implementation

/*  * Copyright (C) The MX4J Contributors.  * All rights reserved.  *  * This software is distributed under the terms of the MX4J License version 1.0.  * See the terms of the MX4J License in the documentation provided with this software.  */ import java.lang.reflect.Array; import java.lang.reflect.Method; /**  * Several utility functions for the JMX implementation  *  * @version $Revision: 1.18 $  */ public class Utils {    /**     * This methods load a class given the classloader and the name of the class, and work for     * extended names of primitive types. <p>     * If you try to do ClassLoader.loadClass("boolean") it barfs it cannot find the class,     * so this method cope with this problem.     */    public static Class loadClass(ClassLoader loader, String name) throws ClassNotFoundException    {       if (name == null) throw new ClassNotFoundException("null");       name = name.trim();       if (name.equals("boolean"))          return boolean.class;       else if (name.equals("byte"))          return byte.class;       else if (name.equals("char"))          return char.class;       else if (name.equals("short"))          return short.class;       else if (name.equals("int"))          return int.class;       else if (name.equals("long"))          return long.class;       else if (name.equals("float"))          return float.class;       else if (name.equals("double"))          return double.class;       else if (name.equals("java.lang.String"))          return String.class;       else if (name.equals("java.lang.Object"))          return Object.class;       else if (name.startsWith("["))       {          // It's an array, figure out how many dimensions          int dimension = 0;          while (name.charAt(dimension) == '[')          {             ++dimension;          }          char type = name.charAt(dimension);          Class cls = null;          switch (type)          {             case 'Z':                cls = boolean.class;                break;             case 'B':                cls = byte.class;                break;             case 'C':                cls = char.class;                break;             case 'S':                cls = short.class;                break;             case 'I':                cls = int.class;                break;             case 'J':                cls = long.class;                break;             case 'F':                cls = float.class;                break;             case 'D':                cls = double.class;                break;             case 'L':                // Strip the semicolon at the end                String n = name.substring(dimension + 1, name.length() - 1);                cls = loadClass(loader, n);                break;          }          if (cls == null)          {             throw new ClassNotFoundException(name);          }          else          {             int[] dim = new int[dimension];             return Array.newInstance(cls, dim).getClass();          }       }       else       {          if (loader != null)             return loader.loadClass(name);          else             return Class.forName(name, false, null);       }    }    /**     * Returns the classes whose names are specified by the <code>names</code> argument, loaded with the     * specified classloader.     */    public static Class[] loadClasses(ClassLoader loader, String[] names) throws ClassNotFoundException    {       int n = names.length;       Class[] cls = new Class[n];       for (int i = 0; i < n; ++i)       {          String name = names[i];          cls[i] = loadClass(loader, name);       }       return cls;    }    /**     * Returns true is the given method is a JMX attribute getter method     */    public static boolean isAttributeGetter(Method m)    {       if (m == null) return false;       String name = m.getName();       Class retType = m.getReturnType();       Class[] params = m.getParameterTypes();       if (retType != Void.TYPE && params.length == 0)       {          if (name.startsWith("get") && name.length() > 3)             return true;          else if (name.startsWith("is") && name.length() > 2 && retType == Boolean.TYPE) return true;       }       return false;    }    /**     * Returns true if the method is a JMX attribute setter method     */    public static boolean isAttributeSetter(Method m)    {       if (m == null) return false;       String name = m.getName();       Class retType = m.getReturnType();       Class[] params = m.getParameterTypes();       if (retType == Void.TYPE && params.length == 1 && name.startsWith("set") && name.length() > 3)       {          return true;       }       return false;    }    public static boolean wildcardMatch(String pattern, String string)    {       int stringLength = string.length();       int stringIndex = 0;       for (int patternIndex = 0; patternIndex < pattern.length(); ++patternIndex)       {          char c = pattern.charAt(patternIndex);          if (c == '*')          {             // Recurse with the pattern without this '*' and the actual string, until             // match is found or we inspected the whole string             while (stringIndex < stringLength)             {                if (wildcardMatch(pattern.substring(patternIndex + 1), string.substring(stringIndex)))                {                   return true;                }                // No match found, try a shorter string, since we are matching '*'                ++stringIndex;             }          }          else if (c == '?')          {             // Increment the string index, since '?' match a single char in the string             ++stringIndex;             if (stringIndex > stringLength)             {                return false;             }          }          else          {             // A normal character in the pattern, must match the one in the string             if (stringIndex >= stringLength || c != string.charAt(stringIndex))             {                return false;             }             ++stringIndex;          }       }       // I've inspected the whole pattern, but not the whole string       return stringIndex == stringLength;    }    public static boolean arrayEquals(Object[] arr1, Object[] arr2)    {       if (arr1 == null && arr2 == null) return true;       if (arr1 == null ^ arr2 == null) return false;       if (!arr1.getClass().equals(arr2.getClass())) return false;       if (arr1.length != arr2.length) return false;       for (int i = 0; i < arr1.length; ++i)       {          Object obj1 = arr1[i];          Object obj2 = arr2[i];          if (obj1 == null ^ obj2 == null) return false;          if (obj1 != null && !obj1.equals(obj2)) return false;       }       return true;    }    public static boolean arrayEquals(byte[] arr1, byte[] arr2)    {       if (arr1 == null && arr2 == null) return true;       if (arr1 == null ^ arr2 == null) return false;       if (!arr1.getClass().equals(arr2.getClass())) return false;       if (arr1.length != arr2.length) return false;       for (int i = 0; i < arr1.length; ++i)       {          byte b1 = arr1[i];          byte b2 = arr2[i];          if (b1 != b2) return false;       }       return true;    }    public static int arrayHashCode(Object[] arr)    {       int hash = 0;       if (arr != null)       {          // Avoid that 2 arrays of length 0 but different classes return same hash          hash ^= arr.getClass().hashCode();          for (int i = 0; i < arr.length; ++i)          {             hash ^= arr[i] == null ? 0 : arr[i].hashCode();          }       }       return hash;    }    public static int arrayHashCode(byte[] arr)    {       int hash = 0;       if (arr != null)       {          // Avoid that 2 arrays of length 0 but different classes return same hash          hash ^= arr.getClass().hashCode();          for (int i = 0; i < arr.length; ++i)          {             hash ^= arr[i];          }       }       return hash;    }    public static char[] arrayCopy(char[] chars)    {       if (chars == null) return null;       char[] copy = new char[chars.length];       System.arraycopy(chars, 0, copy, 0, chars.length);       return copy;    } }