1    //
2    // SwitchRMI  Framework
3    // Copyright (c) 2000-2002 by Michael J. Henderson & Associates.
4    //
5    // Michael Henderson
6    // http://switchrmi.sf.net
7    // mailto:mikehenderson@dunelm.org.uk
8    //
9    // This library is free software.
10   //
11   // You may redistribute it and/or modify it under the terms of the GNU
12   // Lesser General Public License as published by the Free Software Foundation.
13   //
14   // Version 2.1 of the license should be included with this distribution in
15   // the file LICENSE, as well as License.html. If the license is not
16   // included with this distribution, you may find a copy at the FSF web
17   // site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
18   // Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
19   //
20   // This library is distributed in the hope that it will be useful,
21   // but WITHOUT ANY WARRANTY; without even the implied waranty of
22   // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23   // Lesser General Public License for more details.
24   //
25   // $Id: RmiScriptObjectFactory.java,v 1.1 2002/11/11 22:19:48 mikehenderson Exp $
26   //
27   package com.mjh.switchrmi.jndi;
28   
29   import com.ibm.bsf.*;
30   import com.mjh.switchrmi.*;
31   
32   import java.io.*;
33   
34   import java.lang.reflect.*;
35   
36   import java.net.*;
37   
38   import java.util.*;
39   
40   import javax.naming.*;
41   import javax.naming.spi.*;
42   
43   import org.apache.log4j.Logger;
44   
45   public class RmiScriptObjectFactory
46       extends RmiObjectFactoryBase
47       implements ObjectFactory
48   {
49       private static final Logger log = 
50               Logger.getLogger(RmiScriptObjectFactory.class.getName());
51       private String source;
52       private String language;
53   
54       public RmiScriptObjectFactory()
55       {
56       }
57   
58       public Object getObjectInstance(Object obj, Name name, Context ctx, 
59                                       Hashtable env)
60                                throws Exception
61       {
62           log.debug("obj = " + obj);
63           log.debug("name = " + name);
64           log.debug("ctx = " + ctx);
65           log.debug("env = " + env);
66   
67           Reference ref = (Reference) obj;
68           URL[] codebase = getCodebase(name, env);
69   
70           log.debug("codebase = " + codebase);
71   
72           ClassLoader loader = getClass().getClassLoader();
73   
74           if (codebase != null)
75           {
76               loader = new URLClassLoader(codebase, loader);
77           }
78   
79           //load interfaces rom loader
80           Class[] interfaces = getInterfaces(name, env, loader);
81           String source = (String) getTypeInfoValue("source", name, env);
82           String language = (String) getTypeInfoValue("language", name, env);
83   
84           log.debug("loader = " + loader);
85           log.debug("source = " + source);
86           log.debug("language = " + language);
87   
88           ScriptInvocationHandler handler = 
89                   new ScriptInvocationHandler(interfaces, source, language, 
90                                               loader);
91   
92           return Proxy.newProxyInstance(loader, interfaces, handler);
93       }
94   
95       private class ScriptInvocationHandler
96           extends RmiInvocationHandlerBase
97       {
98           private String script;
99           private String language;
100          private ClassLoader loader;
101          private BSFManager manager;
102          private BSFEngine engine;
103  
104          public ScriptInvocationHandler(Class[] interfaces, String script, 
105                                         String language, ClassLoader cl)
106          {
107              super(interfaces);
108              this.script = script;
109              this.language = language;
110              this.loader = cl;
111  
112              if (log.isDebugEnabled())
113              {
114                  log.debug("script = " + script);
115                  log.debug("language = [" + language + "]");
116              }
117          }
118  
119          public Object rmiInvoke(Object target, Method method, Object[] args)
120                           throws Throwable
121          {
122              if (manager == null)
123              {
124                  init();
125              }
126  
127              String scriptMethodName = 
128                      convertJavaMethodNameToScriptMethodName(method.getName());
129              Object result = engine.call(null, scriptMethodName, args);
130  
131              if (log.isDebugEnabled())
132              {
133                  log.debug("result = " + result);
134              }
135  
136              return convertResultToMethodReturnType(result, 
137                                                     method.getReturnType());
138          }
139  
140          private void init() throws Exception
141          {
142              boolean debug = log.isDebugEnabled();
143  
144              language = determineScriptLanguage();
145  
146              if (debug)
147              {
148                  log.debug("language = " + language);
149              }
150  
151              manager = new BSFManager();
152  
153              if (debug)
154              {
155                  log.debug("manager = " + manager);
156              }
157  
158              engine = manager.loadScriptingEngine(language);
159  
160              if (debug)
161              {
162                  log.debug("engine = " + engine);
163              }
164  
165              manager.exec(language, script, -1, -1, readScript());
166          }
167  
168          private String readScript()
169                             throws Exception
170          {
171              boolean debug = log.isDebugEnabled();
172              StringBuffer sb = new StringBuffer();
173  
174              if (debug)
175              {
176                  log.debug("script = " + script);
177              }
178  
179              java.net.URL url = loader.getResource(script);
180  
181              if (debug)
182              {
183                  log.debug("url = " + url);
184              }
185  
186              InputStream in = loader.getResourceAsStream(script);
187  
188              if (debug)
189              {
190                  log.debug("in = " + in);
191              }
192  
193              BufferedReader reader = 
194                      new BufferedReader(new InputStreamReader(in));
195              String line = reader.readLine();
196  
197              while (line != null)
198              {
199                  sb.append(line);
200                  sb.append("\n");
201                  line = reader.readLine();
202              }
203  
204              String string = sb.toString();
205  
206              if (debug)
207              {
208                  log.debug("script text = " + string);
209              }
210  
211              return string;
212          }
213  
214          private String determineScriptLanguage()
215              throws Exception
216          {
217              if ((language == null) || (language.length() == 0))
218              {
219                  language = manager.getLangFromFilename(script);
220              }
221  
222              return language;
223          }
224  
225          private String convertJavaMethodNameToScriptMethodName(String javaName)
226          {
227              return javaName;
228          }
229  
230          private Object convertResultToMethodReturnType(Object value, 
231                                                         Class targetType)
232          {
233              if (targetType == int.class)
234              {
235                  value = new Integer(((Number) value).intValue());
236              }
237  
238              return value;
239          }
240      }
241  }