📄 netrexxengine.java
字号:
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; } public void initialize(BSFManager mgr, String lang,Vector declaredBeans) throws BSFException { super.initialize(mgr, lang, declaredBeans); mgrfuncs = new BSFFunctions (mgr, this); }private GeneratedFile openUniqueFile(String directory,String prefix,String suffix) { File file=null,obj=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); obj=new File(directory+File.separatorChar+className+".class"); if(file!=null && !file.exists() & obj!=null & !obj.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 void undeclareBean (BSFDeclaredBean bean) throws BSFException {}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -