1 22 23 package org.gjt.sp.jedit; 24 25 import bsh.*; 27 import bsh.classpath.ClassManagerImpl; 28 29 import java.io.*; 30 import java.lang.ref.*; 31 import java.lang.reflect.InvocationTargetException ; 32 import java.util.*; 33 import org.gjt.sp.jedit.io.*; 34 import org.gjt.sp.jedit.gui.BeanShellErrorDialog; 35 import org.gjt.sp.jedit.textarea.*; 36 import org.gjt.sp.util.Log; 37 39 59 public class BeanShell 60 { 61 private static final String REQUIRED_VERSION = "2.0b1.1-jedit-1"; 62 63 68 public static void evalSelection(View view, JEditTextArea textArea) 69 { 70 String command = textArea.getSelectedText(); 71 if(command == null) 72 { 73 view.getToolkit().beep(); 74 return; 75 } 76 Object returnValue = eval(view,global,command); 77 if(returnValue != null) 78 textArea.setSelectedText(returnValue.toString()); 79 } 81 86 public static void showEvaluateDialog(View view) 87 { 88 String command = GUIUtilities.input(view,"beanshell-eval-input",null); 89 if(command != null) 90 { 91 if(!command.endsWith(";")) 92 command = command + ";"; 93 94 int repeat = view.getInputHandler().getRepeatCount(); 95 96 if(view.getMacroRecorder() != null) 97 { 98 view.getMacroRecorder().record(repeat,command); 99 } 100 101 Object returnValue = null; 102 try 103 { 104 for(int i = 0; i < repeat; i++) 105 { 106 returnValue = _eval(view,global,command); 107 } 108 } 109 catch(Throwable e) 110 { 111 Log.log(Log.ERROR,BeanShell.class,e); 112 113 handleException(view,null,e); 114 } 115 116 if(returnValue != null) 117 { 118 String [] args = { returnValue.toString() }; 119 GUIUtilities.message(view,"beanshell-eval",args); 120 } 121 } 122 } 124 129 public static void showEvaluateLinesDialog(View view) 130 { 131 String command = GUIUtilities.input(view,"beanshell-eval-line",null); 132 133 JEditTextArea textArea = view.getTextArea(); 134 Buffer buffer = view.getBuffer(); 135 136 if(command == null || command.length() == 0) 137 return; 138 139 Selection[] selection = textArea.getSelection(); 140 if(selection.length == 0) 141 { 142 view.getToolkit().beep(); 143 return; 144 } 145 146 if(!command.endsWith(";")) 147 command = command + ";"; 148 149 String script = "int[] lines = textArea.getSelectedLines();\n" 150 + "for(int i = 0; i < lines.length; i++)\n" 151 + "{\n" 152 + "line = lines[i];\n" 153 + "index = line - lines[0];\n" 154 + "start = buffer.getLineStartOffset(line);\n" 155 + "end = buffer.getLineEndOffset(line);\n" 156 + "text = buffer.getText(start,end - start - 1);\n" 157 + "newText = " + command + "\n" 158 + "if(newText != null)\n" 159 + "{\n" 160 + "buffer.remove(start,end - start - 1);\n" 161 + "buffer.insert(start,String.valueOf(newText));\n" 162 + "}\n" 163 + "}\n"; 164 165 if(view.getMacroRecorder() != null) 166 view.getMacroRecorder().record(1,script); 167 168 try 169 { 170 buffer.beginCompoundEdit(); 171 172 BeanShell.eval(view,global,script); 173 } 174 finally 175 { 176 buffer.endCompoundEdit(); 177 } 178 179 textArea.selectNone(); 180 } 182 207 public static void runScript(View view, String path, Reader in, 208 boolean ownNamespace) 209 { 210 try 211 { 212 _runScript(view,path,in,ownNamespace); 213 } 214 catch(Throwable e) 215 { 216 Log.log(Log.ERROR,BeanShell.class,e); 217 218 handleException(view,path,e); 219 } 220 } 222 242 public static void runScript(View view, String path, Reader in, 243 NameSpace namespace) 244 { 245 try 246 { 247 _runScript(view,path,in,namespace); 248 } 249 catch(Throwable e) 250 { 251 Log.log(Log.ERROR,BeanShell.class,e); 252 253 handleException(view,path,e); 254 } 255 } 257 283 public static void _runScript(View view, String path, Reader in, 284 boolean ownNamespace) throws Exception 285 { 286 _runScript(view,path,in,ownNamespace 287 ? new NameSpace(global,"namespace") 288 : global); 289 } 291 312 public static void _runScript(View view, String path, Reader in, 313 NameSpace namespace) throws Exception 314 { 315 Log.log(Log.MESSAGE,BeanShell.class,"Running script " + path); 316 317 Interpreter interp = createInterpreter(namespace); 318 319 VFS vfs = null; 320 Object session = null; 321 322 try 323 { 324 if(in == null) 325 { 326 Buffer buffer = jEdit.openTemporary(null, 327 null,path,false); 328 329 if(!buffer.isLoaded()) 330 VFSManager.waitForRequests(); 331 332 in = new StringReader(buffer.getText(0, 333 buffer.getLength())); 334 } 335 336 setupDefaultVariables(namespace,view); 337 interp.set("scriptPath",path); 338 339 running = true; 340 341 interp.eval(in,namespace,path); 342 } 343 catch(Exception e) 344 { 345 unwrapException(e); 346 } 347 finally 348 { 349 running = false; 350 351 if(session != null) 352 { 353 try 354 { 355 vfs._endVFSSession(session,view); 356 } 357 catch(IOException io) 358 { 359 Log.log(Log.ERROR,BeanShell.class,io); 360 GUIUtilities.error(view,"read-error", 361 new String [] { path, io.toString() }); 362 } 363 } 364 365 try 366 { 367 if(namespace == global) 369 { 370 resetDefaultVariables(namespace); 371 interp.unset("scriptPath"); 372 } 373 } 374 catch(EvalError e) 375 { 376 } 378 } 379 } 381 392 public static Object eval(View view, NameSpace namespace, String command) 393 { 394 try 395 { 396 return _eval(view,namespace,command); 397 } 398 catch(Throwable e) 399 { 400 Log.log(Log.ERROR,BeanShell.class,e); 401 402 handleException(view,null,e); 403 } 404 405 return null; 406 } 408 422 public static Object _eval(View view, NameSpace namespace, String command) 423 throws Exception 424 { 425 Interpreter interp = createInterpreter(namespace); 426 427 try 428 { 429 setupDefaultVariables(namespace,view); 430 if(Debug.BEANSHELL_DEBUG) 431 Log.log(Log.DEBUG,BeanShell.class,command); 432 return interp.eval(command); 433 } 434 catch(Exception e) 435 { 436 unwrapException(e); 437 return null; 439 } 440 finally 441 { 442 try 443 { 444 resetDefaultVariables(namespace); 445 } 446 catch(UtilEvalError e) 447 { 448 } 450 } 451 } 453 464 public static BshMethod cacheBlock(String id, String code, boolean namespace) 465 throws Exception 466 { 467 String name = "__internal_" + id; 468 469 if(namespace) 471 { 472 _eval(null,global,name + "(ns) {\nthis.callstack.set(0,ns);\n" + code + "\n}"); 473 return global.getMethod(name,new Class [] { NameSpace.class }); 474 } 475 else 476 { 477 _eval(null,global,name + "() {\n" + code + "\n}"); 478 return global.getMethod(name,new Class [0]); 479 } 480 } 482 493 public static Object runCachedBlock(BshMethod method, View view, 494 NameSpace namespace) throws Exception 495 { 496 boolean useNamespace; 497 if(namespace == null) 498 { 499 useNamespace = false; 500 namespace = global; 501 } 502 else 503 useNamespace = true; 504 505 try 506 { 507 setupDefaultVariables(namespace,view); 508 509 Object retVal = method.invoke(useNamespace 510 ? new Object [] { namespace } 511 : NO_ARGS, 512 interpForMethods,new CallStack(), null); 513 if(retVal instanceof Primitive) 514 { 515 if(retVal == Primitive.VOID) 516 return null; 517 else 518 return ((Primitive)retVal).getValue(); 519 } 520 else 521 return retVal; 522 } 523 catch(Exception e) 524 { 525 unwrapException(e); 526 return null; 528 } 529 finally 530 { 531 resetDefaultVariables(namespace); 532 } 533 } 535 540 public static boolean isScriptRunning() 541 { 542 return running; 543 } 545 550 public static NameSpace getNameSpace() 551 { 552 return global; 553 } 555 557 563 public static void runScript(View view, String path, 564 boolean ownNamespace, boolean rethrowBshErrors) 565 { 566 runScript(view,path,null,ownNamespace); 567 } 569 575 public static void runScript(View view, String path, Reader in, 576 boolean ownNamespace, boolean rethrowBshErrors) 577 { 578 runScript(view,path,in,ownNamespace); 579 } 581 586 public static Object eval(View view, String command, 587 boolean rethrowBshErrors) 588 { 589 return eval(view,global,command); 590 } 592 597 public static Object eval(View view, NameSpace namespace, 598 String command, boolean rethrowBshErrors) 599 { 600 return eval(view,namespace,command); 601 } 603 605 607 static void init() 609 { 610 621 622 classManager = new ClassManagerImpl(); 623 classManager.setClassLoader(new JARClassLoader()); 624 625 global = new NameSpace(classManager, 626 "jEdit embedded BeanShell interpreter"); 627 global.importPackage("org.gjt.sp.jedit"); 628 global.importPackage("org.gjt.sp.jedit.browser"); 629 global.importPackage("org.gjt.sp.jedit.buffer"); 630 global.importPackage("org.gjt.sp.jedit.gui"); 631 global.importPackage("org.gjt.sp.jedit.help"); 632 global.importPackage("org.gjt.sp.jedit.io"); 633 global.importPackage("org.gjt.sp.jedit.menu"); 634 global.importPackage("org.gjt.sp.jedit.msg"); 635 global.importPackage("org.gjt.sp.jedit.options"); 636 global.importPackage("org.gjt.sp.jedit.pluginmgr"); 637 global.importPackage("org.gjt.sp.jedit.print"); 638 global.importPackage("org.gjt.sp.jedit.search"); 639 global.importPackage("org.gjt.sp.jedit.syntax"); 640 global.importPackage("org.gjt.sp.jedit.textarea"); 641 global.importPackage("org.gjt.sp.util"); 642 643 interpForMethods = createInterpreter(global); 644 } 646 651 static void resetClassManager() 652 { 653 classManager.reset(); 654 } 656 658 660 private static final Object [] NO_ARGS = new Object [0]; 662 private static BshClassManager classManager; 663 private static Interpreter interpForMethods; 664 private static NameSpace global; 665 private static boolean running; 666 668 private static void setupDefaultVariables(NameSpace namespace, View view) 670 throws UtilEvalError 671 { 672 if(view != null) 673 { 674 EditPane editPane = view.getEditPane(); 675 namespace.setVariable("view",view, false); 676 namespace.setVariable("editPane",editPane, false); 677 namespace.setVariable("buffer",editPane.getBuffer(), false); 678 namespace.setVariable("textArea",editPane.getTextArea(), false); 679 namespace.setVariable("wm",view.getDockableWindowManager(), false); 680 } 681 } 683 private static void resetDefaultVariables(NameSpace namespace) 685 throws UtilEvalError 686 { 687 namespace.setVariable("view",null, false); 688 namespace.setVariable("editPane",null, false); 689 namespace.setVariable("buffer",null, false); 690 namespace.setVariable("textArea",null, false); 691 namespace.setVariable("wm",null, false); 692 } 694 699 private static void unwrapException(Exception e) throws Exception 700 { 701 if(e instanceof TargetError) 702 { 703 Throwable t = ((TargetError)e).getTarget(); 704 if(t instanceof Exception ) 705 throw (Exception )t; 706 else if(t instanceof Error ) 707 throw (Error )t; 708 } 709 710 if(e instanceof InvocationTargetException ) 711 { 712 Throwable t = ((InvocationTargetException )e).getTargetException(); 713 if(t instanceof Exception ) 714 throw (Exception )t; 715 else if(t instanceof Error ) 716 throw (Error )t; 717 } 718 719 throw e; 720 } 722 private static void handleException(View view, String path, Throwable t) 724 { 725 if(t instanceof IOException) 726 { 727 VFSManager.error(view,path,"ioerror.read-error", 728 new String [] { t.toString() }); 729 } 730 else 731 new BeanShellErrorDialog(view,t); 732 } 734 private static Interpreter createInterpreter(NameSpace nameSpace) 736 { 737 return new Interpreter(null,System.out,System.err,false,nameSpace); 738 } 740 private static String getVersion() 742 { 743 try 744 { 745 return (String )Interpreter.class.getField("VERSION").get(null); 746 } 747 catch(Exception e) 748 { 749 return "unknown"; 750 } 751 } 753 755 static class CustomClassManager extends ClassManagerImpl 757 { 758 private LinkedList listeners = new LinkedList(); 759 private ReferenceQueue refQueue = new ReferenceQueue(); 760 761 public synchronized void addListener( Listener l ) 763 { 764 listeners.add( new WeakReference( l, refQueue) ); 765 766 Reference deadref; 768 while ( (deadref = refQueue.poll()) != null ) 769 { 770 boolean ok = listeners.remove( deadref ); 771 if ( ok ) 772 { 773 } 775 else 776 { 777 if ( Interpreter.DEBUG ) Interpreter.debug( 778 "tried to remove non-existent weak ref: "+deadref); 779 } 780 } 781 } 782 783 public void removeListener( Listener l ) 784 { 785 throw new Error ("unimplemented"); 786 } 787 788 public void reset() 789 { 790 classLoaderChanged(); 791 } 792 793 protected synchronized void classLoaderChanged() 794 { 795 clearCaches(); 797 if (listeners != null) 798 { 799 800 for (Iterator iter = listeners.iterator(); 801 iter.hasNext(); ) 802 { 803 WeakReference wr = (WeakReference) 804 iter.next(); 805 Listener l = (Listener)wr.get(); 806 if ( l == null ) iter.remove(); 808 else 809 l.classLoaderChanged(); 810 } 811 } 812 } 813 } } 815 | Popular Tags |