alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Glassfish example source code file (TypeUtil.java)

This example Glassfish source code file (TypeUtil.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Glassfish tags/keywords

class, class, classloader, exception, hashtable, illegalargumentexception, method, method, reflection, string, string, type, typevariable, util, vector, vector

The Glassfish TypeUtil.java source code

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.enterprise.deployment.util;

import com.sun.enterprise.deployment.FieldDescriptor;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.*;

/**
 * Datatype management utility methods
 */
public class TypeUtil {

    // map a decimal digit to its (real!) character
    private static final char[] digits = { 
	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9' 
    };

    // Map of primitive class name and its associated Class object
    private static Hashtable primitiveClasses_;

    static {
        primitiveClasses_ = new Hashtable();
        primitiveClasses_.put(Character.TYPE.getName(), Character.TYPE);
        primitiveClasses_.put(Boolean.TYPE.getName(), Boolean.TYPE);
        primitiveClasses_.put(Byte.TYPE.getName(), Byte.TYPE);
        primitiveClasses_.put(Integer.TYPE.getName(), Integer.TYPE);
        primitiveClasses_.put(Long.TYPE.getName(), Long.TYPE);
        primitiveClasses_.put(Short.TYPE.getName(), Short.TYPE);
        primitiveClasses_.put(Float.TYPE.getName(), Float.TYPE);
        primitiveClasses_.put(Double.TYPE.getName(), Double.TYPE);
    }

    /** 
     * Place a character representation of src into the buffer.
     * No formatting (e.g. localization) is done.
     *
     * @param src - the integer to convert.  Must not be Integer.MIN_VALUE.
     * @param buf - the buf to put the result in
     * @param offset - the offset in buf to place the first digit
     * @return the number of bytes added to buf
     * @exception IllegalArgumentException if src is Integer.MIN_VALUE.
     */
    public static int intGetChars(
	int src,
	char buf[],
	int offset
    ) {
	int power = 1000000000;  // magnitude of highest digit this can handle
	int this_digit;
	boolean have_emitted = false;
	int init_offset = offset;

	// special case src is zero
	if (src == 0) {
	    buf[offset] = digits[0];
	    return 1;
	}
	else if (src < 0) {
	    if (src == Integer.MIN_VALUE)
		throw new IllegalArgumentException();
	    
	    // emit the negation sign and continue as if positive
	    buf[offset++] = '-';
	    src = Math.abs(src);
	}

	// iterate until there are no more digits to emit
	while (power > 0) {
	    this_digit = src / power;
	    if (this_digit != 0 || have_emitted) {
		// emit this digit
		have_emitted = true;
		buf[offset++] = digits[this_digit];
	    }
	    src = src % power;
	    power = power / 10;
	}
	return offset - init_offset;
    }


    // map a digit to its single byte character
    private static final byte[] charval = { 
	(byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5',(byte) '6',(byte) '7',(byte) '8',(byte) '9' 
    };

    /** 
     * Place a byte representation of src into the byte array buf.
     * No commas or any other formatting is done to the integer.
     * @param src - the integer to convert.  Must not be Integer.MIN_VALUE.
     * @param buf - the buf to put the result in
     * @param offset - the offset in buf to place the first digit
     * @return the number of bytes added to buf
     * @exception IllegalArgumentException if src is Integer.MIN_VALUE.
     */
    public static int intGetBytes(
	int src,
	byte buf[],
	int offset
    ) {
	int power = 1000000000;  // magnitude of highest digit this can handle
	int this_digit;
	boolean have_emitted = false;
	int init_offset = offset;

	// special case src is zero
	if (src == 0) {
	    buf[offset] = charval[0];
	    return 1;
	}
	else if (src < 0) {
	    if (src == Integer.MIN_VALUE)
		throw new IllegalArgumentException();
	    
	    // emit the negation sign and continue as if positive
	    buf[offset++] = (byte) '-';
	    src = Math.abs(src);
	}

	// iterate until there are no more digits to emit
	while (power > 0) {
	    this_digit = src / power;
	    if (this_digit != 0 || have_emitted) {
		// emit this digit
		have_emitted = true;
		buf[offset++] = charval[this_digit];
	    }
	    src = src % power;
	    power = power / 10;
	}
	return offset - init_offset;
    }


    /**
     * Work around a performance bug in String.hashCode() for strings longer
     * than sixteen characters, by calculating a (slower) hash on all the
     * characters in the string.  Not needed starting in the JDK 1.2 release.
     */
    public static int hashCode(String s)
    {
	int length = s.length();
	int h = 1;

	for (int i = 0; i < length; i++)
	    h = (h * 37) + (int) s.charAt(i);
	return h;
    }


    /**
     * Word-wrap a string into an array of strings.  Space is the only
     * separator character recognized.
     */
    public static String[] wordWrap(String msg, int widthInChars) {
	int width = widthInChars;
	int nextBreak =0;
	int lastBreak = 0;
	int length = msg.length();
	int lengthLeft = length;
	boolean breakFound = true;
	Vector v = new Vector();
	int nextNewline = msg.indexOf("\n");
	    
	while (lengthLeft > width || nextNewline != -1) {
	    // Find a convenient word break, always respecting explicit line
	    // breaks.
	    nextBreak = nextNewline;

	    // If no newline, look for a space.
	    if (nextBreak == -1 || 
		nextBreak <= lastBreak ||
		nextBreak > lastBreak + width) {
		nextBreak = msg.lastIndexOf(" ", lastBreak + width);
	    }

	    // No space, break it at the wrap width.
	    if (nextBreak == -1 || nextBreak <= lastBreak) {
		nextBreak = lastBreak + width - 1;
		breakFound = false;
		if (nextBreak > length) {
		    break;
		}
	    }

	    // Save the substring and adjust indexes.
	    String substr = msg.substring(lastBreak, nextBreak);
	    v.addElement(substr);
	    lengthLeft -= substr.length();

	    lastBreak = nextBreak;
	    if (breakFound) {
		++lastBreak;
	    }
	    breakFound = true;
	    nextNewline = msg.indexOf("\n", lastBreak);
	}

	v.addElement(msg.substring(lastBreak));
	String[] lines = new String[v.size()];
	v.copyInto(lines);
	return lines;
    }


    /**
     * Convert an array of strings to a single line with elements separated
     * by the given separator. Similar to Tcl's <code>join.
     * @param from the array of strings to convert
     * @param separator the string to insert between each element
     */
    public static String arrayToString(String[] from, String separator) {
	StringBuffer sb = new StringBuffer(100);
	String sep = "";
	for (int i = 0; i < from.length; i++) {
	   sb.append(sep);
	   sb.append(from[i]);
	   sep = separator;
	}
	return sb.toString();
    }


    /**
     * Convert a string of delimited strings to an array of strings.
     * Similar to AWK's and Tcl's <code>split.
     * @param from the string to convert
     * @param separator the delimiter
     */
    public static String[] stringToArray(String from, String separator) {
	if (from == null) {
	    return null;
	}
	if (separator == null) {
	    separator = " ";
	}
	StringTokenizer toks = new StringTokenizer(from, separator);
	String[] result = new String[toks.countTokens()];
	int i = 0;
	while (toks.hasMoreTokens()) {
	    result[i++] = toks.nextToken().trim();
	}
	return result;
    }


    /**
     * Truncate a float to the required number of significant digits.
     */
    public static String truncateFloat(float f, int digits) {
	double factor = Math.pow(10, digits);
	f = (float)(Math.round(f * factor) / factor);
	return Float.toString(f);
    }


    /**
     * Add commas to a number for "123,456.7" style formatting.
     * @deprecated Use standard java.* APIs which create the correct
     *	localized number format.
     */
    public static String addCommas(float f) {
	String floatStr = truncateFloat(f, 0);
	return addCommas(floatStr);
    }


    /**
     * Add commas to a number for "123,456.7" style formatting.
     * @deprecated Use standard java.* APIs which create the correct
     *	localized number format.
     */
    public static String addCommas(String numStr) {
	int dotIndex = numStr.lastIndexOf('.');
	String n;

	String fraction = "";
	if (dotIndex >= 0) {
	    fraction = numStr.substring(dotIndex);
	    n = numStr.substring(0, dotIndex);
	} else {
	    n = numStr;
	}

	String val = "";
	int lastIndex = 0;
	for (int i = n.length(); i > 0; i -= 3) {
	    String comma;
	    if (i > 3) {
		comma = ",";
	    } else {
		comma = "";
	    }
	    int start = Math.max(i - 3, 0);
	    val = comma + n.substring(start, i) + val;
	    lastIndex = start;
	}
	val = n.substring(0, lastIndex) + val + fraction;
	return val;
    }


    /**
     * Test if a class is a subclass of another.
     * @deprecated Use <em>sup.isAssignableFrom(sub)
     */
    public static boolean isSubclassOf(Class sub, Class sup) {
	if (sub == sup) {
	    return true;
	}
	Class superclass = sub.getSuperclass();
	while (superclass != null && superclass != sup) {
	    superclass = superclass.getSuperclass();
	}
	return (superclass != null);
    }

    /**
     * Get all super-interfaces of a class, excluding the 
     * given base interface.
     * Returns a set of strings containing class names.
     */
    public static Set getSuperInterfaces(ClassLoader cl, String className, String baseClassName) throws ClassNotFoundException {
        Set allSuper = new HashSet();
        if( !className.equals(baseClassName) ) {
            Class theClass          = cl.loadClass(className);
            Class[] superInterfaces = theClass.getInterfaces();

            for(int superIndex = 0; superIndex < superInterfaces.length; superIndex++) {
                Class currentClass      = superInterfaces[superIndex];
                String currentClassName = currentClass.getName();
                if( !currentClassName.equals(baseClassName) ) {
                    allSuper.add(currentClassName);
                    allSuper.addAll(getSuperInterfaces(cl, currentClassName, baseClassName));
                }
            } // End for -- each super interface
        }
        return allSuper;
    }

    public static Method getMethod(Class declaringClass, ClassLoader loader,
                                   String name, String[] paramClassNames)
       throws Exception
    {

        Class[] parameterTypes=null;
        if (paramClassNames!=null) {       
            parameterTypes = new Class[paramClassNames.length];
            for(int pIndex = 0; pIndex < parameterTypes.length; pIndex++) {
                String next = paramClassNames[pIndex];
                if( primitiveClasses_.containsKey(next) ) {
                    parameterTypes[pIndex] = 
                        (Class) primitiveClasses_.get(next);
                } else {
                    parameterTypes[pIndex] = Class.forName(next, true, loader);
                }
            }
        }
        return declaringClass.getMethod(name, parameterTypes);
    }

    public static Method getDeclaredMethod(Class declaringClass, ClassLoader loader,
                                   String name, String[] paramClassNames)
       throws Exception
    {

        Class[] parameterTypes=null;
        if (paramClassNames!=null) {       
            parameterTypes = new Class[paramClassNames.length];
            for(int pIndex = 0; pIndex < parameterTypes.length; pIndex++) {
                String next = paramClassNames[pIndex];
                if( primitiveClasses_.containsKey(next) ) {
                    parameterTypes[pIndex] = 
                        (Class) primitiveClasses_.get(next);
                } else {
                    parameterTypes[pIndex] = Class.forName(next, true, loader);
                }
            }
        }
        return declaringClass.getDeclaredMethod(name, parameterTypes);
    }

    /**
     * Compares the signatures of two methods to see if they
     * have the same numer of parameters and same parameter types.
     *
     * Note that this equality check does NOT cover :
     * 1) declaring class 2) exceptions 3) method name 
     * 4) return type
     *
     */
    public static boolean sameParamTypes(Method m1, Method m2) {
        boolean same = false;

        Type[] gpm1 = m1.getGenericParameterTypes();
        Type[] gpm2 = m2.getGenericParameterTypes();

        if ((gpm1.length == gpm2.length)) {
            same = true;
            for (int i = 0; i < gpm1.length; i++) {
                if (!gpm1[i].equals(gpm2[i])) {
                    if (gpm1[i] instanceof TypeVariable || gpm2[i] instanceof TypeVariable) {
                        continue;
                    } else if(gpm1[i] instanceof ParameterizedType || gpm2[i] instanceof ParameterizedType) {

                        //See issue 15595 (ClassFormatError: Duplicate method name thrown in deployment)
                        //For ParameterizedType params, compare their non-generics parameter types.
                        same = m1.getParameterTypes()[i].equals(m2.getParameterTypes()[i]);
                        if(!same) {
                            break;
                        }
                    } else {
                        same = false;
                        break;
                    }
                }
            }
        }

        return same;
    }

    /**
     * Compares the signatures of two methods to see if they
     * have the same method name, parameters, and return type.  
     *
     * Note that this equality check does NOT cover :
     * 1) declaring class 2) exceptions
     *
     */
    public static boolean sameMethodSignature(Method m1, Method m2) {
        boolean same = false;
        
        if(m1.getName().equals(m2.getName())) {
            same = sameParamTypes(m1, m2) && sameReturnTypes(m1, m2);
        }

        return same;
    }

    /**
     * Compares the return types of 2 methods.
     * @param m1 method 1
     * @param m2 method 2
     * @return true if the return types of the 2 methods are the same, or if
     * one of them is instance of java.lang.reflect.TypeVariable.
     */
    private static boolean sameReturnTypes(Method m1, Method m2) {
        if(m1.getReturnType().equals(m2.getReturnType())) {
            return true;
        }
        
        Type grt1 = m1.getGenericReturnType();
        Type grt2 = m2.getGenericReturnType();

        if(grt1.equals(grt2)) {
            return true;
        }
        if(grt1 instanceof TypeVariable || grt2 instanceof TypeVariable) {
            return true;
        }

        return false;
    }

    public static Vector getPossibleCmpCmrFields(ClassLoader cl,
                                                 String className) 
        throws Exception {

        Vector fieldDescriptors = new Vector();
        Class theClass = cl.loadClass(className);

        // Start with all *public* methods
        Method[] methods = theClass.getMethods();

        // Find all accessors that could be cmp fields. This list 
        // will contain all cmr field accessors as well, since there
        // is no good way to distinguish between the two purely based
        // on method signature.
        for(int mIndex = 0; mIndex < methods.length; mIndex++) {
            Method next = methods[mIndex];
            String nextName = next.getName();
            int nextModifiers = next.getModifiers();
            if( Modifier.isAbstract(nextModifiers) ) {
                if( nextName.startsWith("get") &&
                    nextName.length() > 3 ) {
                    String field = 
                        nextName.substring(3,4).toLowerCase() + 
                        nextName.substring(4);
                    fieldDescriptors.add(new FieldDescriptor(field));
                }
            }
        }
        return fieldDescriptors;
    }

    /**
     * Convert a java beans setter method to its property name.
     */
    public static String setterMethodToPropertyName(String setterMethodName) {

        if( (setterMethodName == null) ||
            (setterMethodName.length() <= 3) ||
            !setterMethodName.startsWith("set") ) {
            throw new IllegalArgumentException("Invalid setter method name " +
                                               setterMethodName);
        } 

        return ( setterMethodName.substring(3, 4).toLowerCase() +
                 setterMethodName.substring(4) );

    }

    /**
     * Convert a java beans property name to a setter method name
     */
    public static String propertyNameToSetterMethod(String propertyName) {

        if( (propertyName == null) ||
            (propertyName.length() == 0) ) {
            throw new IllegalArgumentException("Invalid property name " +
                                               propertyName);
        } 

        return ( "set" + propertyName.substring(0, 1).toUpperCase() +
                 propertyName.substring(1) );

    }
    
   /**
    * Convert String array of class names into array of Classes.
    */
    public static Class[] paramClassNamesToTypes(String[] paramClassNames, 
            ClassLoader loader) throws Exception {

        Class[] parameterTypes = null;
        if (paramClassNames != null) {
            parameterTypes = new Class[paramClassNames.length];
            for(int pIndex = 0; pIndex < parameterTypes.length; pIndex++) {
                String next = paramClassNames[pIndex];
                if( primitiveClasses_.containsKey(next) ) {
                    parameterTypes[pIndex] =
                        (Class) primitiveClasses_.get(next);
                } else {
                    parameterTypes[pIndex] = Class.forName(next, true, loader);
                }
            }
        }

        return parameterTypes;
    }
}

Other Glassfish examples (source code examples)

Here is a short list of links related to this Glassfish TypeUtil.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.