Save This Page
Home » bsf-src-2.4.0 » org.apache.bsf » [javadoc | source]
    1   /*
    2    * Copyright 2004,2004 The Apache Software Foundation.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    *
   10    * Unless required by applicable law or agreed to in writing, software
   11    * distributed under the License is distributed on an "AS IS" BASIS,
   12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   13    * See the License for the specific language governing permissions and
   14    * limitations under the License.
   15    */
   16   
   17   package org.apache.bsf;
   18   
   19   import java.beans.PropertyChangeSupport;
   20   import java.io.IOException;
   21   import java.io.InputStream;
   22   import java.net.URL;
   23   import java.security.AccessController;
   24   import java.security.PrivilegedActionException;
   25   import java.security.PrivilegedExceptionAction;
   26   import java.util.Enumeration;
   27   import java.util.Hashtable;
   28   import java.util.Iterator;
   29   import java.util.MissingResourceException;
   30   import java.util.NoSuchElementException;
   31   import java.util.Properties;
   32   import java.util.StringTokenizer;
   33   import java.util.Vector;
   34   
   35   import org.apache.bsf.util.CodeBuffer;
   36   import org.apache.bsf.util.ObjectRegistry;
   37   import org.apache.commons.logging.Log;
   38   import org.apache.commons.logging.LogFactory;
   39   
   40   /**
   41    * This class is the entry point to the bean scripting framework. An
   42    * application wishing to integrate scripting to a Java app would
   43    * place an instance of a BSFManager in their code and use its services
   44    * to register the beans they want to make available for scripting,
   45    * load scripting engines, and run scripts.
   46    * <p>
   47    * BSFManager serves as the registry of available scripting engines
   48    * as well. Loading and unloading of scripting engines is
   49    * supported as well. Each BSFManager loads one engine per language.
   50    * Several BSFManagers can be created per JVM.
   51    *
   52    * @author   Sanjiva Weerawarana
   53    * @author   Matthew J. Duftler
   54    * @author   Sam Ruby
   55    * @author   Olivier Gruber (added original debugging support)
   56    * @author   Don Schwarz (added support for registering languages dynamically)
   57    */
   58   public class BSFManager {
   59       // version string is in the form "abc.yyyymmdd" where
   60       // "abc" represents a dewey decimal number (three levels, each between 0 and 9),
   61       // and "yyyy" a four digit year, "mm" a two digit month, "dd" a two digit day.
   62       //
   63       // Example: "240.20060925" stands for: BSF version "2.4.0" as of "2006-09-25"
   64       protected static String version="240.20061006";
   65   
   66       // table of registered scripting engines
   67       protected static Hashtable registeredEngines = new Hashtable();
   68   
   69       // mapping of file extensions to languages
   70       protected static Hashtable extn2Lang = new Hashtable();
   71   
   72       // table of scripting engine instances created by this manager.
   73       // only one instance of a given language engine is created by a single
   74       // manager instance.
   75       protected Hashtable loadedEngines = new Hashtable();
   76   
   77       // table of registered beans for use by scripting engines.
   78       protected ObjectRegistry objectRegistry = new ObjectRegistry();
   79   
   80       // prop change support containing loaded engines to inform when any
   81       // of my interesting properties change
   82       protected PropertyChangeSupport pcs;
   83   
   84       // the class loader to use if a class loader is needed. Default is
   85       // he who loaded me (which may be null in which case its Class.forName).
   86       // protected ClassLoader classLoader = getClass().getClassLoader();
   87       protected ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // rgf, 2006-01-05
   88   
   89       // temporary directory to use to dump temporary files into. Note that
   90       // if class files are dropped here then unless this dir is in the
   91       // classpath or unless the classloader knows to look here, the classes
   92       // will not be found.
   93       protected String tempDir = ".";
   94   
   95       // classpath used by those that need a classpath
   96       protected String classPath;
   97   
   98       // stores BSFDeclaredBeans representing objects
   99       // introduced by a client of BSFManager
  100       protected Vector declaredBeans = new Vector();
  101   
  102       private Log logger = LogFactory.getLog(this.getClass().getName());
  103   
  104       //////////////////////////////////////////////////////////////////////
  105       //
  106       // pre-register engines that BSF supports off the shelf
  107       //
  108       //////////////////////////////////////////////////////////////////////
  109   
  110       static {
  111           try {
  112               Enumeration e = BSFManager.class.getClassLoader().getResources("org/apache/bsf/Languages.properties");
  113               while (e.hasMoreElements()) {
  114                   URL url = (URL)e.nextElement();
  115                   InputStream is = url.openStream();
  116   
  117                   Properties p = new Properties();
  118                   p.load(is);
  119   
  120                   for (Enumeration keys = p.propertyNames(); keys.hasMoreElements();) {
  121   
  122                       String key = (String) keys.nextElement();
  123                       String value = p.getProperty(key);
  124                       String className = value.substring(0, value.indexOf(","));
  125   
  126   
  127   
  128   
  129                       // get the extensions for this language
  130                       String exts = value.substring(value.indexOf(",")+1, value.length());
  131                       StringTokenizer st = new StringTokenizer(exts, "|");
  132                       String[] extensions = new String[st.countTokens()];
  133                       for (int i = 0; st.hasMoreTokens(); i++) {
  134                           extensions[i] = ((String) st.nextToken()).trim();
  135                       }
  136   
  137                       registerScriptingEngine(key, className, extensions);
  138                   }
  139               }
  140           } catch (IOException ex) {
  141   
  142               ex.printStackTrace();
  143               System.err.println("Error reading Languages file " + ex);
  144           } catch (NoSuchElementException nsee) {
  145   
  146               nsee.printStackTrace();
  147               System.err.println("Syntax error in Languages resource bundle");
  148           } catch (MissingResourceException mre) {
  149   
  150               mre.printStackTrace();
  151               System.err.println("Initialization error: " + mre.toString());
  152           }
  153       }
  154   
  155       public BSFManager() {
  156           pcs = new PropertyChangeSupport(this);
  157       }
  158   
  159   
  160      /** Returns the version string of BSF.
  161        *
  162        * @return version string in the form &quot;abc.yyyymmdd&quot; where
  163          &quot;abc&quot; represents a dewey decimal number (three levels, each between 0 and 9), and
  164          &quot;yyyy&quot; a four digit year, &quot;mm&quot; a two digit month,
  165          &quot;dd&quot; a two digit day.
  166       *
  167          <br>Example: &quot;<code>240.20061006</code>&quot;
  168          stands for: BSF version <code>2.4.0</code> as of <code>2006-10-06</code>.
  169       *
  170       *
  171        * @since 2006-01-17
  172        */
  173       public static String getVersion() {
  174   
  175           return version;
  176       }
  177   
  178       /**
  179        * Apply the given anonymous function of the given language to the given
  180        * parameters and return the resulting value.
  181        *
  182        * @param lang language identifier
  183        * @param source (context info) the source of this expression
  184        (e.g., filename)
  185        * @param lineNo (context info) the line number in source for expr
  186        * @param columnNo (context info) the column number in source for expr
  187        * @param funcBody the multi-line, value returning script to evaluate
  188        * @param paramNames the names of the parameters above assumes
  189        * @param arguments values of the above parameters
  190        *
  191        * @exception BSFException if anything goes wrong while running the script
  192        */
  193       public Object apply(String lang,
  194                           String source,
  195                           int lineNo,
  196                           int columnNo,
  197                           Object funcBody,
  198                           Vector paramNames,
  199                           Vector arguments)
  200           throws BSFException {
  201       	logger.debug("BSFManager:apply");
  202   
  203       	final BSFEngine e = loadScriptingEngine(lang);
  204           final String sourcef = source;
  205           final int lineNof = lineNo, columnNof = columnNo;
  206           final Object funcBodyf = funcBody;
  207           final Vector paramNamesf = paramNames;
  208           final Vector argumentsf = arguments;
  209           Object result = null;
  210   
  211           try {
  212               final Object resultf =
  213                   AccessController.doPrivileged(new PrivilegedExceptionAction() {
  214                           public Object run() throws Exception {
  215                               return e.apply(sourcef, lineNof, columnNof,
  216                                              funcBodyf, paramNamesf, argumentsf);
  217                           }
  218                       });
  219               result = resultf;
  220           } catch (PrivilegedActionException prive) {
  221   
  222           	logger.error("Exception: ", prive);
  223               throw (BSFException) prive.getException();
  224           }
  225   
  226           return result;
  227       }
  228   
  229       /**
  230        * Compile the application of the given anonymous function of the given
  231        * language to the given parameters into the given <tt>CodeBuffer</tt>.
  232        *
  233        * @param lang language identifier
  234        * @param source (context info) the source of this expression
  235        (e.g., filename)
  236        * @param lineNo (context info) the line number in source for expr
  237        * @param columnNo (context info) the column number in source for expr
  238        * @param funcBody the multi-line, value returning script to evaluate
  239        * @param paramNames the names of the parameters above assumes
  240        * @param arguments values of the above parameters
  241        * @param cb       code buffer to compile into
  242        *
  243        * @exception BSFException if anything goes wrong while running the script
  244        */
  245       public void compileApply(String lang,
  246                                String source,
  247                                int lineNo,
  248                                int columnNo,
  249                                Object funcBody,
  250                                Vector paramNames,
  251                                Vector arguments,
  252                                CodeBuffer cb)
  253           throws BSFException {
  254       	logger.debug("BSFManager:compileApply");
  255   
  256           final BSFEngine e = loadScriptingEngine(lang);
  257           final String sourcef = source;
  258           final int lineNof = lineNo, columnNof = columnNo;
  259           final Object funcBodyf = funcBody;
  260           final Vector paramNamesf = paramNames;
  261           final Vector argumentsf = arguments;
  262           final CodeBuffer cbf = cb;
  263   
  264           try {
  265               AccessController.doPrivileged(new PrivilegedExceptionAction() {
  266                       public Object run() throws Exception {
  267                           e.compileApply(sourcef, lineNof, columnNof,
  268                                          funcBodyf, paramNamesf,
  269                                          argumentsf, cbf);
  270                           return null;
  271                       }
  272                   });
  273           } catch (PrivilegedActionException prive) {
  274   
  275           	logger.error("Exception :", prive);
  276               throw (BSFException) prive.getException();
  277           }
  278       }
  279   
  280       /**
  281        * Compile the given expression of the given language into the given
  282        * <tt>CodeBuffer</tt>.
  283        *
  284        * @param lang     language identifier
  285        * @param source   (context info) the source of this expression
  286        (e.g., filename)
  287        * @param lineNo   (context info) the line number in source for expr
  288        * @param columnNo (context info) the column number in source for expr
  289        * @param expr     the expression to compile
  290        * @param cb       code buffer to compile into
  291        *
  292        * @exception BSFException if any error while compiling the expression
  293        */
  294       public void compileExpr(String lang,
  295                               String source,
  296                               int lineNo,
  297                               int columnNo,
  298                               Object expr,
  299                               CodeBuffer cb)
  300           throws BSFException {
  301       	logger.debug("BSFManager:compileExpr");
  302   
  303       	final BSFEngine e = loadScriptingEngine(lang);
  304           final String sourcef = source;
  305           final int lineNof = lineNo, columnNof = columnNo;
  306           final Object exprf = expr;
  307           final CodeBuffer cbf = cb;
  308   
  309           try {
  310               AccessController.doPrivileged(new PrivilegedExceptionAction() {
  311                       public Object run() throws Exception {
  312                           e.compileExpr(sourcef, lineNof, columnNof, exprf, cbf);
  313                           return null;
  314                       }
  315                   });
  316           } catch (PrivilegedActionException prive) {
  317   
  318           	logger.error("Exception :", prive);
  319               throw (BSFException) prive.getException();
  320           }
  321       }
  322   
  323       /**
  324        * Compile the given script of the given language into the given
  325        * <tt>CodeBuffer</tt>.
  326        *
  327        * @param lang     language identifier
  328        * @param source   (context info) the source of this script
  329        (e.g., filename)
  330        * @param lineNo   (context info) the line number in source for script
  331        * @param columnNo (context info) the column number in source for script
  332        * @param script   the script to compile
  333        * @param cb       code buffer to compile into
  334        *
  335        * @exception BSFException if any error while compiling the script
  336        */
  337       public void compileScript(String lang,
  338                                 String source,
  339                                 int lineNo,
  340                                 int columnNo,
  341                                 Object script,
  342                                 CodeBuffer cb)
  343           throws BSFException {
  344       	logger.debug("BSFManager:compileScript");
  345   
  346           final BSFEngine e = loadScriptingEngine(lang);
  347           final String sourcef = source;
  348           final int lineNof = lineNo, columnNof = columnNo;
  349           final Object scriptf = script;
  350           final CodeBuffer cbf = cb;
  351   
  352           try {
  353               AccessController.doPrivileged(new PrivilegedExceptionAction() {
  354                       public Object run() throws Exception {
  355                           e.compileScript(sourcef, lineNof, columnNof,
  356                                           scriptf, cbf);
  357                           return null;
  358                       }
  359                   });
  360           } catch (PrivilegedActionException prive) {
  361   
  362           	logger.error("Exception :", prive);
  363               throw (BSFException) prive.getException();
  364           }
  365       }
  366   
  367       /**
  368        * Declare a bean. The difference between declaring and registering
  369        * is that engines are spsed to make declared beans "pre-available"
  370        * in the scripts as far as possible. That is, if a script author
  371        * needs a registered bean, he needs to look it up in some way. However
  372        * if he needs a declared bean, the language has the responsibility to
  373        * make those beans avaialable "automatically."
  374        * <p>
  375        * When a bean is declared it is automatically registered as well
  376        * so that any declared bean can be gotton to by looking it up as well.
  377        * <p>
  378        * If any of the languages that are already running in this manager
  379        * says they don't like this (by throwing an exception) then this
  380        * method will simply quit with that exception. That is, any engines
  381        * that come after than in the engine enumeration will not even be
  382        * told about this new bean.
  383        * <p>
  384        * So, in general its best to declare beans before the manager has
  385        * been asked to load any engines because then the user can be informed
  386        * when an engine rejects it. Also, its much more likely that an engine
  387        * can declare a bean at start time than it can at any time.
  388        *
  389        * @param beanName name to declare bean as
  390        * @param bean     the bean that's being declared
  391        * @param type     the type to represent the bean as
  392        *
  393        * @exception BSFException if any of the languages that are already
  394        *            running decides to throw an exception when asked to
  395        *            declare this bean.
  396        */
  397       public void declareBean(String beanName, Object bean, Class type)
  398           throws BSFException {
  399       	logger.debug("BSFManager:declareBean");
  400   
  401           registerBean(beanName, bean);
  402   
  403           BSFDeclaredBean tempBean = new BSFDeclaredBean(beanName, bean, type);
  404           declaredBeans.addElement(tempBean);
  405   
  406           Enumeration enginesEnum = loadedEngines.elements();
  407           BSFEngine engine;
  408           while (enginesEnum.hasMoreElements()) {
  409               engine = (BSFEngine) enginesEnum.nextElement();
  410               engine.declareBean(tempBean);
  411           }
  412       }
  413   
  414       /**
  415        * Evaluate the given expression of the given language and return the
  416        * resulting value.
  417        *
  418        * @param lang language identifier
  419        * @param source (context info) the source of this expression
  420        (e.g., filename)
  421        * @param lineNo (context info) the line number in source for expr
  422        * @param columnNo (context info) the column number in source for expr
  423        * @param expr the expression to evaluate
  424        *
  425        * @exception BSFException if anything goes wrong while running the script
  426        */
  427       public Object eval(String lang,
  428                          String source,
  429                          int lineNo,
  430                          int columnNo,
  431                          Object expr)
  432           throws BSFException {
  433       	logger.debug("BSFManager:eval");
  434   
  435           final BSFEngine e = loadScriptingEngine(lang);
  436           final String sourcef = source;
  437           final int lineNof = lineNo, columnNof = columnNo;
  438           final Object exprf = expr;
  439           Object result = null;
  440   
  441           try {
  442               final Object resultf =
  443                   AccessController.doPrivileged(new PrivilegedExceptionAction() {
  444                           public Object run() throws Exception {
  445                               return e.eval(sourcef, lineNof, columnNof, exprf);
  446                           }
  447                       });
  448               result = resultf;
  449           } catch (PrivilegedActionException prive) {
  450   
  451           	logger.error("Exception: ", prive);
  452               throw (BSFException) prive.getException();
  453           }
  454   
  455           return result;
  456       }
  457   
  458       //////////////////////////////////////////////////////////////////////
  459       //
  460       // Convenience functions for exec'ing and eval'ing scripts directly
  461       // without loading and dealing with engines etc..
  462       //
  463       //////////////////////////////////////////////////////////////////////
  464   
  465       /**
  466        * Execute the given script of the given language.
  467        *
  468        * @param lang     language identifier
  469        * @param source   (context info) the source of this expression
  470        (e.g., filename)
  471        * @param lineNo   (context info) the line number in source for expr
  472        * @param columnNo (context info) the column number in source for expr
  473        * @param script   the script to execute
  474        *
  475        * @exception BSFException if anything goes wrong while running the script
  476        */
  477       public void exec(String lang,
  478                        String source,
  479                        int lineNo,
  480                        int columnNo,
  481                        Object script)
  482           throws BSFException {
  483       	logger.debug("BSFManager:exec");
  484   
  485           final BSFEngine e = loadScriptingEngine(lang);
  486           final String sourcef = source;
  487           final int lineNof = lineNo, columnNof = columnNo;
  488           final Object scriptf = script;
  489   
  490           try {
  491               AccessController.doPrivileged(new PrivilegedExceptionAction() {
  492                       public Object run() throws Exception {
  493                           e.exec(sourcef, lineNof, columnNof, scriptf);
  494                           return null;
  495                       }
  496                   });
  497           } catch (PrivilegedActionException prive) {
  498   
  499           	logger.error("Exception :", prive);
  500               throw (BSFException) prive.getException();
  501           }
  502       }
  503   
  504       /**
  505        * Execute the given script of the given language, attempting to
  506        * emulate an interactive session w/ the language.
  507        *
  508        * @param lang     language identifier
  509        * @param source   (context info) the source of this expression
  510        *                 (e.g., filename)
  511        * @param lineNo   (context info) the line number in source for expr
  512        * @param columnNo (context info) the column number in source for expr
  513        * @param script   the script to execute
  514        *
  515        * @exception BSFException if anything goes wrong while running the script
  516        */
  517       public void iexec(String lang,
  518                        String source,
  519                        int lineNo,
  520                        int columnNo,
  521                        Object script)
  522           throws BSFException {
  523       	logger.debug("BSFManager:iexec");
  524   
  525           final BSFEngine e = loadScriptingEngine(lang);
  526           final String sourcef = source;
  527           final int lineNof = lineNo, columnNof = columnNo;
  528           final Object scriptf = script;
  529   
  530           try {
  531               AccessController.doPrivileged(new PrivilegedExceptionAction() {
  532                       public Object run() throws Exception {
  533                           e.iexec(sourcef, lineNof, columnNof, scriptf);
  534                           return null;
  535                       }
  536                   });
  537           } catch (PrivilegedActionException prive) {
  538   
  539           	logger.error("Exception :", prive);
  540               throw (BSFException) prive.getException();
  541           }
  542       }
  543   
  544       /**
  545        * Get classLoader
  546        */
  547       public ClassLoader getClassLoader() {
  548       	logger.debug("BSFManager:getClassLoader");
  549           return classLoader;
  550       }
  551   
  552       /**
  553        * Get classPath
  554        */
  555       public String getClassPath() {
  556       	logger.debug("BSFManager:getClassPath");
  557           if (classPath == null) {
  558               try {
  559                   classPath = System.getProperty("java.class.path");
  560               } catch (Throwable t) {
  561   
  562               	logger.debug("Exception :", t);
  563                   // prolly a security exception .. so no can do
  564               }
  565           }
  566           return classPath;
  567       }
  568   
  569       /**
  570        * Determine the language of a script file by looking at the file
  571        * extension.
  572        *
  573        * @param fileName the name of the file
  574        *
  575        * @return the scripting language the file is in if the file extension
  576        *         is known to me (must have been registered via
  577        *         registerScriptingEngine).
  578        *
  579        * @exception BSFException if file's extension is unknown.
  580        */
  581       public static String getLangFromFilename(String fileName)
  582           throws BSFException {
  583           int dotIndex = fileName.lastIndexOf(".");
  584   
  585           if (dotIndex != -1) {
  586               String extn = fileName.substring(dotIndex + 1);
  587               String langval = (String) extn2Lang.get(extn);
  588               String lang = null;
  589               int index, loops = 0;
  590   
  591               if (langval != null) {
  592                   while ((index = langval.indexOf(":", 0)) != -1) {
  593                       // Great. Multiple language engines registered
  594                       // for this extension.
  595                       // Try to find first one that is in our classpath.
  596                       lang = langval.substring(0, index);
  597                       langval = langval.substring(index + 1);
  598                       loops++;
  599   
  600                       // Test to see if in classpath
  601                       try {
  602                           String engineName =
  603                               (String) registeredEngines.get(lang);
  604                           Class.forName(engineName);
  605                       } catch (ClassNotFoundException cnfe) {
  606   
  607                           // Bummer.
  608                           lang = langval;
  609                           continue;
  610                       }
  611   
  612                       // Got past that? Good.
  613                       break;
  614                   }
  615                   if (loops == 0) { lang = langval; }
  616               }
  617   
  618               if (lang != null && lang != "") {
  619                   return lang;
  620               }
  621           }
  622           throw new BSFException(BSFException.REASON_OTHER_ERROR,
  623                                  "file extension missing or unknown: "
  624                                  + "unable to determine language for '"
  625                                  + fileName
  626                                  + "'");
  627       }
  628   
  629       /**
  630        * Return the current object registry of the manager.
  631        *
  632        * @return the current registry.
  633        */
  634       public ObjectRegistry getObjectRegistry() {
  635           return objectRegistry;
  636       }
  637   
  638       /**
  639        * Get tempDir
  640        */
  641       public String getTempDir() {
  642           return tempDir;
  643       }
  644   
  645       /**
  646        * Determine whether a language is registered.
  647        *
  648        * @param lang string identifying a language
  649        *
  650        * @return true iff it is
  651        */
  652       public static boolean isLanguageRegistered(String lang) {
  653           return (registeredEngines.get(lang) != null);
  654       }
  655   
  656       //////////////////////////////////////////////////////////////////////
  657       //
  658       // Bean scripting framework services
  659       //
  660       //////////////////////////////////////////////////////////////////////
  661   
  662       /**
  663        * Load a scripting engine based on the lang string identifying it.
  664        *
  665        * @param lang string identifying language
  666        * @exception BSFException if the language is unknown (i.e., if it
  667        *            has not been registered) with a reason of
  668        *            REASON_UNKNOWN_LANGUAGE. If the language is known but
  669        *            if the interface can't be created for some reason, then
  670        *            the reason is set to REASON_OTHER_ERROR and the actual
  671        *            exception is passed on as well.
  672        */
  673       public BSFEngine loadScriptingEngine(String lang) throws BSFException {
  674       	logger.debug("BSFManager:loadScriptingEngine");
  675   
  676           // if its already loaded return that
  677           BSFEngine eng = (BSFEngine) loadedEngines.get(lang);
  678           if (eng != null) {
  679               return eng;
  680           }
  681   
  682           // is it a registered language?
  683           String engineClassName = (String) registeredEngines.get(lang);
  684           if (engineClassName == null) {
  685           	logger.error("unsupported language: " + lang);
  686               throw new BSFException(BSFException.REASON_UNKNOWN_LANGUAGE,
  687                                      "unsupported language: " + lang);
  688           }
  689   
  690           // create the engine and initialize it. if anything goes wrong
  691           // except.
  692           try {
  693               Class engineClass =
  694                   (classLoader == null)
  695                   ? Class.forName(engineClassName)
  696                   : classLoader.loadClass(engineClassName);
  697               final BSFEngine engf = (BSFEngine) engineClass.newInstance();
  698               final BSFManager thisf = this;
  699               final String langf = lang;
  700               final Vector dbf = declaredBeans;
  701               AccessController.doPrivileged(new PrivilegedExceptionAction() {
  702                       public Object run() throws Exception {
  703                           engf.initialize(thisf, langf, dbf);
  704                           return null;
  705                       }
  706                   });
  707               eng = engf;
  708               loadedEngines.put(lang, eng);
  709               pcs.addPropertyChangeListener(eng);
  710               return eng;
  711           } catch (PrivilegedActionException prive) {
  712   
  713           	    logger.error("Exception :", prive);
  714                   throw (BSFException) prive.getException();
  715           } catch (Throwable t) {
  716   
  717           	logger.error("Exception :", t);
  718               throw new BSFException(BSFException.REASON_OTHER_ERROR,
  719                                      "unable to load language: " + lang,
  720                                      t);
  721           }
  722       }
  723   
  724       /**
  725        * return a handle to a bean registered in the bean registry by the
  726        * application or a scripting engine. Returns null if bean is not found.
  727        *
  728        * @param beanName name of bean to look up
  729        *
  730        * @return the bean if its found or null
  731        */
  732       public Object lookupBean(String beanName) {
  733       	logger.debug("BSFManager:lookupBean");
  734   
  735           try {
  736               return ((BSFDeclaredBean)objectRegistry.lookup(beanName)).bean;
  737           } catch (IllegalArgumentException e) {
  738   
  739           	logger.debug("Exception :", e);
  740               return null;
  741           }
  742       }
  743   
  744       /**
  745        * Registering a bean allows a scripting engine or the application to
  746        * access that bean by name and to manipulate it.
  747        *
  748        * @param beanName name to register under
  749        * @param bean     the bean to register
  750        */
  751       public void registerBean(String beanName, Object bean) {
  752       	logger.debug("BSFManager:registerBean");
  753   
  754           BSFDeclaredBean tempBean;
  755   
  756           if(bean == null) {
  757               tempBean = new BSFDeclaredBean(beanName, null, null);
  758           } else {
  759   
  760               tempBean = new BSFDeclaredBean(beanName, bean, bean.getClass());
  761           }
  762           objectRegistry.register(beanName, tempBean);
  763       }
  764   
  765       /**
  766        * Register a scripting engine in the static registry of the
  767        * BSFManager.
  768        *
  769        * @param lang string identifying language
  770        * @param engineClassName fully qualified name of the class interfacing
  771        *        the language to BSF.
  772        * @param extensions array of file extensions that should be mapped to
  773        *        this language type. may be null.
  774        */
  775       public static void registerScriptingEngine(String lang,
  776                                                  String engineClassName,
  777                                                  String[] extensions) {
  778           registeredEngines.put(lang, engineClassName);
  779           if (extensions != null) {
  780               for (int i = 0; i < extensions.length; i++) {
  781                   String langstr = (String) extn2Lang.get(extensions[i]);
  782                   langstr = (langstr == null) ? lang : lang + ":" + langstr;
  783                   extn2Lang.put(extensions[i], langstr);
  784               }
  785           }
  786       }
  787   
  788       /**
  789        * Set the class loader for those that need to use it. Default is he
  790        * who loaded me or null (i.e., its Class.forName).
  791        *
  792        * @param classLoader the class loader to use.
  793        */
  794       public void setClassLoader(ClassLoader classLoader) {
  795       	logger.debug("BSFManager:setClassLoader");
  796   
  797           pcs.firePropertyChange("classLoader", this.classLoader, classLoader);
  798           this.classLoader = classLoader;
  799       }
  800   
  801       /**
  802        * Set the classpath for those that need to use it. Default is the value
  803        * of the java.class.path property.
  804        *
  805        * @param classPath the classpath to use
  806        */
  807       public void setClassPath(String classPath) {
  808       	logger.debug("BSFManager:setClassPath");
  809   
  810           pcs.firePropertyChange("classPath", this.classPath, classPath);
  811           this.classPath = classPath;
  812       }
  813   
  814       /**
  815        * Set the object registry used by this manager. By default a new
  816        * one is created when the manager is new'ed and this overwrites
  817        * that one.
  818        *
  819        * @param objectRegistry the registry to use
  820        */
  821       public void setObjectRegistry(ObjectRegistry objectRegistry) {
  822       	logger.debug("BSFManager:setObjectRegistry");
  823   
  824           this.objectRegistry = objectRegistry;
  825       }
  826   
  827       /**
  828        * Temporary directory to put stuff into (for those who need to). Note
  829        * that unless this directory is in the classpath or unless the
  830        * classloader knows to look in here, any classes here will not
  831        * be found! BSFManager provides a service method to load a class
  832        * which uses either the classLoader provided by the class loader
  833        * property or, if that fails, a class loader which knows to load from
  834        * the tempdir to try to load the class. Default value of tempDir
  835        * is "." (current working dir).
  836        *
  837        * @param tempDir the temporary directory
  838        */
  839       public void setTempDir(String tempDir) {
  840       	logger.debug("BSFManager:setTempDir");
  841   
  842           pcs.firePropertyChange("tempDir", this.tempDir, tempDir);
  843           this.tempDir = tempDir;
  844       }
  845   
  846       /**
  847        * Gracefully terminate all engines
  848        */
  849       public void terminate() {
  850       	logger.debug("BSFManager:terminate");
  851   
  852           Enumeration enginesEnum = loadedEngines.elements();
  853           BSFEngine engine;
  854           while (enginesEnum.hasMoreElements()) {
  855               engine = (BSFEngine) enginesEnum.nextElement();
  856               engine.terminate();
  857           }
  858   
  859           loadedEngines = new Hashtable();
  860       }
  861   
  862       /**
  863        * Undeclare a previously declared bean. This removes the bean from
  864        * the list of declared beans in the manager as well as asks every
  865        * running engine to undeclared the bean. As with above, if any
  866        * of the engines except when asked to undeclare, this method does
  867        * not catch that exception. Quietly returns if the bean is unknown.
  868        *
  869        * @param beanName name of bean to undeclare
  870        *
  871        * @exception BSFException if any of the languages that are already
  872        *            running decides to throw an exception when asked to
  873        *            undeclare this bean.
  874        */
  875       public void undeclareBean(String beanName) throws BSFException {
  876       	logger.debug("BSFManager:undeclareBean");
  877   
  878           unregisterBean(beanName);
  879   
  880           BSFDeclaredBean tempBean = null;
  881           boolean found = false;
  882           for (Iterator i = declaredBeans.iterator(); i.hasNext();) {
  883               tempBean = (BSFDeclaredBean) i.next();
  884               if (tempBean.name.equals(beanName)) {
  885               	found = true;
  886                   break;
  887               }
  888           }
  889   
  890           if (found) {
  891               declaredBeans.removeElement(tempBean);
  892   
  893               Enumeration enginesEnum = loadedEngines.elements();
  894               while (enginesEnum.hasMoreElements()) {
  895                   BSFEngine engine = (BSFEngine) enginesEnum.nextElement();
  896                   engine.undeclareBean(tempBean);
  897               }
  898           }
  899       }
  900   
  901       /**
  902        * Unregister a previously registered bean. Silent if name is not found.
  903        *
  904        * @param beanName name of bean to unregister
  905        */
  906       public void unregisterBean(String beanName) {
  907       	logger.debug("BSFManager:unregisterBean");
  908   
  909           objectRegistry.unregister(beanName);
  910       }
  911   }

Save This Page
Home » bsf-src-2.4.0 » org.apache.bsf » [javadoc | source]