in src/main/java/org/apache/bsf/engines/java/JavaEngine.java [140:256]
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 StringBuilder changed = new StringBuilder();
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;
}