View Javadoc

1   /*
2    * Copyright 2007 The International Moth Class Association (IMCA)
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 net.sf.imca.services;
17  
18  import java.lang.reflect.InvocationTargetException;
19  import java.lang.reflect.Method;
20  import java.lang.reflect.Constructor;
21  import java.util.ArrayList;
22  import java.util.Collection;
23  import java.util.Vector;
24  import java.util.Hashtable;
25  
26  /**
27   * Utilities for common reflection tasks.
28   *
29   * @author dougculnane
30   */
31  public class ReflectionUtil {
32  
33      public static final Object[] NO_PARAMS = new Object[] {};
34  
35      public static final String ENTITY = "Entity";
36  
37      private static final String GET = "get";
38  
39      private static final String SET = "set";
40  
41      private static final String ID = "Id";
42  
43      private static final String CLASS = "Class";
44  
45      @SuppressWarnings("unchecked")
46      public static void replaceDBObject(Object dbObject, Object newObject)
47              throws Exception {
48  
49          Method[] methods = newObject.getClass().getMethods();
50  
51          for (int i = 0; i < methods.length; i++) {
52              if (methods[i].getName().startsWith(GET)) {
53                  String methodName = methods[i].getName().substring(3);
54                  if (!(ID.equals(methodName) || CLASS.equals(methodName))) {
55  
56                      Class dataType = methods[i].getReturnType();
57                      Object value = methods[i].invoke(newObject, NO_PARAMS);
58                      Method dbObjectMethod = dbObject.getClass().getMethod(
59                              SET + methodName, dataType);
60  
61                      dbObjectMethod.invoke(dbObject, value);
62                  }
63              }
64          }
65  
66      }
67  
68      @SuppressWarnings("unchecked")
69      public static void mergeDBObject(Object dbObject, Object newObject)
70              throws Exception {
71  
72          Method[] methods = newObject.getClass().getMethods();
73  
74          for (int i = 0; i < methods.length; i++) {
75              if (methods[i].getName().startsWith(GET)) {
76                  String setterName = methods[i].getName().substring(3);
77                  if (!ID.equals(setterName)) {
78  
79                      Class dataType = methods[i].getReturnType();
80                      Object value = methods[i].invoke(newObject, NO_PARAMS);
81                      if (value != null) {
82                          if (!"".equals(value)) {
83                              Method dbObjectMethod = dbObject.getClass()
84                                      .getMethod(SET + setterName, dataType);
85                              dbObjectMethod.invoke((new Object[] { dataType }),
86                                      value);
87                          }
88                      }
89  
90                  }
91              }
92          }
93      }
94  
95      @SuppressWarnings("unchecked")
96      public static Object getObject(String className)
97              throws ClassNotFoundException, SecurityException,
98              NoSuchMethodException, IllegalArgumentException,
99              InstantiationException, IllegalAccessException,
100             InvocationTargetException {
101 
102         Class clazz = ReflectionUtil.class.getClassLoader()
103                 .loadClass(className);
104 
105         Constructor constructor = clazz.getConstructor();
106         Object object = constructor.newInstance();
107 
108         return object;
109     }
110 
111     public static String[] getSetMethodNames(Object entity) {
112         return getMethodNamesStartingWith(entity, SET);
113     }
114 
115     public static String[] getGetMethodNames(Object entity) {
116         return getMethodNamesStartingWith(entity, GET);
117     }
118 
119     private static String[] getMethodNamesStartingWith(Object entity,
120             String startingWith) {
121         Method[] methods = entity.getClass().getMethods();
122         Vector<String> methodVec = new Vector<String>();
123 
124         for (int i = 0; i < methods.length; i++) {
125             if (methods[i].getName().startsWith(startingWith)) {
126                 methodVec.add(methods[i].getName());
127             }
128         }
129         String[] methodNames = new String[methodVec.size()];
130         for (int i = 0; i < methodNames.length; i++) {
131             methodNames[i] = methodVec.get(i);
132         }
133 
134         return methodNames;
135     }
136 
137     @SuppressWarnings("unchecked")
138     public static void setEntityValuesFromParameterMap(Object entity,
139             Hashtable<String, String> parameterMap) throws SecurityException,
140             NoSuchMethodException, IllegalArgumentException,
141             IllegalAccessException, InvocationTargetException, ClassNotFoundException, InstantiationException {
142 
143         String[] setMethodNames = ReflectionUtil.getSetMethodNames(entity);
144         for (int i = 0; i < setMethodNames.length; i++) {
145             EditDataService service = new EditDataService();
146             String value = parameterMap.get(setMethodNames[i].substring(3));
147 
148             if (value != null) {
149 
150                 if ((SET + ID).equals(setMethodNames[i])) {
151                     if (value != null && "".equals(value)) {
152                         Method setMedthod = entity.getClass().getMethod(
153                                 SET + ID, int.class);
154                         setMedthod
155                                 .invoke(entity, new Long(value).longValue());
156                     }
157                 } else {
158                     Method getMethod = entity.getClass().getMethod(
159                             GET + setMethodNames[i].substring(3));
160                     
161                     Class dataType = getMethod.getReturnType();
162                     Method setMethod = entity.getClass().getMethod(
163                             setMethodNames[i], dataType);
164                     
165                     if ("java.lang.String".equals(dataType.getName())) {
166                         setMethod.invoke(entity, value);
167                     } else if ("boolean".equals(dataType.getName())) {
168                         try {
169                             Boolean bol = new Boolean(value);
170                             setMethod.invoke(entity, bol.booleanValue());
171                         } catch (Exception formatEx) {
172                             // TODO: handle boolean Format error
173                         }
174                     } else if ("int".equals(dataType.getName())) {
175                         try {
176                             Long id = new Long(value);
177                             setMethod.invoke(entity, id.longValue());
178                         } catch (NumberFormatException nfe) {
179                             // TODO: handle Number Format error
180                         }
181                     } else if ("double".equals(dataType.getName())) {
182                         try {
183                             Double d = new Double(value);
184                             setMethod.invoke(entity, d.doubleValue());
185                         } catch (NumberFormatException nfe) {
186                             // TODO: handle Number Format error
187                         }
188                     } else if (dataType.getName().endsWith(ENTITY)) {
189                         if (value.length() > 0) {
190                             Object childEntity = service.findEntity(dataType, new Long(value.trim()).longValue());
191                             setMethod.invoke(entity, childEntity);
192                         }
193                     } else if ("java.util.Collection".equals(dataType.getName())) {
194                         String temp = setMethod.getGenericParameterTypes()[0].toString();
195                         String entityClassName = temp.substring(temp.indexOf("<") + 1, temp.indexOf(">"));
196                         String[] values = value.split(",");
197                         Collection<Object> children = new Vector<Object>();
198                         for (int j=0; j < values.length; j++){
199                             if (values[j].trim().length() > 0) {
200                                 Object childEntity = service.findEntity(getObject(entityClassName).getClass(), new Long(values[j].trim()).longValue());
201                                 children.add(childEntity);
202                             }
203                         }
204                         setMethod.invoke(entity, children);
205                     } else {
206                         // This should never happen.
207                         System.out.println("WARN " + dataType + ": " + value);
208                     }
209                 }
210             }
211         }
212     }
213 
214     public static Vector<Object> getChildEntities(Object dbObject)
215             throws IllegalArgumentException, SecurityException,
216             IllegalAccessException, InvocationTargetException,
217             NoSuchMethodException {
218 
219         String[] getMethodNames = ReflectionUtil.getGetMethodNames(dbObject);
220         Vector<Object> entities = new Vector<Object>();
221 
222         for (int i = 0; i < getMethodNames.length; i++) {
223             if (!(GET + CLASS).equals(getMethodNames[i])) {
224                 Method method = dbObject.getClass()
225                         .getMethod(getMethodNames[i]);
226                 if (method.getReturnType().getName().endsWith(ENTITY)) {
227                     entities.add(method.invoke(dbObject, NO_PARAMS));
228                 }
229             }
230         }
231 
232         return entities;
233     }
234 
235     /*
236      * http://forum.java.sun.com/thread.jspa?threadID=341935&tstart=0
237      */
238     @SuppressWarnings("unchecked")
239     public static ArrayList<Class> getClasses(String packageName)
240             throws ClassNotFoundException {
241         
242         ArrayList<Class> classes = new ArrayList<Class>();
243         // Get a File object for the package
244         java.io.File directory = null;
245         try {
246             ClassLoader cld = Thread.currentThread().getContextClassLoader();
247             if (cld == null) {
248                 throw new ClassNotFoundException("Can't get class loader.");
249             }
250             String path = '/' + packageName.replace('.', '/');
251             java.net.URL resource = cld.getResource(path);
252             if (resource == null) {
253                 throw new ClassNotFoundException("No resource for " + path);
254             }
255             directory = new java.io.File(resource.getFile());
256         } catch (NullPointerException x) {
257             throw new ClassNotFoundException(packageName + " (" + directory
258                     + ") does not appear to be a valid package");
259         }
260         if (directory.exists()) {
261             // Get the list of the files contained in the package
262             String[] files = directory.list();
263             for (int i = 0; i < files.length; i++) {
264                 // we are only interested in .class files
265                 if (files[i].endsWith(".class")) {
266                     // removes the .class extension
267                     classes.add(Class.forName(packageName + '.'
268                             + files[i].substring(0, files[i].length() - 6)));
269                 }
270             }
271         } else {
272             throw new ClassNotFoundException(packageName
273                     + " does not appear to be a valid package");
274         }
275         //Class[] classesA = new Class[classes.size()];
276         //classes.toArray(classesA);
277         return classes;
278     }
279 
280     public static String getEntityId(Object entity) 
281             throws SecurityException, NoSuchMethodException, 
282             IllegalArgumentException, IllegalAccessException, 
283             InvocationTargetException {
284         Method getIdMethod = entity.getClass().getMethod("getId");
285         getIdMethod.invoke(entity, NO_PARAMS);
286         return getIdMethod.invoke(entity, NO_PARAMS).toString();
287     }
288 }