View Javadoc

1   package com.zmicer.utils;
2   
3   import org.apache.log4j.Logger;
4   import sun.reflect.Reflection;
5   
6   import java.util.HashMap;
7   import java.util.Map;
8   import java.util.StringTokenizer;
9   import java.util.regex.Pattern;
10  
11  /**
12   * Utility class for working with reflexion mechanism
13   * <p/>
14   * $Author:: zmicer             $<br/>
15   * $Rev:: 67                    $<br/>
16   * $Date:: 2007-08-28 21:37:07 #$<br/>
17   */
18  public class ReflexionUtils
19  {
20      /**
21       * Logger instance.
22       */
23      final public static Logger LOG = Logger.getLogger(ZmicerUtilsConstants.LoggingCategory.REFLEXION.toString());
24  
25      /**
26       * Pattern to find the name of the method is currently running.
27       */
28      final public static Pattern PATTERN = Pattern.compile("\\.([a-zA-Z0-9_]*)\\(.*\r\n.*invoke0");
29  
30      /**
31       * Get the instance of Object using the provided full class name.
32       * <br/>
33       * All the exception may appear during reflexion are catched and logged. In this case <code>null</code> is returned.
34       *
35       * @param className             the full class name ro be reflected, Can not be null (otherwise <code>IllegalArgumentException</code> would appear).
36       * @param throwIfNotInitialized if this is true we throw exception (IllegalStateException) if some implementations can not be
37       *                              instantiated
38       *
39       * @return Object, reflected object
40       */
41      public static Object reflectObject(final String className, boolean throwIfNotInitialized)
42      {
43          InputArgumentUtils.checkStrings(true, className);
44          try
45          {
46              return ReflexionUtils.class.getClassLoader().loadClass(className).newInstance();
47          }
48          catch (Throwable t)
49          {
50              final String message = "Can not instantiate the class instance using the provided " +
51                      "name: [" + className + "]; reason: "+t.getMessage()+"";  //with "getMessage()" reason more clear (:    
52              LoggingUtils.logException(LOG, t, message, ReflexionUtils.class);
53              if (throwIfNotInitialized)
54              {
55                  throw new IllegalStateException(message);
56              }
57          }
58          return null;
59      }
60  
61      /**
62       * Get the instance of Object using the provided full class name.
63       * <br/>
64       * All the exception may appear during reflexion are catched and logged. In this case <code>null</code> is returned as the value.
65       *
66       * @param info                  the map with #key type of the object to be reflected #value. Can not contains null as neither key or value
67       *                              Can not be null (otherwise <code>IllegalArgumentException</code> would appear).
68       * @param throwIfNotInitialized if this is true we throw exception (IllegalStateException) if some implementations can not be
69       *                              instantiated
70       *
71       * @return map of the relflected objects with the appropaite keys
72       */
73      public static Map<String, Object> reflectObjects(final Map<String, String> info, final boolean throwIfNotInitialized)
74      {
75          InputArgumentUtils.checkObjects(info);
76          final Map<String, Object> result = new HashMap<String, Object>();
77          for (String key : info.keySet())
78          {
79              try
80              {
81                  if (org.apache.commons.lang.StringUtils.isBlank(key) || org.apache.commons.lang.StringUtils.isBlank(info.get(key)))
82                  {
83                      final String message = "The map provided can not contains blank key and values. key [" + key + "], value [" +
84                          info.get(key) + "]";
85                      LoggingUtils.error(LOG, ReflexionUtils.class, message);
86                      throw new IllegalArgumentException(message);
87                  }
88                  result.put(key, ReflexionUtils.class.getClassLoader().loadClass(info.get(key)).newInstance());
89              }
90              catch (Throwable t)
91              {
92                  final String message = "Can not instantiate the class instance using the provided name: [" + info.get(key) + "]";
93                  LoggingUtils.logException(LOG, t, message, ReflexionUtils.class);
94                  if (throwIfNotInitialized)
95                  {
96                      throw new IllegalStateException(message);
97                  }
98                  result.put(key, null);
99              }
100         }
101         return result;
102     }
103 
104     /**
105      * Get the base name of the provided String -  the name of the class.
106      *
107      * @param claz <code>Class</code> instance. Can not be null (otherwise <code>IllegalArgumentException</code> would appear).
108      *
109      * @return String, the base name of the class (without the packages pathes)
110      */
111     public static String getBaseName(final Class claz)
112     {
113         if (null == claz || null == claz.getName())
114         {
115             throw new IllegalArgumentException("The class and class name can not be null.");
116         }
117         final StringTokenizer tokenizer = new StringTokenizer(claz.getName(), ".");
118         String result = null;
119         while (tokenizer.hasMoreTokens())
120         {
121             result = tokenizer.nextToken();
122         }
123         return result;
124     }
125 
126     /**
127      * Get the full name of the class from instances of which the certain array object class of which is passed as the single input param.
128      * <p/>
129      * todo [zmicer]: please clarify if this method to determine this full class name is correct for another versions of Java JDK. May be
130      * there are another ways to clarify this.
131      * <p/>
132      * Example: imagine we have the array of the {@link Global} object. This appropriate class for this array would have the name
133      * "[Lcom.sourceforge.jpatterns.schema.Global;", and String we need is "com.sourceforge.jpatterns.schema.Global".
134      *
135      * @param claz Class of an array for which we need to determine the class of the objects this array stores.
136      *             Can not be null (otherwise <code>IllegalArgumentException</code> would appear).
137      *             In the case the class provided do not correspond to the array of objects the IllegalArgumentException would appear too.
138      *
139      * @return String, the full name of class instances of which are the members of the array class of which is passed to this method.
140      */
141     public static String getClassNameOfArrayMembers(final Class claz)
142     {
143         InputArgumentUtils.checkObjects(claz);
144         final String prefix = "[L";
145         final String postfix = ";";
146         if (!claz.getName().startsWith(prefix) || !claz.getName().endsWith(postfix))
147         {
148             LoggingUtils.debug(LOG, ReflexionUtils.class, "Incorrect name of the class corresponding to the array of objects was " +
149                 "provided: class name [" + claz.getName() + "]");
150             throw new IllegalArgumentException("Please provide the correct class corresponding to the array of objects.");
151         }
152         return claz.getName().substring(prefix.length(), claz.getName().length() - postfix.length());
153     }
154 
155     /**
156      * note [zmicer]: only for the test purposes (for JPatterns test engine allowing to setup the props/xml environment per the folders)
157      *
158      * @return the caller class full name.
159      */
160     public static String getCallerFullClassName()
161     {
162         return Reflection.getCallerClass(MagicNumbers.THREE).getName();
163     }
164 
165     /**
166      * Analog of the instance of construction (e.g. obj instanceof Serializable)
167      *
168      * @param obj       object to be checked. Can not be null (otherwise <code>IllegalArgumentException</code> would appear).
169      * @param baseClass base class (interface class) which should be used for the determining if obj is instace of this class
170      *                  Can not be null (otherwise <code>IllegalArgumentException</code> would appear).
171      *
172      * @return the true if this is "instance of" of the provided class (it is called base class here)
173      */
174     public static boolean instanceOf(final Object obj, Class<?> baseClass)
175     {
176         InputArgumentUtils.checkObjects(obj, baseClass);
177         return baseClass.isAssignableFrom(obj.getClass());
178     }
179 
180 }