in src/main/java/org/apache/bsf/engines/java/JavaEngine.java [160:287]
public Object eval (final String source, final int lineNo, final int columnNo,
final Object oscript) throws BSFException
{
Object retval = null;
String classname = null;
GeneratedFile gf = null;
final 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) {
final 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);
}
final Object[] callArgs = {mgr};
retval = internalCall(this,"BSFJavaEngineEntry",callArgs);
}
catch(final 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
final String[] minorClassfiles = file.list(new FilenameFilter()
{
// Starts with classname$ and ends with .class
public boolean accept(final File dir,final 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;
}