Utils.java Source code

Java tutorial

Introduction

Here is the source code for Utils.java

Source

/*
 * 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;
    }
}