You are viewing a plain text version of this content. The canonical link for it is here.
Posted to bsf-dev@jakarta.apache.org by sa...@apache.org on 2006/09/02 20:13:31 UTC
svn commit: r439627 - in /jakarta/bsf/trunk: build.xml
src/org/apache/bsf/BSFManager.java src/org/apache/bsf/Main.java
src/org/apache/bsf/engines/java/JavaEngine.java
Author: sanka
Date: Sat Sep 2 11:13:30 2006
New Revision: 439627
URL: http://svn.apache.org/viewvc?rev=439627&view=rev
Log:
Applied the set of patches sent by Kev Jackson. Many thanks Kev ..
Modified:
jakarta/bsf/trunk/build.xml
jakarta/bsf/trunk/src/org/apache/bsf/BSFManager.java
jakarta/bsf/trunk/src/org/apache/bsf/Main.java
jakarta/bsf/trunk/src/org/apache/bsf/engines/java/JavaEngine.java
Modified: jakarta/bsf/trunk/build.xml
URL: http://svn.apache.org/viewvc/jakarta/bsf/trunk/build.xml?rev=439627&r1=439626&r2=439627&view=diff
==============================================================================
--- jakarta/bsf/trunk/build.xml (original)
+++ jakarta/bsf/trunk/build.xml Sat Sep 2 11:13:30 2006
@@ -62,7 +62,7 @@
<!-- =================================================================== -->
<patternset id="java.source.files">
<!-- Optionally includes engines based on dependencies being present -->
- <!-- FIXME: Exclude the first three, temporarily -->
+
<include name="**/bsf/*.java" />
<include name="**/util/**/*.java" />
@@ -179,7 +179,7 @@
<antcall target="checkJython" />
<antcall target="checkNetRexx" />
<antcall target="checkRhino" />
- <!--<echo message="Warning: Rhino dependencies were not resolved." unless="rhino.present"/>-->
+
<antcall target="checkXalan" />
<antcall target="checkJUnit" />
</target>
@@ -196,9 +196,11 @@
<mkdir dir="${build.dest}"/>
<javac srcdir="${src.dir}" destdir="${build.dest}" debug="${project.debug}" deprecation="${project.deprecation}">
<classpath>
- <fileset dir="lib"><include name="*.jar"/></fileset>
+ <fileset dir="lib">
+ <include name="*.jar"/>
+ </fileset>
</classpath>
- <patternset refid="java.source.files"></patternset>
+ <patternset refid="java.source.files"/>
</javac>
</target>
@@ -252,11 +254,11 @@
<classpath refid="anakia.classpath" />
</taskdef>
- <anakia basedir="${site.src}" destdir="${site.dest}/" extension=".html" style="./site.vsl" projectFile="${site.projectFile}" excludes="**/stylesheets/** faq.xml" includes="**/*.xml" lastModifiedCheck="true" templatePath="${templ.path}" velocityPropertiesFile="${velocity.props}">
- </anakia>
+ <anakia basedir="${site.src}" destdir="${site.dest}/" extension=".html" style="./site.vsl" projectFile="${site.projectFile}" excludes="**/stylesheets/** faq.xml" includes="**/*.xml" lastModifiedCheck="true" templatePath="${templ.path}" velocityPropertiesFile="${velocity.props}"/>
+
+
+ <anakia basedir="${site.src}" destdir="${site.dest}/" extension=".html" style="./faq.vsl" projectFile="${site.projectFile}" includes="faq.xml" lastModifiedCheck="true" templatePath="${templ.path}" velocityPropertiesFile="${velocity.props}"/>
- <anakia basedir="${site.src}" destdir="${site.dest}/" extension=".html" style="./faq.vsl" projectFile="${site.projectFile}" includes="faq.xml" lastModifiedCheck="true" templatePath="${templ.path}" velocityPropertiesFile="${velocity.props}">
- </anakia>
<copy todir="${site.dest}/images" filtering="no">
<fileset dir="${site.src}/images">
@@ -370,4 +372,4 @@
</target>
<target name="all" depends="build-site, dist" />
-</project>
+</project>
\ No newline at end of file
Modified: jakarta/bsf/trunk/src/org/apache/bsf/BSFManager.java
URL: http://svn.apache.org/viewvc/jakarta/bsf/trunk/src/org/apache/bsf/BSFManager.java?rev=439627&r1=439626&r2=439627&view=diff
==============================================================================
--- jakarta/bsf/trunk/src/org/apache/bsf/BSFManager.java (original)
+++ jakarta/bsf/trunk/src/org/apache/bsf/BSFManager.java Sat Sep 2 11:13:30 2006
@@ -25,6 +25,7 @@
import java.security.PrivilegedExceptionAction;
import java.util.Enumeration;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.MissingResourceException;
import java.util.NoSuchElementException;
import java.util.Properties;
@@ -114,16 +115,17 @@
Properties p = new Properties();
p.load(is);
- Enumeration keys = p.propertyNames();
- while (keys.hasMoreElements()) {
+ for (Enumeration keys = p.propertyNames(); keys.hasMoreElements();) {
+
String key = (String) keys.nextElement();
String value = p.getProperty(key);
+ String className = value.substring(0, value.indexOf(","));
+
+
- StringTokenizer tokens = new StringTokenizer(value, ",");
- String className = (String) tokens.nextToken();
// get the extensions for this language
- String exts = (String) tokens.nextToken();
+ String exts = value.substring(value.indexOf(",")+1, value.length());
StringTokenizer st = new StringTokenizer(exts, "|");
String[] extensions = new String[st.countTokens()];
for (int i = 0; st.hasMoreTokens(); i++) {
@@ -133,16 +135,16 @@
registerScriptingEngine(key, className, extensions);
}
}
- }
- catch (IOException ex) {
+ } catch (IOException ex) {
+
ex.printStackTrace();
System.err.println("Error reading Languages file " + ex);
- }
- catch (NoSuchElementException nsee) {
+ } catch (NoSuchElementException nsee) {
+
nsee.printStackTrace();
System.err.println("Syntax error in Languages resource bundle");
- }
- catch (MissingResourceException mre) {
+ } catch (MissingResourceException mre) {
+
mre.printStackTrace();
System.err.println("Initialization error: " + mre.toString());
}
@@ -163,8 +165,8 @@
* "dd" two digit day.
* @since 2006-01-17
*/
- public static String getVersion()
- {
+ public static String getVersion() {
+
return version;
}
@@ -210,8 +212,8 @@
}
});
result = resultf;
- }
- catch (PrivilegedActionException prive) {
+ } catch (PrivilegedActionException prive) {
+
logger.error("Exception: ", prive);
throw (BSFException) prive.getException();
}
@@ -263,8 +265,8 @@
return null;
}
});
- }
- catch (PrivilegedActionException prive) {
+ } catch (PrivilegedActionException prive) {
+
logger.error("Exception :", prive);
throw (BSFException) prive.getException();
}
@@ -306,8 +308,8 @@
return null;
}
});
- }
- catch (PrivilegedActionException prive) {
+ } catch (PrivilegedActionException prive) {
+
logger.error("Exception :", prive);
throw (BSFException) prive.getException();
}
@@ -350,8 +352,8 @@
return null;
}
});
- }
- catch (PrivilegedActionException prive) {
+ } catch (PrivilegedActionException prive) {
+
logger.error("Exception :", prive);
throw (BSFException) prive.getException();
}
@@ -439,8 +441,8 @@
}
});
result = resultf;
- }
- catch (PrivilegedActionException prive) {
+ } catch (PrivilegedActionException prive) {
+
logger.error("Exception: ", prive);
throw (BSFException) prive.getException();
}
@@ -487,8 +489,8 @@
return null;
}
});
- }
- catch (PrivilegedActionException prive) {
+ } catch (PrivilegedActionException prive) {
+
logger.error("Exception :", prive);
throw (BSFException) prive.getException();
}
@@ -527,8 +529,8 @@
return null;
}
});
- }
- catch (PrivilegedActionException prive) {
+ } catch (PrivilegedActionException prive) {
+
logger.error("Exception :", prive);
throw (BSFException) prive.getException();
}
@@ -550,8 +552,8 @@
if (classPath == null) {
try {
classPath = System.getProperty("java.class.path");
- }
- catch (Throwable t) {
+ } catch (Throwable t) {
+
logger.debug("Exception :", t);
// prolly a security exception .. so no can do
}
@@ -577,8 +579,9 @@
if (dotIndex != -1) {
String extn = fileName.substring(dotIndex + 1);
- String langval = (String) extn2Lang.get(extn), lang = null;
- int index = 0, loops = 0;
+ String langval = (String) extn2Lang.get(extn);
+ String lang = null;
+ int index, loops = 0;
if (langval != null) {
while ((index = langval.indexOf(":", 0)) != -1) {
@@ -594,8 +597,8 @@
String engineName =
(String) registeredEngines.get(lang);
Class.forName(engineName);
- }
- catch (ClassNotFoundException cnfe) {
+ } catch (ClassNotFoundException cnfe) {
+
// Bummer.
lang = langval;
continue;
@@ -604,7 +607,7 @@
// Got past that? Good.
break;
}
- if (loops == 0) lang = langval;
+ if (loops == 0) { lang = langval; }
}
if (lang != null && lang != "") {
@@ -700,12 +703,12 @@
loadedEngines.put(lang, eng);
pcs.addPropertyChangeListener(eng);
return eng;
- }
- catch (PrivilegedActionException prive) {
+ } catch (PrivilegedActionException prive) {
+
logger.error("Exception :", prive);
throw (BSFException) prive.getException();
- }
- catch (Throwable t) {
+ } catch (Throwable t) {
+
logger.error("Exception :", t);
throw new BSFException(BSFException.REASON_OTHER_ERROR,
"unable to load language: " + lang,
@@ -726,8 +729,8 @@
try {
return ((BSFDeclaredBean)objectRegistry.lookup(beanName)).bean;
- }
- catch (IllegalArgumentException e) {
+ } catch (IllegalArgumentException e) {
+
logger.debug("Exception :", e);
return null;
}
@@ -747,8 +750,8 @@
if(bean == null) {
tempBean = new BSFDeclaredBean(beanName, null, null);
- }
- else {
+ } else {
+
tempBean = new BSFDeclaredBean(beanName, bean, bean.getClass());
}
objectRegistry.register(beanName, tempBean);
@@ -871,8 +874,8 @@
BSFDeclaredBean tempBean = null;
boolean found = false;
- for (int i = 0; i < declaredBeans.size(); i++) {
- tempBean = (BSFDeclaredBean) declaredBeans.elementAt(i);
+ for (Iterator i = declaredBeans.iterator(); i.hasNext();) {
+ tempBean = (BSFDeclaredBean) i.next();
if (tempBean.name.equals(beanName)) {
found = true;
break;
@@ -900,4 +903,4 @@
objectRegistry.unregister(beanName);
}
-}
+}
\ No newline at end of file
Modified: jakarta/bsf/trunk/src/org/apache/bsf/Main.java
URL: http://svn.apache.org/viewvc/jakarta/bsf/trunk/src/org/apache/bsf/Main.java?rev=439627&r1=439626&r2=439627&view=diff
==============================================================================
--- jakarta/bsf/trunk/src/org/apache/bsf/Main.java (original)
+++ jakarta/bsf/trunk/src/org/apache/bsf/Main.java Sat Sep 2 11:13:30 2006
@@ -92,7 +92,7 @@
in = new FileReader(inFileName);
} else {
in = new InputStreamReader(System.in);
- inFileName = "<STDIN>";
+ inFileName = DEFAULT_IN_FILE_NAME;
}
BSFManager mgr = new BSFManager();
@@ -114,45 +114,47 @@
cb);
cb.print(pw, true);
out.close();
- } else
+ } else {
if (mode.equals(ARG_VAL_EXEC)) {
mgr.exec(language, inFileName, 0, 0, IOUtils.getStringFromReader(in));
- } else /* eval */ {
- Object obj =
- mgr.eval(language, inFileName, 0, 0, IOUtils.getStringFromReader(in));
-
+ } else { /* eval */
+ Object obj = mgr.eval(language, inFileName, 0, 0, IOUtils.getStringFromReader(in));
+
+
// Try to display the result.
-
+
if (obj instanceof java.awt.Component) {
- Frame f;
-
- if (obj instanceof Frame) {
- f = (Frame) obj;
- } else {
- f = new Frame ("BSF Result: " + inFileName);
- f.add ((java.awt.Component) obj);
- }
-
- // Add a window listener to quit on closing.
- f.addWindowListener(
- new WindowAdapter () {
- public void windowClosing (WindowEvent e) {
- System.exit (0);
- }
- });
- f.pack ();
- f.show ();
+ Frame f;
+ if (obj instanceof Frame) {
+ f = (Frame) obj;
+ } else {
+ f = new Frame ("BSF Result: " + inFileName);
+ f.add ((java.awt.Component) obj);
+ }
+ // Add a window listener to quit on closing.
+ f.addWindowListener(
+ new WindowAdapter () {
+ public void windowClosing (WindowEvent e) {
+ System.exit (0);
+ }
+ }
+ );
+ f.pack ();
+ f.show ();
+
} else {
- System.err.println("Result: " +
- obj);
+ System.err.println("Result: " + obj);
+
}
-
+
System.err.println("Result: " + obj);
}
+ }
} catch (BSFException e) {
- e.printStackTrace();
+ e.printStackTrace();
}
}
+
private static void printHelp() {
System.err.println("Usage:");
System.err.println();
@@ -183,4 +185,4 @@
System.err.println(
" [-out className] default: " + DEFAULT_CLASS_NAME);
}
-}
+}
\ No newline at end of file
Modified: jakarta/bsf/trunk/src/org/apache/bsf/engines/java/JavaEngine.java
URL: http://svn.apache.org/viewvc/jakarta/bsf/trunk/src/org/apache/bsf/engines/java/JavaEngine.java?rev=439627&r1=439626&r2=439627&view=diff
==============================================================================
--- jakarta/bsf/trunk/src/org/apache/bsf/engines/java/JavaEngine.java (original)
+++ jakarta/bsf/trunk/src/org/apache/bsf/engines/java/JavaEngine.java Sat Sep 2 11:13:30 2006
@@ -81,291 +81,271 @@
* <p>
* @author Joe Kesselman
*/
-public class JavaEngine extends BSFEngineImpl
-{
- Class javaclass=null;
- 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.
- */
- private int uniqueFileOffset=-1;
- 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;
- }
- }
- /**
- * Constructor.
- */
- public JavaEngine ()
- {
- // Do compilation-possible check here??????????????
- }
- public Object call (Object object, String method, Object[] args)
- throws BSFException
- {
- throw new BSFException (BSFException.REASON_UNSUPPORTED_FEATURE,
- "call() is not currently supported by JavaEngine");
- }
- public void compileScript (String source, int lineNo, int columnNo,
- Object script, CodeBuffer cb) throws BSFException {
- ObjInfo oldRet = cb.getFinalServiceMethodStatement ();
-
- if (oldRet != null && oldRet.isExecutable ()) {
- cb.addServiceMethodStatement (oldRet.objName + ";");
- }
-
- cb.addServiceMethodStatement (script.toString ());
- cb.setFinalServiceMethodStatement (null);
- }
- /**
- * This is used by an application to evaluate a string containing
- * some expression. It should store the "bsf" handle where the
- * script can get to it, for callback purposes.
- * <p>
- * Note that Java compilation imposes serious overhead,
- * but in exchange you get full Java performance
- * 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 protect it.
- * <p>
- * There is no published API for invoking javac as a class. There's a trick
- * that seems to work for Java 1.1.x, but it stopped working in Java 1.2.
- * We will attempt to use it, then if necessary fall back on invoking
- * javac via the command line.
- */
- public Object eval (String source, int lineNo, int columnNo,
- Object oscript) throws BSFException
- {
- Object retval=null;
- String classname=null;
- GeneratedFile gf=null;
-
- String basescript=oscript.toString();
- String script=basescript; // May be altered by $$CLASSNAME$$ expansion
-
- try {
- // Do we already have a class exactly matching this code?
- javaclass=(Class)codeToClass.get(basescript);
-
- if(javaclass!=null)
- {
- classname=javaclass.getName();
- }
- else
- {
- gf=openUniqueFile(tempDir, "BSFJava",".java");
- if(gf==null)
- throw new BSFException("couldn't create JavaEngine scratchfile");
-
- // Obtain classname
- classname=gf.className;
-
- // Write the kluge header to the file.
- gf.fos.write(("import java.lang.*;"+
- "import java.util.*;"+
- "public class "+classname+" {\n" +
- " static public Object BSFJavaEngineEntry(org.apache.bsf.BSFManager bsf) {\n")
- .getBytes());
-
- // Edit the script to replace placeholder with the generated
- // classname. Note that this occurs _after_ the cache was checked!
- int startpoint,endpoint;
- if((startpoint=script.indexOf(placeholder))>=0)
- {
- StringBuffer changed=new StringBuffer();
- for(;
- startpoint>=0;
- startpoint=script.indexOf(placeholder,startpoint))
- {
- changed.setLength(0); // Reset for 2nd pass or later
- if(startpoint>0)
- changed.append(script.substring(0,startpoint));
- changed.append(classname);
- endpoint=startpoint+placeholder.length();
- if(endpoint<script.length())
- changed.append(script.substring(endpoint));
- script=changed.toString();
- }
- }
-
- // MJD - debug
-// BSFDeclaredBean tempBean;
-// String className;
-//
-// for (int i = 0; i < declaredBeans.size (); i++) {
-// tempBean = (BSFDeclaredBean) declaredBeans.elementAt (i);
-// className = StringUtils.getClassName (tempBean.bean.getClass ());
-//
-// gf.fos.write ((className + " " +
-// tempBean.name + " = (" + className +
-// ")bsf.lookupBean(\"" +
-// tempBean.name + "\");").getBytes ());
-// }
- // MJD - debug
-
- // Copy the input to the file.
- // Assumes all available -- probably mistake, but same as other engines.
- gf.fos.write(script.getBytes());
- // Close the method and class
- gf.fos.write(("\n }\n}\n").getBytes());
- gf.fos.close();
-
- // Compile through Java to .class file
- // May not be threadsafe. Serialize access on static object:
- synchronized(serializeCompilation)
- {
- JavaUtils.JDKcompile(gf.file.getPath(), classPath);
- }
-
- // Load class.
- javaclass=EngineUtils.loadClass (mgr, classname);
-
- // Stash class for reuse
- codeToClass.put(basescript,javaclass);
- }
-
- Object[] callArgs={mgr};
- retval=internal_call(this,"BSFJavaEngineEntry",callArgs);
- }
-
-
- catch(Exception e)
- {
- e.printStackTrace ();
- throw new BSFException (BSFException.REASON_IO_ERROR, e.getMessage ());
- }
- finally
- {
- // Cleanup: delete the .java and .class files
-
-// if(gf!=null && gf.file!=null && gf.file.exists())
-// gf.file.delete(); // .java file
-
-
- if(classname!=null)
- {
- // Generated class
- File file=new File(tempDir+File.separatorChar+classname+".class");
-// if(file.exists())
-// file.delete();
-
- // Search for and clean up minor classes, classname$xxx.class
- file=new File(tempDir); // ***** Is this required?
- minorPrefix=classname+"$"; // Indirect arg to filter
- String[] minor_classfiles=
- file.list(new FilenameFilter()
- {
- // Starts with classname$ and ends with .class
- public boolean accept(File dir,String name)
- {
- return
- (0==name.indexOf(minorPrefix))
- &&
- (name.lastIndexOf(".class")==name.length()-6)
- ;
- }
- });
- for(int i=0;i<minor_classfiles.length;++i)
- {
- file=new File(minor_classfiles[i]);
-// file.delete();
- }
- }
- }
-
- return retval;
- }
- public void initialize (BSFManager mgr, String lang,
- Vector declaredBeans) throws BSFException {
- super.initialize (mgr, lang, declaredBeans);
- }
- /**
- * Return an object from an extension.
- * @param object Object on which to make the internal_call (ignored).
- * @param method The name of the method to internal_call.
- * @param args an array of arguments to be
- * passed to the extension, which may be either
- * Vectors of Nodes, or Strings.
- */
- Object internal_call (Object object, String method, Object[] args)
- throws BSFException
- {
- //***** ISSUE: Only static methods are currently supported
- Object retval=null;
- try
- {
- if(javaclass!=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(javaclass,method,argtypes);
- retval=m.invoke(null,args);
- }
- }
- catch(Exception e)
- {
- throw new BSFException (BSFException.REASON_IO_ERROR, e.getMessage ());
- }
- return retval;
- }
- private GeneratedFile openUniqueFile(String directory,String prefix,String suffix)
- {
- File file=null;
- FileOutputStream fos=null;
- int max=1000; // Don't try forever
- GeneratedFile gf=null;
- int i;
- String className = null;
- for(i=max,++uniqueFileOffset;
- fos==null && i>0;
- --i,++uniqueFileOffset)
- {
- // Probably a timing hazard here... ***************
- try
- {
- className = prefix+uniqueFileOffset;
- file=new File(directory+File.separatorChar+className+suffix);
- if(file!=null && !file.exists())
- fos=new FileOutputStream(file);
- }
- catch(Exception e)
- {
- // File could not be opened for write, or Security Exception
- // was thrown. If someone else created the file before we could
- // open it, that's probably a threading conflict and we don't
- // bother reporting it.
- if(!file.exists())
- {
- logger.error("openUniqueFile: unexpected ", e);
- }
- }
- }
- if(fos==null)
- logger.error("openUniqueFile: Failed "+max+"attempts.");
- else
- gf=new GeneratedFile(file,fos,className);
- return gf;
- }
-}
+public class JavaEngine extends BSFEngineImpl {
+ Class javaclass = null;
+ 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.
+ */
+ private int uniqueFileOffset = -1;
+
+ 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;
+ }
+ }
+
+ /**
+ * Constructor.
+ */
+ public JavaEngine () {
+ // Do compilation-possible check here??????????????
+ }
+
+ public Object call (Object object, String method, Object[] args)
+ throws BSFException
+ {
+ throw new BSFException (BSFException.REASON_UNSUPPORTED_FEATURE,
+ "call() is not currently supported by JavaEngine");
+ }
+
+ public void compileScript (String source, int lineNo, int columnNo,
+ Object script, CodeBuffer cb) throws BSFException {
+ ObjInfo oldRet = cb.getFinalServiceMethodStatement ();
+
+ if (oldRet != null && oldRet.isExecutable ()) {
+ cb.addServiceMethodStatement (oldRet.objName + ";");
+ }
+
+ cb.addServiceMethodStatement (script.toString ());
+ cb.setFinalServiceMethodStatement (null);
+ }
+
+ /**
+ * This is used by an application to evaluate a string containing
+ * some expression. It should store the "bsf" handle where the
+ * script can get to it, for callback purposes.
+ * <p>
+ * Note that Java compilation imposes serious overhead,
+ * but in exchange you get full Java performance
+ * 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 protect it.
+ * <p>
+ * There is no published API for invoking javac as a class. There's a trick
+ * that seems to work for Java 1.1.x, but it stopped working in Java 1.2.
+ * We will attempt to use it, then if necessary fall back on invoking
+ * javac via the command line.
+ */
+ public Object eval (String source, int lineNo, int columnNo,
+ Object oscript) throws BSFException
+ {
+ Object retval = null;
+ String classname = null;
+ GeneratedFile gf = null;
+
+ String basescript = oscript.toString();
+ String script = basescript; // May be altered by $$CLASSNAME$$ expansion
+
+ try {
+ // Do we already have a class exactly matching this code?
+ javaclass = (Class)codeToClass.get(basescript);
+
+ if(javaclass != null) {
+ classname=javaclass.getName();
+ } else {
+ gf = openUniqueFile(tempDir, "BSFJava",".java");
+ if( gf == null) {
+ throw new BSFException("couldn't create JavaEngine scratchfile");
+ }
+ // Obtain classname
+ classname = gf.className;
+
+ // Write the kluge header to the file.
+ gf.fos.write(("import java.lang.*;"+
+ "import java.util.*;"+
+ "public class "+classname+" {\n" +
+ " static public Object BSFJavaEngineEntry(org.apache.bsf.BSFManager bsf) {\n")
+ .getBytes());
+
+ // Edit the script to replace placeholder with the generated
+ // classname. Note that this occurs _after_ the cache was checked!
+ int startpoint = script.indexOf(placeholder);
+ int endpoint;
+ if(startpoint >= 0) {
+ StringBuffer changed = new StringBuffer();
+ for(; startpoint >=0; startpoint = script.indexOf(placeholder,startpoint)) {
+ changed.setLength(0); // Reset for 2nd pass or later
+ if(startpoint > 0) {
+ changed.append(script.substring(0,startpoint));
+ }
+ changed.append(classname);
+ endpoint = startpoint+placeholder.length();
+ if(endpoint < script.length()) {
+ changed.append(script.substring(endpoint));
+ }
+ script = changed.toString();
+ }
+ }
+
+ // MJD - debug
+// BSFDeclaredBean tempBean;
+// String className;
+//
+// for (int i = 0; i < declaredBeans.size (); i++) {
+// tempBean = (BSFDeclaredBean) declaredBeans.elementAt (i);
+// className = StringUtils.getClassName (tempBean.bean.getClass ());
+//
+// gf.fos.write ((className + " " +
+// tempBean.name + " = (" + className +
+// ")bsf.lookupBean(\"" +
+// tempBean.name + "\");").getBytes ());
+// }
+ // MJD - debug
+
+ // Copy the input to the file.
+ // Assumes all available -- probably mistake, but same as other engines.
+ gf.fos.write(script.getBytes());
+ // Close the method and class
+ gf.fos.write(("\n }\n}\n").getBytes());
+ gf.fos.close();
+
+ // Compile through Java to .class file
+ // May not be threadsafe. Serialize access on static object:
+ synchronized(serializeCompilation) {
+ JavaUtils.JDKcompile(gf.file.getPath(), classPath);
+ }
+
+ // Load class.
+ javaclass = EngineUtils.loadClass(mgr, classname);
+
+ // Stash class for reuse
+ codeToClass.put(basescript, javaclass);
+ }
+
+ Object[] callArgs = {mgr};
+ retval = internalCall(this,"BSFJavaEngineEntry",callArgs);
+ }
+
+
+ catch(Exception e) {
+ e.printStackTrace ();
+ throw new BSFException (BSFException.REASON_IO_ERROR, e.getMessage ());
+ } finally {
+ // Cleanup: delete the .java and .class files
+
+// if(gf!=null && gf.file!=null && gf.file.exists())
+// gf.file.delete(); // .java file
+
+
+ if(classname!=null) {
+ // Generated class
+ File file = new File(tempDir+File.separatorChar+classname+".class");
+// if(file.exists())
+// file.delete();
+
+ // Search for and clean up minor classes, classname$xxx.class
+ file = new File(tempDir); // ***** Is this required?
+ minorPrefix = classname+"$"; // Indirect arg to filter
+ String[] minorClassfiles = file.list(new FilenameFilter()
+ {
+ // Starts with classname$ and ends with .class
+ public boolean accept(File dir,String name) {
+ return
+ (0 == name.indexOf(minorPrefix))
+ &&
+ (name.lastIndexOf(".class") == name.length()-6);
+ }
+ });
+ for(int i = 0; i < minorClassfiles.length; ++i) {
+ file = new File(minorClassfiles[i]);
+// file.delete();
+ }
+ }
+ }
+ return retval;
+ }
+
+ public void initialize (BSFManager mgr, String lang,
+ Vector declaredBeans) throws BSFException {
+ super.initialize (mgr, lang, declaredBeans);
+ }
+ /**
+ * Return an object from an extension.
+ * @param object Object on which to make the internal_call (ignored).
+ * @param method The name of the method to internal_call.
+ * @param args an array of arguments to be
+ * passed to the extension, which may be either
+ * Vectors of Nodes, or Strings.
+ */
+ Object internalCall (Object object, String method, Object[] args)
+ throws BSFException
+ {
+ //***** ISSUE: Only static methods are currently supported
+ Object retval = null;
+ try {
+ if(javaclass != 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(javaclass, method, argtypes);
+ retval = m.invoke(null, args);
+ }
+ }
+ catch(Exception e) {
+ throw new BSFException (BSFException.REASON_IO_ERROR, e.getMessage ());
+ }
+ return retval;
+ }
+
+ private GeneratedFile openUniqueFile(String directory,String prefix,String suffix) {
+ File file = null;
+ FileOutputStream fos = null;
+ int max = 1000; // Don't try forever
+ GeneratedFile gf = null;
+ int i;
+ String className = null;
+ for(i=max,++uniqueFileOffset; fos==null && i>0;--i,++uniqueFileOffset) {
+ // Probably a timing hazard here... ***************
+ try {
+ className = prefix+uniqueFileOffset;
+ file = new File(directory+File.separatorChar+className+suffix);
+ if(file != null && !file.exists()) {
+ fos = new FileOutputStream(file);
+ }
+ }
+ catch(Exception e) {
+ // File could not be opened for write, or Security Exception
+ // was thrown. If someone else created the file before we could
+ // open it, that's probably a threading conflict and we don't
+ // bother reporting it.
+ if(!file.exists()) {
+ logger.error("openUniqueFile: unexpected ", e);
+ }
+ }
+ }
+ if(fos==null) {
+ logger.error("openUniqueFile: Failed "+max+"attempts.");
+ } else {
+ gf = new GeneratedFile(file,fos,className);
+ }
+ return gf;
+ }
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: bsf-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: bsf-dev-help@jakarta.apache.org