KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > nanocontainer > script > bsh > BeanShellComponentAdapter


1 /*****************************************************************************
2  * Copyright (C) NanoContainer Organization. All rights reserved. *
3  * ------------------------------------------------------------------------- *
4  * The software in this package is published under the terms of the BSD *
5  * style license a copy of which has been included with this distribution in *
6  * the LICENSE.txt file. *
7  * *
8  * Original code by Leo Simons *
9  *****************************************************************************/

10 package org.nanocontainer.script.bsh;
11
12 import bsh.EvalError;
13 import bsh.Interpreter;
14 import org.picocontainer.Parameter;
15 import org.picocontainer.PicoContainer;
16 import org.picocontainer.PicoInitializationException;
17 import org.picocontainer.PicoIntrospectionException;
18 import org.picocontainer.defaults.AbstractComponentAdapter;
19 import org.picocontainer.defaults.UnsatisfiableDependenciesException;
20
21 import java.io.IOException JavaDoc;
22 import java.io.InputStreamReader JavaDoc;
23 import java.io.Reader JavaDoc;
24 import java.net.URL JavaDoc;
25 import java.util.Arrays JavaDoc;
26 import java.util.Collections JavaDoc;
27
28 /**
29  * This adapter relies on <a HREF="http://beanshell.org/">Bsh</a> for instantiation
30  * (and possibly also initialisation) of component instances.
31  * <p/>
32  * When {@link org.picocontainer.ComponentAdapter#getComponentInstance} is called (by PicoContainer),
33  * the adapter instance will look for a script with the same name as the component implementation
34  * class (but with the .bsh extension). This script must reside in the same folder as the class.
35  * (It's ok to have them both in a jar).
36  * <p/>
37  * The bsh script's only contract is that it will have to instantiate a bsh variable called
38  * "instance".
39  * <p/>
40  * The script will have access to the following variables:
41  * <ul>
42  * <li>adapter - the adapter calling the script</li>
43  * <li>picoContainer - the MutablePicoContainer calling the adapter</li>
44  * <li>componentKey - the component key</li>
45  * <li>componentImplementation - the component implementation</li>
46  * <li>parameters - the ComponentParameters (as a List)</li>
47  * </ul>
48  * @author <a HREF="mail at leosimons dot com">Leo Simons</a>
49  * @author Aslak Hellesoy
50  * @version $Id: BeanShellComponentAdapter.java 3144 2006-12-26 10:12:19Z mauro $
51  */

52 public class BeanShellComponentAdapter extends AbstractComponentAdapter {
53     private final Parameter[] parameters;
54
55     private Object JavaDoc instance = null;
56
57     /**
58      * Classloader to set for the BeanShell interpreter.
59      */

60     private final ClassLoader JavaDoc classLoader;
61
62     public BeanShellComponentAdapter(final Object JavaDoc componentKey, final Class JavaDoc componentImplementation, final Parameter[] parameters, final ClassLoader JavaDoc classLoader) {
63         super(componentKey, componentImplementation);
64         this.parameters = parameters;
65         this.classLoader = classLoader;
66     }
67
68     public BeanShellComponentAdapter(final Object JavaDoc componentKey, final Class JavaDoc componentImplementation, final Parameter[] parameters) {
69         this(componentKey, componentImplementation, parameters, BeanShellComponentAdapter.class.getClassLoader());
70     }
71
72     public Object JavaDoc getComponentInstance(PicoContainer pico)
73             throws PicoInitializationException, PicoIntrospectionException {
74
75         if (instance == null) {
76             try {
77                 Interpreter i = new Interpreter();
78                 i.setClassLoader(classLoader);
79                 i.set("adapter", this);
80                 i.set("picoContainer", pico);
81                 i.set("componentKey", getComponentKey());
82                 i.set("componentImplementation", getComponentImplementation());
83                 i.set("parameters", parameters != null ? Arrays.asList(parameters) : Collections.EMPTY_LIST);
84                 i.eval("import " + getComponentImplementation().getName() + ";");
85
86                 String JavaDoc scriptPath = "/" + getComponentImplementation().getName().replace('.', '/') + ".bsh";
87
88                 // Inside IDEA, this relies on the compilation output path being the same directory as the source path.
89
// kludge - copy ScriptableDemoBean.bsh to the same location in the test output compile class path.
90
// the same problem exists for maven, but some custom jelly script will be able to fix that.
91
URL JavaDoc scriptURL = getComponentImplementation().getResource(scriptPath);
92                 if (scriptURL == null) {
93                     throw new BeanShellScriptInitializationException("Couldn't load script at path " + scriptPath);
94                 }
95                 Reader JavaDoc sourceReader = new InputStreamReader JavaDoc(scriptURL.openStream());
96                 i.eval(sourceReader, i.getNameSpace(), scriptURL.toExternalForm());
97
98                 instance = i.get("instance");
99                 if (instance == null) {
100                     throw new BeanShellScriptInitializationException("The 'instance' variable was not instantiated");
101                 }
102             } catch (EvalError e) {
103                 throw new BeanShellScriptInitializationException(e);
104             } catch (IOException JavaDoc e) {
105                 throw new BeanShellScriptInitializationException(e);
106             }
107         }
108         return instance;
109     }
110
111     public void verify(PicoContainer pico) throws UnsatisfiableDependenciesException {
112     }
113 }
114
Popular Tags