All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.picocontainer.script.bsh.BeanShellAdapter Maven / Gradle / Ivy

There is a newer version: 2.2
Show newest version
/*****************************************************************************
 * Copyright (C) PicoContainer Organization. All rights reserved.            *
 * ------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the BSD      *
 * style license a copy of which has been included with this distribution in *
 * the LICENSE.txt file.                                                     *
 *                                                                           *
 * Original code by Leo Simons                                               *
 *****************************************************************************/
package org.picocontainer.script.bsh;

import bsh.EvalError;
import bsh.Interpreter;
import org.picocontainer.Parameter;
import org.picocontainer.PicoContainer;
import org.picocontainer.PicoCompositionException;
import org.picocontainer.adapters.AbstractAdapter;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.lang.reflect.Type;

/**
 * This adapter relies on Bsh for instantiation
 * (and possibly also initialisation) of component instances.
 * 

* When {@link org.picocontainer.ComponentAdapter#getComponentInstance} is called (by PicoContainer), * the adapter instance will look for a script with the same name as the component implementation * class (but with the .bsh extension). This script must reside in the same folder as the class. * (It's ok to have them both in a jar). *

* The bsh script's only contract is that it will have to instantiate a bsh variable called * "instance". *

* The script will have access to the following variables: *

    *
  • addAdapter - the adapter calling the script
  • *
  • picoContainer - the MutablePicoContainer calling the addAdapter
  • *
  • componentKey - the component key
  • *
  • componentImplementation - the component implementation
  • *
  • parameters - the ComponentParameters (as a List)
  • *
* @author Leo Simons * @author Aslak Hellesoy */ @SuppressWarnings({ "unchecked", "serial" }) public class BeanShellAdapter extends AbstractAdapter { private final Parameter[] parameters; private Object instance = null; /** * Classloader to set for the BeanShell interpreter. */ private final ClassLoader classLoader; public BeanShellAdapter(final Object componentKey, final Class componentImplementation, final Parameter[] parameters, final ClassLoader classLoader) { super(componentKey, componentImplementation); this.parameters = parameters; this.classLoader = classLoader; } public BeanShellAdapter(final Object componentKey, final Class componentImplementation, final Parameter... parameters) { this(componentKey, componentImplementation, parameters, BeanShellAdapter.class.getClassLoader()); } public Object getComponentInstance(PicoContainer pico, Type into) throws PicoCompositionException { if (instance == null) { try { Interpreter i = new Interpreter(); i.setClassLoader(classLoader); i.set("addAdapter", this); i.set("picoContainer", pico); i.set("componentKey", getComponentKey()); i.set("componentImplementation", getComponentImplementation()); i.set("parameters", parameters != null ? Arrays.asList(parameters) : Collections.EMPTY_LIST); i.eval("import " + getComponentImplementation().getName() + ";"); String scriptPath = "/" + getComponentImplementation().getName().replace('.', '/') + ".bsh"; // Inside IDEA, this relies on the compilation output path being the same directory as the source path. // kludge - copy ScriptableDemoBean.bsh to the same location in the test output compile class path. // the same problem exists for maven, but some custom jelly script will be able to fix that. URL scriptURL = getComponentImplementation().getResource(scriptPath); if (scriptURL == null) { throw new BeanShellScriptCompositionException("Couldn't load script at path " + scriptPath); } Reader sourceReader = new InputStreamReader(scriptURL.openStream()); i.eval(sourceReader, i.getNameSpace(), scriptURL.toExternalForm()); instance = i.get("instance"); if (instance == null) { throw new BeanShellScriptCompositionException("The 'instance' variable was not instantiated"); } } catch (EvalError e) { throw new BeanShellScriptCompositionException(e); } catch (IOException e) { throw new BeanShellScriptCompositionException(e); } } return instance; } public void verify(PicoContainer pico) { } public String getDescriptor() { return "BeanShellConsole"; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy