View Javadoc

1   /*
2    * Copyright 2000-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.portals.graffito.jcr.reflection;
17  
18  import java.lang.reflect.InvocationTargetException;
19  
20  import net.sf.cglib.proxy.Enhancer;
21  
22  import org.apache.commons.beanutils.ConstructorUtils;
23  import org.apache.commons.beanutils.PropertyUtils;
24  import org.apache.portals.graffito.jcr.exception.JcrMappingException;
25  
26  
27  /***
28   * Utility class for handling reflection using BeanUtils.
29   * 
30   * @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a>
31   */
32  abstract public class ReflectionUtils {
33      
34      // default the class loader to the load of this class
35      private static ClassLoader classLoader = ReflectionUtils.class.getClassLoader();
36      
37      /***
38       * Sets the class loader to use in the {@link #forName(String)} method to
39       * load classes.
40       * <p>
41       * Care must be taken when using this method as when setting an improperly
42       * set up classloader, the mapper will not work again throwing tons of
43       * exceptions.
44       * 
45       * @param newClassLoader The new class loader to use. This may be
46       *      <code>null</code> in which case the system class loader will be used.
47       */
48      public static void setClassLoader(ClassLoader newClassLoader) {
49          classLoader = newClassLoader;
50      }
51      
52      /***
53       * Returns the class loader which is used by the {@link #forName(String)}
54       * method to load classes.
55       * 
56       * @return The class loader used by {@link #forName(String)} or
57       *      <code>null</code> if the system class loader is used.
58       */
59      public static ClassLoader getClassLoader() {
60          return classLoader;
61      }
62      
63      public static Object getNestedProperty(Object object, String fieldName) {
64          if (null == object) {
65              return null;
66          }
67          
68          try {
69              return PropertyUtils.getNestedProperty(object, fieldName);
70          }
71          catch(IllegalAccessException e) {
72              throw new JcrMappingException("Cannot access property "
73                      + fieldName,
74                      e);
75          }
76          catch(InvocationTargetException e) {
77              throw new JcrMappingException("Cannot access property "
78                      + fieldName,
79                      e);
80          }
81          catch(NoSuchMethodException e) {
82              throw new JcrMappingException("Cannot access property "
83                      + fieldName,
84                      e);
85          }
86      }
87      
88      public static Class getPropertyType(Object object, String fieldName) {
89          try {
90              return PropertyUtils.getPropertyType(object, fieldName);
91          }
92          catch(Exception ex) {
93              throw new JcrMappingException("Cannot access property "
94                      + fieldName,
95                      ex);
96          }
97      }
98  
99      public static Object newInstance(Class clazz) {
100         try {
101             return clazz.newInstance();
102         }
103         catch(Exception ex) {
104             throw new JcrMappingException("Cannot create instance for class "
105                     + clazz,
106                     ex);
107         }
108     }
109     
110     /***
111      * @param className
112      * @param objects
113      * @return
114      */
115     public static Object  invokeConstructor(String className,  Object[] params) {
116         try {
117             Class converterClass= forName(className);
118     
119             return  ConstructorUtils.invokeConstructor(converterClass, params);
120         }
121         catch(Exception ex) {
122             throw new JcrMappingException("Cannot create instance for class "  + className,  ex);
123         }
124     }
125 
126     /***
127      * @param object
128      * @param fieldName
129      * @param path
130      */
131     public static void setNestedProperty(Object object, String fieldName, Object value) {
132         try {
133             PropertyUtils.setNestedProperty(object, fieldName, value);
134         }
135         catch(Exception ex) {
136             throw new JcrMappingException("Cannot set the field " + fieldName + " in the class : " + object.getClass().toString(),
137                     ex);
138         }
139     }
140 
141     /***
142      * @param string
143      * @return
144      */
145     public static Object newInstance(String clazz) {
146         try {
147             return forName(clazz).newInstance();
148         }
149         catch(Exception ex) {
150             throw new JcrMappingException("Cannot create instance for class "  + clazz, ex);
151         }
152     }
153 
154     /***
155      * @param elementClassName
156      * @return
157      */
158     public static Class forName(String clazz) {
159         try {
160             return Class.forName(clazz, true, getClassLoader());
161         }
162         catch(Exception ex) {
163             throw new JcrMappingException("Cannot load class " + clazz, ex);
164         }
165     }
166     
167     public static boolean isProxy(Class beanClass)
168     {    	        	     
169          return Enhancer.isEnhanced(beanClass);	
170     }
171     
172     public static Class getBeanClass(Object bean)
173     {
174     	     Class beanClass = bean.getClass();
175          if (isProxy(beanClass))
176          {
177         	     //CGLIB specific
178         	 	return beanClass.getSuperclass();
179          }
180          return beanClass;
181     }
182     
183 }