KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > util > xml > confix > ReflectionFactory


1 package org.sapia.util.xml.confix;
2
3 import java.lang.reflect.InvocationTargetException JavaDoc;
4
5 // Import of Sun's JDK classes
6
// ---------------------------
7
import java.lang.reflect.Method JavaDoc;
8
9 import java.util.ArrayList JavaDoc;
10 import java.util.Iterator JavaDoc;
11 import java.util.List JavaDoc;
12
13
14 /**
15  * This class instantiates objects based on the name of XML elements, using these
16  * names to dynamically find the class of the objects to instantiate.
17  *
18  * @author Yanick Duchesne
19  *
20  * <dl>
21  * <dt><b>Copyright:</b><dd>Copyright &#169; 2002-2003 <a HREF="http://www.sapia-oss.org">Sapia Open Source Software</a>. All Rights Reserved.</dd></dt>
22  * <dt><b>License:</b><dd>Read the license.txt file of the jar or visit the
23  * <a HREF="http://www.sapia-oss.org/license.html">license page</a> at the Sapia OSS web site</dd></dt>
24  * </dl>
25  */

26 public class ReflectionFactory implements ObjectFactoryIF {
27   /////////////////////////////////////////////////////////////////////////////////////////
28
///////////////////////////////// INSTANCE ATTRIBUTES /////////////////////////////////
29
/////////////////////////////////////////////////////////////////////////////////////////
30

31   /** The list of packages from which to use reflection. */
32   private List JavaDoc _thePackages;
33
34   /////////////////////////////////////////////////////////////////////////////////////////
35
//////////////////////////////////// CONSTRUCTORS /////////////////////////////////////
36
/////////////////////////////////////////////////////////////////////////////////////////
37

38   /**
39    * Creates a new ReflectionFactory instance with the arguments passed in.
40    *
41    * @param somePackages The package from which to use reflection.
42    */

43   public ReflectionFactory(String JavaDoc[] somePackages) {
44     _thePackages = new ArrayList JavaDoc();
45
46     for (int i = 0; i < somePackages.length; i++) {
47       _thePackages.add(somePackages[i]);
48     }
49   }
50
51   /////////////////////////////////////////////////////////////////////////////////////////
52
/////////////////////////////////// STATIC METHODS ////////////////////////////////////
53
/////////////////////////////////////////////////////////////////////////////////////////
54

55   /**
56    * Utility to change the first letter of the string passed in to uppercase.
57    *
58    * @return The new string with the first letter in uppercase.
59    */

60   public static String JavaDoc firstToUpper(String JavaDoc aString) {
61     StringBuffer JavaDoc aBuffer = new StringBuffer JavaDoc();
62
63     for (int i = 0; i < aString.length(); i++) {
64       if (i == 0) {
65         aBuffer.append(Character.toUpperCase(aString.charAt(i)));
66       } else {
67         aBuffer.append(aString.charAt(i));
68       }
69     }
70
71     return aBuffer.toString();
72   }
73
74   /**
75    * Invokes a method on the target object using the method prefix and the
76    * element name passed in.
77    *
78    * @param aMethodPrefix The prefix of the method to call (create, add, ...).
79    * @param anElementName The element name for which we have to invoke a method.
80    * @param aTarget The target object on which the method invocation is done.
81    * @return The result of the method invocation or null if the method call failed.
82    */

83   protected static Object JavaDoc invokeMethod(String JavaDoc aMethodPrefix,
84     String JavaDoc anElementName, Object JavaDoc aTarget) {
85     Object JavaDoc anObject = null;
86
87     try {
88       // Invoking the method on the parent object that starts with the prefix passed in
89
Method JavaDoc aMethod = aTarget.getClass().getMethod(aMethodPrefix +
90           anElementName, new Class JavaDoc[0]);
91
92       anObject = aMethod.invoke(aTarget, new Object JavaDoc[0]);
93     } catch (NoSuchMethodException JavaDoc nsme) {
94     } catch (IllegalAccessException JavaDoc iae) {
95     } catch (InvocationTargetException JavaDoc ite) {
96     }
97
98     return anObject;
99   }
100   
101   protected static boolean invokeVoidMethod(Object JavaDoc aTarget, String JavaDoc elementName){
102     if(aTarget == null){
103       return false;
104     }
105     
106     Method JavaDoc toInvoke = null;
107     toInvoke = findVoidMethod(aTarget.getClass(), elementName);
108    
109     if(toInvoke == null){
110       toInvoke = findVoidMethod(aTarget.getClass(), "set" + AbstractXMLProcessor.toMethodName(elementName));
111     }
112     if(toInvoke == null){
113       toInvoke = findVoidMethod(aTarget.getClass(), "add" + AbstractXMLProcessor.toMethodName(elementName));
114     }
115     if(toInvoke == null){
116       return false;
117     }
118     try{
119       toInvoke.invoke(aTarget, new Object JavaDoc[0]);
120       return true;
121     } catch (IllegalAccessException JavaDoc iae) {
122       return false;
123     } catch (InvocationTargetException JavaDoc ite) {
124       return false;
125     }
126   }
127   
128   protected static Method JavaDoc findVoidMethod(Class JavaDoc owner, String JavaDoc name){
129     try{
130       Method JavaDoc m = owner.getMethod(name, new Class JavaDoc[0]);
131       if(m.getReturnType().equals(void.class)){
132         return m;
133       }
134       return null;
135     }catch(NoSuchMethodException JavaDoc e){
136       return null;
137     }
138   }
139
140   /////////////////////////////////////////////////////////////////////////////////////////
141
/////////////////////////////////// MUTATOR METHODS ///////////////////////////////////
142
/////////////////////////////////////////////////////////////////////////////////////////
143

144   /**
145    * Adds the package passed in to this factory.
146    *
147    * @param aPackage The package to add.
148    */

149   public void addPackage(String JavaDoc aPackage) {
150     _thePackages.add(aPackage);
151   }
152
153   /////////////////////////////////////////////////////////////////////////////////////////
154
/////////////////////////////// INTERACE IMPLEMENTATION ///////////////////////////////
155
/////////////////////////////////////////////////////////////////////////////////////////
156

157   /**
158    * Creates an object for the element passed in.
159    *
160    * @param aPrefix The namespace prefix of the element.
161    * @param aNamespaceURI The namespace URI of the element.
162    * @param anElementName The element name for wich to create an object.
163    * @param aParent The parent object of the object to create.
164    * @exception ObjectCreationException If an error occurs creating the object.
165    */

166   public CreationStatus newObjectFor(String JavaDoc aPrefix, String JavaDoc aNamespaceURI,
167     String JavaDoc anElementName, Object JavaDoc aParent) throws ObjectCreationException {
168     Object JavaDoc anObject = null;
169     
170     if (aParent != null) {
171       // Call the createXXX() method on the target object
172

173       anObject = invokeMethod("create", firstToUpper(anElementName), aParent);
174
175       if (anObject != null) {
176         return CreationStatus.create(anObject).assigned(true);
177       } else {
178         // Call the addXXX() method on the target object
179
anObject = invokeMethod("add", firstToUpper(anElementName), aParent);
180
181         if (anObject != null) {
182           return CreationStatus.create(anObject).assigned(true);
183         } else {
184           anObject = invokeMethod("set", firstToUpper(anElementName), aParent);
185
186           if (anObject != null) {
187             return CreationStatus.create(anObject).assigned(true);
188           }
189         }
190       }
191     }
192
193     String JavaDoc aLocalClassName = firstToUpper(AbstractXMLProcessor.formatElementName(
194           anElementName));
195     Class JavaDoc clazz = null;
196     boolean isFound = false;
197
198     for (Iterator JavaDoc it = _thePackages.iterator(); !isFound && it.hasNext();) {
199       String JavaDoc aPackageName = (String JavaDoc) it.next();
200
201       try {
202         String JavaDoc aQualifiedClassName = new StringBuffer JavaDoc().append(aPackageName)
203                                                        .append(".")
204                                                        .append(aLocalClassName)
205                                                        .toString();
206
207         clazz = Class.forName(aQualifiedClassName);
208         isFound = true;
209       } catch (ClassNotFoundException JavaDoc cnfe) {
210       }
211     }
212
213     try {
214       if (clazz != null) {
215         return CreationStatus.create(clazz.newInstance());
216       } else {
217         if(!invokeVoidMethod(aParent, anElementName)){
218           throw new ObjectCreationException("Element not recognized: " +
219               anElementName);
220         }
221         else{
222           return CreationStatus.create(new NullObjectImpl()).assigned(true);
223         }
224       }
225     } catch (IllegalAccessException JavaDoc iae) {
226       String JavaDoc aMessage = "Security error creating an object for the element " +
227         anElementName;
228
229       throw new ObjectCreationException(aMessage, iae);
230     } catch (InstantiationException JavaDoc ie) {
231       String JavaDoc aMessage = "Instantiation error creating an object for the element " +
232         anElementName;
233
234       throw new ObjectCreationException(aMessage, ie);
235     } catch (RuntimeException JavaDoc re) {
236       String JavaDoc aMessage = "System error creating an object for the element " +
237         anElementName;
238
239       throw new ObjectCreationException(aMessage, re);
240     }
241   }
242   
243   public static class NullObjectImpl implements NullObject{}
244 }
245
Popular Tags