KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > bsf > util > EngineUtils


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2002 The Apache Software Foundation. All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * 3. The end-user documentation included with the redistribution, if
20  * any, must include the following acknowlegement:
21  * "This product includes software developed by the
22  * Apache Software Foundation (http://www.apache.org/)."
23  * Alternately, this acknowlegement may appear in the software itself,
24  * if and wherever such third-party acknowlegements normally appear.
25  *
26  * 4. The names "Apache BSF", "Apache", and "Apache Software Foundation"
27  * must not be used to endorse or promote products derived from
28  * this software without prior written permission. For written
29  * permission, please contact apache@apache.org.
30  *
31  * 5. Products derived from this software may not be called "Apache"
32  * nor may "Apache" appear in their names without prior written
33  * permission of the Apache Group.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many individuals
50  * on behalf of the Apache Software Foundation and was originally created by
51  * Sanjiva Weerawarana and others at International Business Machines
52  * Corporation. For more information on the Apache Software Foundation,
53  * please see <http://www.apache.org/>.
54  */

55
56 package org.apache.bsf.util;
57
58 import java.lang.reflect.*;
59 import java.util.*;
60 import java.io.*;
61 import java.beans.*;
62
63 import org.apache.bsf.*;
64 import org.apache.bsf.util.*;
65
66 /**
67  * This class contains utilities that language integrators can use
68  * when implementing the BSFEngine interface.
69  *
70  * @author Sanjiva Weerawarana
71  * @author Sam Ruby
72  */

73 public class EngineUtils {
74   // the BSF class loader that knows how to load from the a specific
75
// temp directory
76
static BSFClassLoader bsfCL;
77
78   //////////////////////////////////////////////////////////////////////////
79

80   /**
81    * Add a script as a listener to some event coming out of an object. The
82    * first two args identify the src of the event and the event set
83    * and the rest identify the script which should be run when the event
84    * fires.
85    *
86    * @param bean event source
87    * @param eventSetName name of event set from event src to bind to
88    * @param filter filter for events
89    * @param engine BSFEngine which can run this script
90    * @param manager BSFManager of the above engine
91    * @param source (context info) the source of this expression
92                          (e.g., filename)
93    * @param lineNo (context info) the line number in source for expr
94    * @param columnNo (context info) the column number in source for expr
95    * @param script the script to execute when the event occurs
96    *
97    * @exception BSFException if anything goes wrong while running the script
98    */

99   public static void addEventListener (Object JavaDoc bean, String JavaDoc eventSetName,
100                        String JavaDoc filter,
101                        BSFEngine engine, BSFManager manager,
102                        String JavaDoc source, int lineNo,
103                        int columnNo, Object JavaDoc script)
104        throws BSFException {
105     BSFEventProcessor ep = new BSFEventProcessor (engine, manager, filter,
106                           source, lineNo, columnNo,
107                           script);
108     try {
109       ReflectionUtils.addEventListener (bean, eventSetName, ep);
110     } catch (Exception JavaDoc e) {
111       e.printStackTrace ();
112       throw new BSFException (BSFException.REASON_OTHER_ERROR,
113                   "ouch while adding event listener: " + e, e);
114     }
115   }
116   //////////////////////////////////////////////////////////////////////////
117

118   /**
119    * Finds and invokes a method with the given signature on the given
120    * bean. The signature of the method that's invoked is first taken
121    * as the types of the args, but if that fails, this tries to convert
122    * any primitive wrapper type args to their primitive counterparts
123    * to see whether a method exists that way. If it does, done.
124    *
125    * @param bean the object on which to invoke the method
126    * @param methodName name of the method
127    * @param args arguments to be given to the method
128    *
129    * @return the result of invoking the method, if any
130    *
131    * @exception BSFException if something goes wrong
132    */

133   public static Object JavaDoc callBeanMethod (Object JavaDoc bean, String JavaDoc methodName,
134                        Object JavaDoc[] args) throws BSFException {
135     // determine arg types. note that a null argtype matches any object type
136
Class JavaDoc[] argTypes = null;
137     if (args != null) {
138       argTypes = new Class JavaDoc[args.length];
139       for (int i = 0; i < args.length; i++) {
140     argTypes[i] = (args[i] == null) ? null : args[i].getClass ();
141       }
142     }
143
144     // we want to allow a static call to occur on an object, similar
145
// to what Java allows. So isStaticOnly is set to false.
146
boolean isStaticOnly = false;
147     Class JavaDoc beanClass = (bean instanceof Class JavaDoc) ? (Class JavaDoc)bean : bean.getClass ();
148
149     // now try to call method with the right signature
150
try {
151       Method m;
152       try {
153     m = MethodUtils.getMethod (beanClass, methodName, argTypes,
154                        isStaticOnly);
155       } catch (NoSuchMethodException JavaDoc e) {
156     // ok, so that didn't work - now try converting any primitive
157
// wrapper types to their primitive counterparts
158
try {
159       // if args is null the NullPointerException will get caught
160
// below and the right thing'll happen .. ugly but works
161
for (int i = 0; i < args.length; i++) {
162         if (args[i] instanceof Number JavaDoc) {
163           // byte is convertible to all primitive numeric types,
164
// so this'll find anything in that order and the
165
// actual type will be that specified by the method decl
166
argTypes[i] = byte.class;
167           if(args[i] instanceof Float JavaDoc) argTypes[i]= float.class;
168           else if(args[i] instanceof Double JavaDoc ) argTypes[i]= double.class;
169         } else if (args[i] instanceof Boolean JavaDoc) {
170           argTypes[i] = boolean.class;
171         }
172       }
173       m = MethodUtils.getMethod (beanClass, methodName, argTypes,
174                      isStaticOnly);
175     } catch (Exception JavaDoc e2) {
176       // throw the original
177
throw e;
178     }
179       }
180
181       // call it, and return the result
182
return m.invoke (bean, args);
183     } catch (Exception JavaDoc e) {
184       // something went wrong while invoking method
185
Throwable JavaDoc t = (e instanceof InvocationTargetException) ?
186                 ((InvocationTargetException)e).getTargetException () :
187                 null;
188       throw new BSFException (BSFException.REASON_OTHER_ERROR,
189                   "method invocation failed: " + e +
190                   ((t==null)?"":(" target exception: "+t)), t);
191     }
192   }
193   //////////////////////////////////////////////////////////////////////////
194

195   /**
196    * Creates a new bean. The signature of teh constructor that's invoked
197    * is first taken as the types of the args, but if that fails, this tries
198    * to convert any primitive wrapper type args to their primitive
199    * counterparts to see whether a method exists that way. If it does, done.
200    *
201    * @param className fully qualified name of class to instantiate
202    * @param args array of constructor args (or null if none)
203    *
204    * @return the created bean
205    *
206    * @exception BSFException if something goes wrong (@see
207    * org.apache.cs.util.MethodUtils for the real
208    * exceptions that can occur).
209    */

210   public static Object JavaDoc createBean (String JavaDoc className,
211                    Object JavaDoc args[]) throws BSFException {
212     Bean obj;
213
214     Class JavaDoc[] argTypes = null;
215     if (args != null) {
216       argTypes = new Class JavaDoc[args.length];
217       for (int i = 0; i < args.length; i++) {
218     argTypes[i] = (args[i] != null) ? args[i].getClass () : null;
219       }
220     }
221
222     try {
223       try {
224     obj = ReflectionUtils.createBean (null, className, argTypes, args);
225     return obj.value;
226       } catch (NoSuchMethodException JavaDoc me) {
227     // ok, so that didn't work - now try converting any primitive
228
// wrapper types to their primitive counterparts
229
try {
230       // if args is null the NullPointerException will get caught
231
// below and the right thing'll happen .. ugly but works
232
for (int i = 0; i < args.length; i++) {
233         if (args[i] instanceof Number JavaDoc) {
234           // byte is convertible to all primitive numeric types,
235
// so this'll find anything in that order and the
236
// actual type will be that specified by the method decl
237
argTypes[i] = byte.class;
238         } else if (args[i] instanceof Boolean JavaDoc) {
239           argTypes[i] = boolean.class;
240         }
241       }
242       obj = ReflectionUtils.createBean (null, className, argTypes, args);
243       return obj.value;
244     } catch (Exception JavaDoc e) {
245       // throw the previous exception
246
throw me;
247     }
248       }
249     } catch (Exception JavaDoc e) {
250       throw new BSFException (BSFException.REASON_OTHER_ERROR,
251                   e.getMessage (), e);
252     }
253   }
254   //////////////////////////////////////////////////////////////////////////
255

256   /**
257    * Given a class return the type signature string fragment for it.
258    * That is, return "I" for int, "J" for long, ... etc..
259    *
260    * @param cl class object for whom the signature fragment is needed.
261    *
262    * @return the string representing the type signature
263    */

264   public static String JavaDoc getTypeSignatureString (Class JavaDoc cl) {
265     if (cl.isPrimitive ()) {
266       if (cl == boolean.class) {
267     return "Z";
268       } else if (cl == byte.class) {
269     return "B";
270       } else if (cl == char.class) {
271     return "C";
272       } else if (cl == short.class) {
273     return "S";
274       } else if (cl == int.class) {
275     return "I";
276       } else if (cl == long.class) {
277     return "J";
278       } else if (cl == float.class) {
279     return "F";
280       } else if (cl == double.class) {
281     return "D";
282       } else { // (cl == void.class)
283
return "V";
284       }
285     } else {
286       StringBuffer JavaDoc sb = new StringBuffer JavaDoc ("L");
287       sb.append (cl.getName ());
288       sb.append (";");
289       return sb.toString().replace ('.', '/');
290     }
291   }
292   //////////////////////////////////////////////////////////////////////////
293

294   /**
295    * Load a class using the class loader of given manager. If that fails
296    * try using a class loader that loads from the tempdir of the manager.
297    *
298    * @param mgr BSFManager who's classLoader and tempDir props are
299    * consulted
300    * @param name name of the class to load
301    *
302    * @return the loaded class
303    *
304    * @exception BSFException if something goes wrong.
305    */

306   public static Class JavaDoc loadClass (BSFManager mgr, String JavaDoc name)
307                                                       throws BSFException {
308     ClassLoader JavaDoc classLoader = mgr.getClassLoader ();
309     try {
310       return (classLoader == null) ? Class.forName (name)
311                                    : classLoader.loadClass (name);
312     } catch (ClassNotFoundException JavaDoc e) {
313       // try to load it from the temp dir using my own class loader
314
try {
315     if (bsfCL == null) {
316       bsfCL = new BSFClassLoader ();
317     }
318     bsfCL.setTempDir (mgr.getTempDir ());
319     return bsfCL.loadClass (name);
320       } catch (ClassNotFoundException JavaDoc e2) {
321     throw new BSFException (BSFException.REASON_OTHER_ERROR,
322                 "unable to load class '" + name + "':" + e, e);
323       }
324     }
325   }
326 }
327
Popular Tags