1 55 56 package org.apache.bsf.engines.java; 57 58 import java.util.*; 59 import java.io.*; 60 import java.lang.*; 61 import java.lang.reflect.Method ; 62 63 import org.apache.bsf.*; 64 import org.apache.bsf.util.BSFEngineImpl; 65 import org.apache.bsf.util.EngineUtils; 66 import org.apache.bsf.util.*; 67 import org.apache.bsf.debug.util.DebugLog; 68 69 116 public class JavaEngine extends BSFEngineImpl 117 { 118 Class javaclass=null; 119 private boolean bsfHandleCreated = false; 120 static Hashtable codeToClass=new Hashtable(); 121 static String serializeCompilation=""; 122 static String placeholder="$$CLASSNAME$$"; 123 String minorPrefix; 124 125 132 private int uniqueFileOffset=-1; 133 private class GeneratedFile 134 { 135 File file=null; 136 FileOutputStream fos=null; 137 String className=null; 138 GeneratedFile(File file,FileOutputStream fos,String className) 139 { 140 this.file=file; 141 this.fos=fos; 142 this.className=className; 143 } 144 } 145 148 public JavaEngine () 149 { 150 } 152 public Object call (Object object, String method, Object [] args) 153 throws BSFException 154 { 155 throw new BSFException (BSFException.REASON_UNSUPPORTED_FEATURE, 156 "call() is not currently supported by JavaEngine"); 157 } 158 public void compileScript (String source, int lineNo, int columnNo, 159 Object script, CodeBuffer cb) throws BSFException { 160 ObjInfo oldRet = cb.getFinalServiceMethodStatement (); 161 162 if (oldRet != null && oldRet.isExecutable ()) { 163 cb.addServiceMethodStatement (oldRet.objName + ";"); 164 } 165 166 cb.addServiceMethodStatement (script.toString ()); 167 cb.setFinalServiceMethodStatement (null); 168 } 169 186 public Object eval (String source, int lineNo, int columnNo, 187 Object oscript) throws BSFException 188 { 189 if (debug) 190 { 191 debugStream.println("JavaEngine: tempDir=" + tempDir); 192 } 193 194 Object retval=null; 195 String classname=null; 196 GeneratedFile gf=null; 197 198 String basescript=oscript.toString(); 199 String script=basescript; 201 try { 202 javaclass=(Class )codeToClass.get(basescript); 204 205 if(javaclass!=null) 206 { 207 classname=javaclass.getName(); 208 } 209 else 210 { 211 gf=openUniqueFile(tempDir, "BSFJava",".java"); 212 if(gf==null) 213 throw new BSFException("couldn't create JavaEngine scratchfile"); 214 215 classname=gf.className; 217 218 gf.fos.write(("import java.lang.*;"+ 220 "import java.util.*;"+ 221 "public class "+classname+" {\n" + 222 " static public Object BSFJavaEngineEntry(org.apache.bsf.BSFManager bsf) {\n") 223 .getBytes()); 224 225 int startpoint,endpoint; 228 if((startpoint=script.indexOf(placeholder))>=0) 229 { 230 StringBuffer changed=new StringBuffer (); 231 for(; 232 startpoint>=0; 233 startpoint=script.indexOf(placeholder,startpoint)) 234 { 235 changed.setLength(0); if(startpoint>0) 237 changed.append(script.substring(0,startpoint)); 238 changed.append(classname); 239 endpoint=startpoint+placeholder.length(); 240 if(endpoint<script.length()) 241 changed.append(script.substring(endpoint)); 242 script=changed.toString(); 243 } 244 } 245 246 261 gf.fos.write(script.getBytes()); 264 gf.fos.write(("\n }\n}\n").getBytes()); 266 gf.fos.close(); 267 268 synchronized(serializeCompilation) 271 { 272 JavaUtils.JDKcompile(gf.file.getPath(), classPath); 273 } 274 275 javaclass=EngineUtils.loadClass (mgr, classname); 277 278 codeToClass.put(basescript,javaclass); 280 } 281 282 Object [] callArgs={mgr}; 283 retval=internal_call(this,"BSFJavaEngineEntry",callArgs); 284 } 285 286 287 catch(Exception e) 288 { 289 e.printStackTrace (); 290 throw new BSFException (BSFException.REASON_IO_ERROR, e.getMessage ()); 291 } 292 finally 293 { 294 296 299 300 if(classname!=null) 301 { 302 File file=new File(tempDir+File.separatorChar+classname+".class"); 304 307 file=new File(tempDir); minorPrefix=classname+"$"; String [] minor_classfiles= 311 file.list(new FilenameFilter() 312 { 313 public boolean accept(File dir,String name) 315 { 316 return 317 (0==name.indexOf(minorPrefix)) 318 && 319 (name.lastIndexOf(".class")==name.length()-6) 320 ; 321 } 322 }); 323 for(int i=0;i<minor_classfiles.length;++i) 324 { 325 file=new File(minor_classfiles[i]); 326 } 328 } 329 } 330 331 return retval; 332 } 333 public void initialize (BSFManager mgr, String lang, 334 Vector declaredBeans) throws BSFException { 335 super.initialize (mgr, lang, declaredBeans); 336 } 337 345 Object internal_call (Object object, String method, Object [] args) 346 throws BSFException 347 { 348 Object retval=null; 350 try 351 { 352 if(javaclass!=null) 353 { 354 Class [] argtypes=new Class [args.length]; 356 for(int i=0;i<args.length;++i) 357 argtypes[i]=args[i].getClass(); 358 359 Method m=MethodUtils.getMethod(javaclass,method,argtypes); 360 retval=m.invoke(null,args); 361 } 362 } 363 catch(Exception e) 364 { 365 throw new BSFException (BSFException.REASON_IO_ERROR, e.getMessage ()); 366 } 367 return retval; 368 } 369 private GeneratedFile openUniqueFile(String directory,String prefix,String suffix) 370 { 371 File file=null; 372 FileOutputStream fos=null; 373 int max=1000; GeneratedFile gf=null; 375 int i; 376 String className = null; 377 for(i=max,++uniqueFileOffset; 378 fos==null && i>0; 379 --i,++uniqueFileOffset) 380 { 381 try 383 { 384 className = prefix+uniqueFileOffset; 385 file=new File(directory+File.separatorChar+className+suffix); 386 if(file!=null && !file.exists()) 387 fos=new FileOutputStream(file); 388 } 389 catch(Exception e) 390 { 391 if(!file.exists()) 396 { 397 DebugLog.stderrPrintln("openUniqueFile: unexpected "+e, DebugLog.BSF_LOG_L0); 398 e.printStackTrace(); 399 } 400 } 401 } 402 if(fos==null) 403 DebugLog.stderrPrintln("openUniqueFile: Failed "+max+"attempts.", DebugLog.BSF_LOG_L0); 404 else 405 gf=new GeneratedFile(file,fos,className); 406 return gf; 407 } 408 } 409 | Popular Tags |