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", "enum",
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 }