001    package com.mockrunner.util.common;
002    
003    import java.util.ArrayList;
004    import java.util.Collections;
005    import java.util.List;
006    
007    public class ClassUtil
008    {
009        private final static String[] KEYWORDS = new String[]
010        {
011            "abstract", "assert", "boolean", "break", "byte",
012            "case", "catch", "char", "class", "const",
013            "continue", "default", "do", "double", "else",
014            "extends", "final", "finally", "float", "for",
015            "goto", "if", "implements", "import", "instanceof",
016            "int", "interface", "long", "native", "new",
017            "package", "private", "protected", "public", "return",
018            "short", "static", "strictFP", "super", "switch",
019            "synchronized", "this", "throw", "throws", "transient",
020            "try", "void", "volatile", "while"
021        };
022        
023        /**
024         * Returns the name of the package of the specified class.
025         * If the class has no package, an empty String will be
026         * returned.
027         * @param clazz the Class
028         * @return the package name
029         */
030        public static String getPackageName(Class clazz)
031        {
032            Package classPackage = clazz.getPackage();
033            if(null == classPackage) return "";
034            return classPackage.getName();
035        }
036        
037        /**
038         * Returns the name of the specified class. This method
039         * only returns the class name without package information.
040         * If the specified class represents a primitive type, the
041         * name of the primitive type will be returned. If the
042         * specified class is an array, <code>[]</code> will be
043         * appended to the name (once for each dimension).
044         * @param clazz the Class
045         * @return the class name
046         */
047        public static String getClassName(Class clazz)
048        {
049            String dimensions = "";
050            while(clazz.isArray())
051            {
052                clazz = clazz.getComponentType();
053                dimensions += "[]";
054            }
055            String classPackage = getPackageName(clazz);
056            if(classPackage.length() == 0)
057            {
058                return clazz.getName() + dimensions;
059            }
060            else
061            {
062                return clazz.getName().substring(classPackage.length() + 1) + dimensions;
063            }
064        }
065        
066        /**
067         * Returns the inheritance hierarchy of the specified class.
068         * The returned array includes all superclasses of the specified class
069         * starting with the most general superclass, which is
070         * <code>java.lang.Object</code>. The returned array also
071         * includes the class itself as the last element. Implemented
072         * interfaces are not included.
073         * @param clazz the Class
074         * @return all superclasses, most general superclass first
075         */
076        public static Class[] getInheritanceHierarchy(Class clazz)
077        {
078            List classes = new ArrayList();
079            Class currentClass = clazz;
080            while(null != currentClass)
081            {
082                classes.add(currentClass);
083                currentClass = currentClass.getSuperclass();
084            }
085            Collections.reverse(classes);
086            return (Class[])classes.toArray(new Class[classes.size()]);
087        }
088        
089        /**
090         * Returns if the specified string is a Java language
091         * keyword.
092         * @param name the string
093         * @return <code>true</code> if it is a keyword,
094         *         <code>false</code> otherwise
095         */
096        public static boolean isKeyword(String name)
097        {
098            for(int ii = 0; ii < KEYWORDS.length; ii++)
099            {
100                if(KEYWORDS[ii].equals(name)) return true;
101            }
102            return false;
103        }
104        
105        /**
106         * Returns a suitable argument name for arguments
107         * of type <code>argumentType</code>. Simply takes
108         * the class name and converts the starting characters
109         * to lower case (by preserving one upper case character).
110         * E.g. the result of <code>JMSTestModule</code> is
111         * <code>jmsTestModule</code>.
112         * If the specified <code>argumentType</code> is an array,
113         * an <code>"s"</code> is appended to the string.
114         * If the resulting string is a Java keyword, <code>"Value"</code> 
115         * is appended to the string (which is always the case with
116         * primitive types).
117         * @param argumentType the argument type
118         * @return a suitable mixed case argument name
119         */
120        public static String getArgumentName(Class argumentType)
121        {
122            String dimensions = "";
123            while(argumentType.isArray())
124            {
125                argumentType = argumentType.getComponentType();
126                dimensions = "s";
127            }
128            String name = getClassName(argumentType);
129            int index = 0;
130            while(index < name.length() - 1 && Character.isUpperCase(name.charAt(index)) && Character.isUpperCase(name.charAt(index + 1)))
131            {
132                index++;
133            }
134            if(index == name.length() - 1)
135            {
136                index++;
137            }
138            name = StringUtil.lowerCase(name, 0, index);
139            if(isKeyword(name))
140            {
141                 name += "Value";
142            }
143            name += dimensions;
144            return name;
145        }
146    }