in src/main/java/org/apache/bsf/engines/netrexx/NetRexxEngine.java [247:450]
public Object execEvalShared (String source, int lineNo, int columnNo,
Object oscript,boolean returnsObject)
throws BSFException
{
Object retval=null;
String classname=null;
GeneratedFile gf=null;
// Moved into the exec process; see comment above.
Class rexxclass=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?
rexxclass=(Class)codeToClass.get(basescript);
if(rexxclass!=null)
{
logger.debug("NetRexxEngine: Found pre-compiled class" +
" for script '" + basescript + "'");
classname=rexxclass.getName();
}
else
{
gf=openUniqueFile(tempDir,"BSFNetRexx",".nrx");
if(gf==null)
throw new BSFException("couldn't create NetRexx scratchfile");
// Obtain classname
classname=gf.className;
// Decide whether to declare a return type
String returnsDecl="";
if(returnsObject)
returnsDecl="returns java.lang.Object";
// Write the kluge header to the file.
// ***** By doing so we give up the ability to use Property blocks.
gf.fos.write(("class "+classname+";\n")
.getBytes());
gf.fos.write(
("method BSFNetRexxEngineEntry(bsf=org.apache.bsf.util.BSFFunctions) "+
" public static "+returnsDecl+";\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();
}
}
BSFDeclaredBean tempBean;
String className;
for (int i = 0; i < declaredBeans.size (); i++)
{
tempBean = (BSFDeclaredBean) declaredBeans.elementAt (i);
className = StringUtils.getClassName (tempBean.type);
gf.fos.write ((tempBean.name + " =" + className + " bsf.lookupBean(\"" +
tempBean.name + "\");").getBytes());
}
if(returnsObject)
gf.fos.write("return ".getBytes());
// Copy the input to the file.
// Assumes all available -- probably mistake, but same as
// other engines.
gf.fos.write(script.getBytes());
gf.fos.close();
logger.debug("NetRexxEngine: wrote temp file " +
gf.file.getPath () + ", now compiling");
// Compile through Java to .class file
String command=gf.file.getPath(); //classname;
if (logger.isDebugEnabled()) {
command += " -verbose4";
} else {
command += " -noverbose";
command += " -noconsole";
}
netrexx.lang.Rexx cmdline= new netrexx.lang.Rexx(command);
int retValue;
// May not be threadsafe. Serialize access on static object:
synchronized(serializeCompilation)
{
// compile to a .java file
retValue =
COM.ibm.netrexx.process.NetRexxC.main(cmdline,
new PrintWriter(System.err));
}
// Check if there were errors while compiling the Rexx code.
if (retValue == 2)
{
throw new BSFException(BSFException.REASON_EXECUTION_ERROR,
"There were NetRexx errors.");
}
// Load class.
logger.debug("NetRexxEngine: loading class "+classname);
rexxclass=EngineUtils.loadClass (mgr, classname);
// Stash class for reuse
codeToClass.put(basescript,rexxclass);
}
Object[] args={mgrfuncs};
retval=callStatic(rexxclass, "BSFNetRexxEngineEntry",args);
}
catch (BSFException e)
{
// Just forward the exception on.
throw e;
}
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);
}
finally
{
// Cleanup: delete the .nrx and .class files
// (if any) generated by NetRexx Trace requests.
if(gf!=null && gf.file!=null && gf.file.exists())
gf.file.delete(); // .nrx file
if(classname!=null)
{
// Generated src
File file=new File(tempDir+File.separatorChar+classname+".java");
if(file.exists())
file.delete();
// Generated class
file=new File(classname+".class");
if(file.exists())
file.delete();
// Can this be done without disrupting trace?
file=new File(tempDir+File.separatorChar+classname+".crossref");
if(file.exists())
file.delete();
// Search for and clean up minor classes, classname$xxx.class
file=new File(tempDir);
minorPrefix=classname+"$"; // Indirect arg to filter
String[] minor_classfiles=
file.list(
// ANONYMOUS CLASS for filter:
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)
;
}
}
);
if(minor_classfiles!=null)
for(int i=minor_classfiles.length;i>0;)
{
file=new File(minor_classfiles[--i]);
file.delete();
}
}
}
return retval;
}