View Javadoc
1   package net.trajano.commons.testing;
2   
3   import java.lang.reflect.Constructor;
4   import java.lang.reflect.Method;
5   import java.lang.reflect.Modifier;
6   import java.text.MessageFormat;
7   import java.util.ResourceBundle;
8   
9   /**
10   * This provides a test to check certain properties of a utility class.
11   * Primarily that it has only one private constructor and no non-static methods
12   * and it is final.
13   *
14   * @author Archimedes Trajano
15   */
16  public final class UtilityClassTestUtil {
17  
18      /**
19       * Resource bundle.
20       */
21      private static final ResourceBundle R = ResourceBundle.getBundle("META-INF.Messages");
22  
23      /**
24       * A utility class class is well defined if it is final and there is one and
25       * only one declared constructor.
26       *
27       * @param clazz
28       *            class to evaluate
29       */
30      private static void assertUtilityClassClassWellDefined(final Class<?> clazz) {
31  
32          if (!Modifier.isFinal(clazz.getModifiers())) {
33              throw new AssertionError(MessageFormat.format(R.getString("UtilityClassTestUtil.notFinal"), //$NON-NLS-1$
34                      clazz));
35          }
36          if (clazz.getDeclaredConstructors().length != 1) {
37              throw new AssertionError(MessageFormat.format(R.getString("UtilityClassTestUtil.notOneConstructor"), //$NON-NLS-1$
38                      clazz));
39          }
40      }
41  
42      /**
43       * A utility class constructor is well defined if it is private.
44       *
45       * @param constructor
46       *            constructor
47       * @throws ReflectiveOperationException
48       *             when there is a problem performing reflection on the class.
49       */
50      private static void assertUtilityClassConstructorWellDefined(final Constructor<?> constructor) throws ReflectiveOperationException {
51  
52          if (constructor.isAccessible() || !Modifier.isPrivate(constructor.getModifiers())) {
53              throw new AssertionError(MessageFormat.format(R.getString("UtilityClassTestUtil.constructorNotPrivate"), //$NON-NLS-1$
54                      constructor));
55          }
56          constructor.setAccessible(true);
57          constructor.newInstance();
58          constructor.setAccessible(false);
59      }
60  
61      /**
62       * Methods of a utility class should be static if it was defined on the
63       * class itself.
64       *
65       * @param clazz
66       *            class to evaluate
67       */
68      private static void assertUtilityClassMethodsWellDefined(final Class<?> clazz) {
69  
70          for (final Method method : clazz.getMethods()) {
71              if (!Modifier.isStatic(method.getModifiers()) && method.getDeclaringClass()
72                      .equals(clazz)) {
73                  throw new AssertionError(MessageFormat.format(R.getString("UtilityClassTestUtil.methodNotStatic"), //$NON-NLS-1$
74                          method));
75              }
76          }
77      }
78  
79      /**
80       * Verifies that a utility class is well defined.
81       *
82       * @param clazz
83       *            utility class to verify.
84       * @throws ReflectiveOperationException
85       *             problem accessing the class or its elements using reflection.
86       */
87      public static void assertUtilityClassWellDefined(final Class<?> clazz) throws ReflectiveOperationException {
88  
89          assertUtilityClassClassWellDefined(clazz);
90          final Constructor<?> constructor = clazz.getDeclaredConstructor();
91          assertUtilityClassConstructorWellDefined(constructor);
92          assertUtilityClassMethodsWellDefined(clazz);
93      }
94  
95      /**
96       * Prevent instantiation of utility class.
97       */
98      private UtilityClassTestUtil() {
99  
100     }
101 }