⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netrexxengine.java

📁 Bean Scripting Framework (BSF)为在java应用中使用脚本语言
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 2004,2004 The Apache Software Foundation. *  * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *  *      http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.bsf.engines.netrexx;import java.io.File;import java.io.FileOutputStream;import java.io.FilenameFilter;import java.io.PrintWriter;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Hashtable;import java.util.Vector;import org.apache.bsf.BSFDeclaredBean;import org.apache.bsf.BSFException;import org.apache.bsf.BSFManager;import org.apache.bsf.util.BSFEngineImpl;import org.apache.bsf.util.BSFFunctions;import org.apache.bsf.util.EngineUtils;import org.apache.bsf.util.MethodUtils;import org.apache.bsf.util.StringUtils;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;/** * This is the interface to NetRexx from the * Bean Scripting Framework. * <p> * The NetRexx code must be written script-style, without a "class" or * "properties" section preceeding the executable code. The NetRexxEngine will * generate a prefix for this code: * <pre> * <code> * class $$CLASSNAME$$; * method BSFNetRexxEngineEntry(bsf=org.apache.bsf.BSFManager) public static; * </code> * </pre> * $$CLASSNAME$$ will be replaced by a generated classname of the form * BSFNetRexx*, and the bsf parameter can be used to retrieve application * objects registered with the Bean Scripting Framework. * <p> * If you use the placeholder string $$CLASSNAME$$ elsewhere * in your script -- including within text strings -- BSFNetRexxEngine will * replace it with the generated name of the class before the NetRexx code * is compiled. * <p> * If you need to use full NetRexx functionality, we recommend that your * NetRexx script define and invoke a "minor class", with or without the * "dependent" keyword as suits your needs. You'll have to use $$CLASSNAME$$ * in naming the minor class, since the name of the main class is synthesized; * for example, to create the minor class "bar" you'd write * "class $$CLASSNAME$$.Bar". * <p> * <h2>Hazards:</h2> * <p> * Since NetRexx has to be _compiled_ to a Java classfile, invoking it involves * a fair amount of computation to load and execute the compiler. We are * currently making an attempt to manage that by caching the class * after it has been loaded, but the indexing is fairly primitive; we * hash against the script string to find the class for it. * <p> * Minor-class .class files are now being deleted after the major class loads. * This coould potentially cause problems. * * @author  Joe Kesselman * @author  Sanjiva Weerawarana */public class NetRexxEngine extends BSFEngineImpl{	BSFFunctions mgrfuncs;	static Hashtable codeToClass=new Hashtable();	static String serializeCompilation="";	static String placeholder="$$CLASSNAME$$";	String minorPrefix;		private Log logger = LogFactory.getLog(this.getClass().getName());	  	/**	 * Create a scratchfile, open it for writing, return its name.	 * Relies on the filesystem to provide us with uniqueness testing.	 * NOTE THAT uniqueFileOffset continues to count; we don't want to	 * risk reusing a classname we have previously loaded in this session	 * even if the classfile has been deleted.	 *	 * I've made the offset static, due to concerns about reuse/reentrancy	 * of the NetRexx engine.	 */  private static int uniqueFileOffset=0;  private class GeneratedFile   {	File file=null;	FileOutputStream fos=null;	String className=null;	GeneratedFile(File file,FileOutputStream fos,String className) 	  {		  this.file=file;		  this.fos=fos;		  this.className=className;	  }  }		// rexxclass used to be an instance variable, on the theory that	// each NetRexxEngine was an instance of a specific script.	// BSF is currently reusing Engines, so caching the class	// no longer makes sense.	// Class rexxclass;		/**	 * Constructor.	 */	public NetRexxEngine ()	{		/*		  The following line is intended to cause the constructor to		  throw a NoClassDefFoundError if the NetRexxC.zip dependency		  is not resolved.		  		  If this line was not here, the problem would not surface until		  the actual processing of a script. We want to know all is well		  at the time the engine is instantiated, not when we attempt to		  process a script.		  */				new netrexx.lang.BadArgumentException();	}	/**	 * Return an object from an extension.	 * @param object object from which to call our static method	 * @param method The name of the method to call.	 * @param args an array of arguments to be	 * passed to the extension, which may be either	 * Vectors of Nodes, or Strings.	 */	public Object call (Object object, String method, Object[] args) 	throws BSFException	{		throw new BSFException(BSFException.REASON_UNSUPPORTED_FEATURE,							   "NetRexx doesn't currently support call()",							   null);	}	/**	 * Invoke a static method.	 * @param rexxclass Class to invoke the method against	 * @param method The name of the method to call.	 * @param args an array of arguments to be	 * passed to the extension, which may be either	 * Vectors of Nodes, or Strings.	 */	Object callStatic(Class rexxclass, String method, Object[] args) 	throws BSFException	{		//***** ISSUE: Currently supports only static methods		Object retval = null;		try		{			if (rexxclass != null)			{				//***** This should call the lookup used in BML, for typesafety				Class[] argtypes=new Class[args.length];				for(int i=0;i<args.length;++i)					argtypes[i]=args[i].getClass();								Method m=MethodUtils.getMethod(rexxclass, method, argtypes);				retval=m.invoke(null,args);			}			else			{				logger.error("NetRexxEngine: ERROR: rexxclass==null!");			}		}		catch(Exception e)		{			e.printStackTrace ();			if (e instanceof InvocationTargetException)			{				Throwable t = ((InvocationTargetException)e).getTargetException ();				t.printStackTrace ();			}			throw new BSFException (BSFException.REASON_IO_ERROR,									e.getMessage (),									e);		}		return retval;	}	public void declareBean (BSFDeclaredBean bean) throws BSFException {}	/**	 * Override impl of execute. In NetRexx, methods which do not wish	 * to return a value should be invoked via exec, which will cause them	 * to be generated without the "returns" clause.	 * Those which wish to return a value should call eval instead.	 * which will add "returns java.lang.Object" to the header.	 *	 * Note: It would be nice to have the "real" return type avaialable, so	 * we could do something more type-safe than Object, and so we could	 * return primitive types without having to enclose them in their	 * object wrappers. BSF does not currently support that concept.	 */	public Object eval (String source, int lineNo, int columnNo,					Object script)	throws BSFException	{		return execEvalShared(source, lineNo, columnNo, script,true);	}	/**	 * Override impl of execute. In NetRexx, methods which do not wish	 * to return a value should be invoked via exec, which will cause them	 * to be generated without the "returns" clause.	 * Those which wish to return a value should call eval instead.	 * which will add "returns java.lang.Object" to the header.	 */	public void exec (String source, int lineNo, int columnNo,				  Object script)	throws BSFException	{		 execEvalShared(source, lineNo, columnNo, script,false);	}	/**	 * This is shared code for the exec() and eval() operations. It will	 * evaluate a string containing a NetRexx method body -- which may be	 * as simple as a single return statement.	 * It should store the "bsf" handle where the	 * script can get to it, for callback purposes.	 * <p>	 * Note that NetRexx compilation imposes serious overhead -- 11 seconds for	 * the first compile, about 3 thereafter -- but in exchange you get	 * Java-like speeds once the classes have been created (minus the cache	 * lookup cost).	 * <p>	 * Nobody knows whether javac is threadsafe.	 * I'm going to serialize access to the compilers to protect it.	 */	public Object execEvalShared (String source, int lineNo, int columnNo, 							  Object oscript,boolean returnsObject)	throws BSFException	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -