1 55 56 package org.apache.bsf.engines.netrexx; 57 58 import java.util.*; 59 import java.io.*; 60 import java.lang.*; 61 import java.lang.reflect.*; 62 63 import org.apache.bsf.*; 64 import org.apache.bsf.util.*; 65 import org.apache.bsf.debug.util.DebugLog; 66 67 110 public class NetRexxEngine extends BSFEngineImpl 111 { 112 BSFFunctions mgrfuncs; 113 private boolean bsfHandleCreated = false; 114 static Hashtable codeToClass=new Hashtable(); 115 static String serializeCompilation=""; 116 static String placeholder="$$CLASSNAME$$"; 117 String minorPrefix; 118 119 129 private static int uniqueFileOffset=0; 130 private class GeneratedFile 131 { 132 File file=null; 133 FileOutputStream fos=null; 134 String className=null; 135 GeneratedFile(File file,FileOutputStream fos,String className) 136 { 137 this.file=file; 138 this.fos=fos; 139 this.className=className; 140 } 141 } 142 143 149 152 public NetRexxEngine () 153 { 154 164 165 new netrexx.lang.BadArgumentException(); 166 } 167 175 public Object call (Object object,String method, Object [] args) 176 throws BSFException 177 { 178 throw new BSFException(BSFException.REASON_UNSUPPORTED_FEATURE, 179 "NetRexx doesn't currently support call()", 180 null); 181 } 182 190 Object callStatic(Class rexxclass, String method, Object [] args) 191 throws BSFException 192 { 193 Object retval = null; 195 try 196 { 197 if (rexxclass != null) 198 { 199 Class [] argtypes=new Class [args.length]; 201 for(int i=0;i<args.length;++i) 202 argtypes[i]=args[i].getClass(); 203 204 Method m=MethodUtils.getMethod(rexxclass, method, argtypes); 205 retval=m.invoke(null,args); 206 } 207 else 208 { 209 DebugLog.stderrPrintln ("NetRexxEngine: ERROR: rexxclass==null!", DebugLog.BSF_LOG_L3); 210 } 211 } 212 catch(Exception e) 213 { 214 e.printStackTrace (); 215 if (e instanceof InvocationTargetException) 216 { 217 Throwable t = ((InvocationTargetException)e).getTargetException (); 218 t.printStackTrace (); 219 } 220 throw new BSFException (BSFException.REASON_IO_ERROR, 221 e.getMessage (), 222 e); 223 } 224 return retval; 225 } 226 public void declareBean (BSFDeclaredBean bean) throws BSFException {} 227 239 public Object eval (String source, int lineNo, int columnNo, 240 Object script) 241 throws BSFException 242 { 243 return execEvalShared(source, lineNo, columnNo, script,true); 244 } 245 252 public void exec (String source, int lineNo, int columnNo, 253 Object script) 254 throws BSFException 255 { 256 execEvalShared(source, lineNo, columnNo, script,false); 257 } 258 273 public Object execEvalShared (String source, int lineNo, int columnNo, 274 Object oscript,boolean returnsObject) 275 throws BSFException 276 { 277 Object retval=null; 278 String classname=null; 279 GeneratedFile gf=null; 280 281 Class rexxclass=null; 283 284 String basescript=oscript.toString(); 285 String script=basescript; 287 try { 288 rexxclass=(Class )codeToClass.get(basescript); 290 291 if(rexxclass!=null) 292 { 293 DebugLog.debugPrintln ("NetRexxEngine: Found pre-compiled class" + 294 " for script '" + basescript + "'", DebugLog.BSF_LOG_L3); 295 classname=rexxclass.getName(); 296 } 297 else 298 { 299 gf=openUniqueFile(tempDir,"BSFNetRexx",".nrx"); 300 if(gf==null) 301 throw new BSFException("couldn't create NetRexx scratchfile"); 302 303 classname=gf.className; 305 306 String returnsDecl=""; 308 if(returnsObject) 309 returnsDecl="returns java.lang.Object"; 310 311 gf.fos.write(("class "+classname+";\n") 314 .getBytes()); 315 gf.fos.write( 316 ("method BSFNetRexxEngineEntry(bsf=org.apache.bsf.util.BSFFunctions) "+ 317 " public static "+returnsDecl+";\n") 318 .getBytes()); 319 320 int startpoint,endpoint; 324 if((startpoint=script.indexOf(placeholder))>=0) 325 { 326 StringBuffer changed=new StringBuffer (); 327 for(; 328 startpoint>=0; 329 startpoint=script.indexOf(placeholder,startpoint)) 330 { 331 changed.setLength(0); if(startpoint>0) 333 changed.append(script.substring(0,startpoint)); 334 changed.append(classname); 335 endpoint=startpoint+placeholder.length(); 336 if(endpoint<script.length()) 337 changed.append(script.substring(endpoint)); 338 script=changed.toString(); 339 } 340 } 341 342 BSFDeclaredBean tempBean; 343 String className; 344 345 for (int i = 0; i < declaredBeans.size (); i++) 346 { 347 tempBean = (BSFDeclaredBean) declaredBeans.elementAt (i); 348 className = StringUtils.getClassName (tempBean.type); 349 350 gf.fos.write ((tempBean.name + " =" + className + " bsf.lookupBean(\"" + 351 tempBean.name + "\");").getBytes()); 352 } 353 354 if(returnsObject) 355 gf.fos.write("return ".getBytes()); 356 357 gf.fos.write(script.getBytes()); 361 gf.fos.close(); 362 363 DebugLog.debugPrintln ("NetRexxEngine: wrote temp file " + 364 gf.file.getPath () + ", now compiling", DebugLog.BSF_LOG_L3); 365 366 String command=gf.file.getPath(); if (DebugLog.getLogLevel() >= 3) { 369 command += " -verbose4"; 370 } else { 371 command += " -noverbose"; 372 command += " -noconsole"; 373 } 374 375 netrexx.lang.Rexx cmdline= new netrexx.lang.Rexx(command); 376 int retValue; 377 378 synchronized(serializeCompilation) 380 { 381 retValue = 383 COM.ibm.netrexx.process.NetRexxC.main(cmdline, 384 new PrintWriter(DebugLog.getDebugStream())); 385 } 386 387 if (retValue == 2) 389 { 390 throw new BSFException(BSFException.REASON_EXECUTION_ERROR, 391 "There were NetRexx errors."); 392 } 393 394 DebugLog.debugPrintln ("NetRexxEngine: loading class "+classname, DebugLog.BSF_LOG_L3); 396 rexxclass=EngineUtils.loadClass (mgr, classname); 397 398 codeToClass.put(basescript,rexxclass); 400 } 401 402 Object [] args={mgrfuncs}; 403 retval=callStatic(rexxclass, "BSFNetRexxEngineEntry",args); 404 } 405 catch (BSFException e) 406 { 407 throw e; 409 } 410 catch(Exception e) 411 { 412 e.printStackTrace (); 413 if (e instanceof InvocationTargetException) 414 { 415 Throwable t = ((InvocationTargetException)e).getTargetException (); 416 t.printStackTrace (); 417 } 418 throw new BSFException (BSFException.REASON_IO_ERROR, 419 e.getMessage (), e); 420 } 421 finally 422 { 423 426 if(gf!=null && gf.file!=null && gf.file.exists()) 427 gf.file.delete(); 429 if(classname!=null) 430 { 431 File file=new File(tempDir+File.separatorChar+classname+".java"); 433 if(file.exists()) 434 file.delete(); 435 436 file=new File(classname+".class"); 438 if(file.exists()) 439 file.delete(); 440 441 file=new File(tempDir+File.separatorChar+classname+".crossref"); 443 if(file.exists()) 444 file.delete(); 445 446 file=new File(tempDir); 448 minorPrefix=classname+"$"; String [] minor_classfiles= 450 file.list( 451 new FilenameFilter() 453 { 454 public boolean accept(File dir,String name) 456 { 457 return 458 (0==name.indexOf(minorPrefix)) 459 && 460 (name.lastIndexOf(".class")==name.length()-6) 461 ; 462 } 463 } 464 ); 465 if(minor_classfiles!=null) 466 for(int i=minor_classfiles.length;i>0;) 467 { 468 file=new File(minor_classfiles[--i]); 469 file.delete(); 470 } 471 } 472 } 473 474 return retval; 475 } 476 public void initialize(BSFManager mgr, String lang,Vector declaredBeans) 477 throws BSFException 478 { 479 super.initialize(mgr, lang, declaredBeans); 480 mgrfuncs = new BSFFunctions (mgr, this); 481 } 482 private GeneratedFile openUniqueFile(String directory,String prefix,String suffix) 483 { 484 File file=null,obj=null; 485 FileOutputStream fos=null; 486 int max=1000; GeneratedFile gf=null; 488 int i; 489 String className = null; 490 for(i=max,++uniqueFileOffset; 491 fos==null && i>0; 492 --i,++uniqueFileOffset) 493 { 494 try 496 { 497 className = prefix+uniqueFileOffset; 498 file=new File(directory+File.separatorChar+className+suffix); 499 obj=new File(directory+File.separatorChar+className+".class"); 500 if(file!=null && !file.exists() & obj!=null & !obj.exists()) 501 fos=new FileOutputStream(file); 502 } 503 catch(Exception e) 504 { 505 if(!file.exists()) 510 { 511 DebugLog.stderrPrintln("openUniqueFile: unexpected "+e, DebugLog.BSF_LOG_L0); 512 } 513 } 514 } 515 if(fos==null) 516 DebugLog.stderrPrintln("openUniqueFile: Failed "+max+"attempts.", DebugLog.BSF_LOG_L0); 517 else 518 gf=new GeneratedFile(file,fos,className); 519 return gf; 520 } 521 522 public void undeclareBean (BSFDeclaredBean bean) throws BSFException {} 523 } 524 | Popular Tags |