View Javadoc

1   /*
2    * Created on May 18, 2005
3    *
4    * Provides a set of static utility methods for working with Classes
5    */
6   package net.sf.tlc.util;
7   
8   import java.lang.reflect.Method;
9   import java.lang.reflect.Modifier;
10  import java.util.ArrayList;
11  import java.util.Arrays;
12  import java.util.HashSet;
13  import java.util.Iterator;
14  import java.util.List;
15  import java.util.Set;
16  
17  /***
18   * Provides a set of static utility methods for working with Classes
19   * 
20   * @author aisrael
21   */
22  public final class ClassUtils {
23  
24      /***
25       * ClassUtils instances should NOT be constructed in standard programming.
26       */
27      private ClassUtils() {
28          // noop
29      }
30  
31      /***
32       * @param name
33       *            method name (e.g., "getProperty")
34       * @return friendly property name (e.g., "property")
35       */
36      private static String getBeanPropertyName(final String name) {
37          final String result;
38  
39          if (name.startsWith("get")) {
40              result = name.substring(3, 4).toLowerCase() + name.substring(4, name.length());
41          } else {
42              result = name;
43          }
44  
45          return result;
46      }
47  
48      /***
49       * Return a 'friendly-name' list of public JavaBean 'properties' - that is,
50       * all accessor methods of the form getAbc() with the 'get' removed and the
51       * first letter of the 'property' converted to lower case.
52       * 
53       * @param c
54       *            Class
55       * @return an array of friendly property names (String[])
56       */
57      public static String[] listBeanProperties(final Class c) {
58          final List properties = new ArrayList();
59  
60          final Method[] methods = c.getMethods();
61          for (int i = 0; i < methods.length; ++i) {
62              final Method method = methods[i];
63              final String methodName = method.getName();
64  
65              if (Modifier.isPublic(method.getModifiers()) && methodName.startsWith("get")
66                      && method.getParameterTypes().length == 0) {
67                  if (methodName != "getClass") {
68                      properties.add(getBeanPropertyName(methodName));
69                  }
70              }
71          }
72  
73          return (String[]) properties.toArray(new String[0]);
74      }
75  
76      /***
77       * List all interfaces implemented by the given class
78       * 
79       * @param c
80       *            Class
81       * @return List of all interfaces (Class) implemented by the class
82       */
83      public static List listAllInterfaces(final Class c) {
84          final Set interfaces = new HashSet();
85          interfaces.addAll(Arrays.asList(c.getInterfaces()));
86          final List superClasses = listAllSuperClasses(c);
87          for (final Iterator i = superClasses.iterator(); i.hasNext();) {
88              final Class d = (Class) i.next();
89              final Class[] di = d.getInterfaces();
90              if (null != di && 0 != di.length) {
91                  interfaces.addAll(Arrays.asList(di));
92              }
93          }
94          return Arrays.asList(interfaces.toArray(new Class[0]));
95      }
96  
97      /***
98       * Returns a List of all super classes of the given class
99       * 
100      * @param c
101      *            Class
102      * @return a List of all super classes of the given class
103      */
104     public static List listAllSuperClasses(final Class c) {
105         final List supers = new ArrayList();
106         Class x = c.getSuperclass();
107         while (null != x && Object.class != x) {
108             supers.add(x);
109             x = x.getSuperclass();
110         }
111         return supers;
112     }
113 
114     /***
115      * Return true if the given class implements the Runnable interface
116      * 
117      * @param c
118      *            Class
119      * @return true if the give class implements the Runnable interface
120      */
121     public static boolean isRunnable(final Class c) {
122         return listAllInterfaces(c).contains(Runnable.class);
123     }
124 
125     /***
126      * Return true if the given class is abstract
127      * 
128      * @param c
129      *            Class
130      * @return true if the given class is abstract
131      */
132     public static boolean isAbstractClass(final Class c) {
133         return Modifier.isAbstract(c.getModifiers());
134     }
135 
136     /***
137      * Return true if Class c is as subclass of parent
138      * 
139      * @param c
140      *            Class under test
141      * @param parent
142      *            parent Class
143      * @return true if Class c is as subclass of parent
144      */
145     public static boolean doesExtend(final Class c, final Class parent) {
146         return listAllSuperClasses(c).contains(parent);
147     }
148 
149     /***
150      * @param c
151      *            Class under test
152      * @param iface
153      *            an interface
154      * @return true if Class c implements iface
155      */
156     public static boolean doesImplement(final Class c, final Class iface) {
157         return listAllInterfaces(c).contains(iface);
158     }
159 
160     /***
161      * @param c Class
162      * @return friendly class name (e.g., "byte[]" or "java.lang.String")
163      */
164     public static String getFriendlyClassName(final Class c) {
165         if (c.isArray()) {
166             return c.getComponentType().getName() + "[]";
167         } else {
168             return c.getName();
169         }
170     }
171 
172 }