Source Code Cross Referenced for Interpreter.java in  » Swing-Library » jEdit » org » gjt » sp » jedit » bsh » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Swing Library » jEdit » org.gjt.sp.jedit.bsh 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*****************************************************************************
0002:         *                                                                           *
0003:         *  This file is part of the BeanShell Java Scripting distribution.          *
0004:         *  Documentation and updates may be found at http://www.beanshell.org/      *
0005:         *                                                                           *
0006:         *  Sun Public License Notice:                                               *
0007:         *                                                                           *
0008:         *  The contents of this file are subject to the Sun Public License Version  *
0009:         *  1.0 (the "License"); you may not use this file except in compliance with *
0010:         *  the License. A copy of the License is available at http://www.sun.com    * 
0011:         *                                                                           *
0012:         *  The Original Code is BeanShell. The Initial Developer of the Original    *
0013:         *  Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright     *
0014:         *  (C) 2000.  All Rights Reserved.                                          *
0015:         *                                                                           *
0016:         *  GNU Public License Notice:                                               *
0017:         *                                                                           *
0018:         *  Alternatively, the contents of this file may be used under the terms of  *
0019:         *  the GNU Lesser General Public License (the "LGPL"), in which case the    *
0020:         *  provisions of LGPL are applicable instead of those above. If you wish to *
0021:         *  allow use of your version of this file only under the  terms of the LGPL *
0022:         *  and not to allow others to use your version of this file under the SPL,  *
0023:         *  indicate your decision by deleting the provisions above and replace      *
0024:         *  them with the notice and other provisions required by the LGPL.  If you  *
0025:         *  do not delete the provisions above, a recipient may use your version of  *
0026:         *  this file under either the SPL or the LGPL.                              *
0027:         *                                                                           *
0028:         *  Patrick Niemeyer (pat@pat.net)                                           *
0029:         *  Author of Learning Java, O'Reilly & Associates                           *
0030:         *  http://www.pat.net/~pat/                                                 *
0031:         *                                                                           *
0032:         *****************************************************************************/package org.gjt.sp.jedit.bsh;
0033:
0034:        import java.io.*;
0035:        import java.lang.reflect.Method;
0036:        import java.lang.reflect.InvocationTargetException;
0037:
0038:        /**
0039:         The BeanShell script interpreter.
0040:
0041:         An instance of Interpreter can be used to source scripts and evaluate 
0042:         statements or expressions.  
0043:         <p>
0044:         Here are some examples:
0045:
0046:         <p><blockquote><pre>
0047:         Interpeter bsh = new Interpreter();
0048:
0049:         // Evaluate statements and expressions
0050:         bsh.eval("foo=Math.sin(0.5)");
0051:         bsh.eval("bar=foo*5; bar=Math.cos(bar);");
0052:         bsh.eval("for(i=0; i<10; i++) { print(\"hello\"); }");
0053:         // same as above using java syntax and apis only
0054:         bsh.eval("for(int i=0; i<10; i++) { System.out.println(\"hello\"); }");
0055:
0056:         // Source from files or streams
0057:         bsh.source("myscript.bsh");  // or bsh.eval("source(\"myscript.bsh\")");
0058:
0059:         // Use set() and get() to pass objects in and out of variables
0060:         bsh.set( "date", new Date() );
0061:         Date date = (Date)bsh.get( "date" );
0062:         // This would also work:
0063:         Date date = (Date)bsh.eval( "date" );
0064:
0065:         bsh.eval("year = date.getYear()");
0066:         Integer year = (Integer)bsh.get("year");  // primitives use wrappers
0067:
0068:         // With Java1.3+ scripts can implement arbitrary interfaces...
0069:         // Script an awt event handler (or source it from a file, more likely)
0070:         bsh.eval( "actionPerformed( e ) { print( e ); }");
0071:         // Get a reference to the script object (implementing the interface)
0072:         ActionListener scriptedHandler = 
0073:         (ActionListener)bsh.eval("return (ActionListener)this");
0074:         // Use the scripted event handler normally...
0075:         new JButton.addActionListener( script );
0076:         </pre></blockquote>
0077:         <p>
0078:
0079:         In the above examples we showed a single interpreter instance, however 
0080:         you may wish to use many instances, depending on the application and how
0081:         you structure your scripts.  Interpreter instances are very light weight
0082:         to create, however if you are going to execute the same script repeatedly
0083:         and require maximum performance you should consider scripting the code as 
0084:         a method and invoking the scripted method each time on the same interpreter
0085:         instance (using eval()). 
0086:         <p>
0087:
0088:         See the BeanShell User's Manual for more information.
0089:         */
0090:        public class Interpreter implements  Runnable, ConsoleInterface,
0091:                Serializable {
0092:            /* --- Begin static members --- */
0093:
0094:            public static final String VERSION = "2.0b4-jedit";
0095:            /*
0096:            	Debug utils are static so that they are reachable by code that doesn't
0097:            	necessarily have an interpreter reference (e.g. tracing in utils).
0098:            	In the future we may want to allow debug/trace to be turned on on
0099:            	a per interpreter basis, in which case we'll need to use the parent
0100:            	reference in some way to determine the scope of the command that
0101:            	turns it on or off.
0102:             */
0103:            public static boolean DEBUG, TRACE, LOCALSCOPING;
0104:
0105:            // This should be per instance
0106:            transient static PrintStream debug;
0107:            static String systemLineSeparator = "\n"; // default
0108:
0109:            static {
0110:                staticInit();
0111:            }
0112:
0113:            /** Shared system object visible under bsh.system */
0114:            static This sharedObject;
0115:
0116:            /**
0117:            	Strict Java mode
0118:            	@see #setStrictJava( boolean )
0119:             */
0120:            private boolean strictJava = false;
0121:
0122:            /* --- End static members --- */
0123:
0124:            /* --- Instance data --- */
0125:
0126:            transient Parser parser;
0127:            NameSpace globalNameSpace;
0128:            transient Reader in;
0129:            transient PrintStream out;
0130:            transient PrintStream err;
0131:            ConsoleInterface console;
0132:
0133:            /** If this interpeter is a child of another, the parent */
0134:            Interpreter parent;
0135:
0136:            /** The name of the file or other source that this interpreter is reading */
0137:            String sourceFileInfo;
0138:
0139:            /** by default in interactive mode System.exit() on EOF */
0140:            private boolean exitOnEOF = true;
0141:
0142:            protected boolean evalOnly, // Interpreter has no input stream, use eval() only
0143:                    interactive; // Interpreter has a user, print prompts, etc.
0144:
0145:            /** Control the verbose printing of results for the show() command. */
0146:            private boolean showResults;
0147:
0148:            /* --- End instance data --- */
0149:
0150:            /**
0151:            	The main constructor.
0152:            	All constructors should now pass through here.
0153:
0154:            	@param namespace If namespace is non-null then this interpreter's
0155:            	root namespace will be set to the one provided.  If it is null a new
0156:            	one will be created for it.
0157:            	@param parent The parent interpreter if this interpreter is a child
0158:            		of another.  May be null.  Children share a BshClassManager with
0159:            		their parent instance.
0160:            	@param sourceFileInfo An informative string holding the filename
0161:            	or other description of the source from which this interpreter is
0162:            	reading... used for debugging.  May be null.
0163:             */
0164:            public Interpreter(Reader in, PrintStream out, PrintStream err,
0165:                    boolean interactive, NameSpace namespace,
0166:                    Interpreter parent, String sourceFileInfo) {
0167:                //System.out.println("New Interpreter: "+this +", sourcefile = "+sourceFileInfo );
0168:                parser = new Parser(in);
0169:                long t1 = System.currentTimeMillis();
0170:                this .in = in;
0171:                this .out = out;
0172:                this .err = err;
0173:                this .interactive = interactive;
0174:                debug = err;
0175:                this .parent = parent;
0176:                if (parent != null)
0177:                    setStrictJava(parent.getStrictJava());
0178:                this .sourceFileInfo = sourceFileInfo;
0179:
0180:                BshClassManager bcm = BshClassManager.createClassManager(this );
0181:                if (namespace == null)
0182:                    this .globalNameSpace = new NameSpace(bcm, "global");
0183:                else
0184:                    this .globalNameSpace = namespace;
0185:
0186:                // now done in NameSpace automatically when root
0187:                // The classes which are imported by default
0188:                //globalNameSpace.loadDefaultImports();
0189:
0190:                /*
0191:                	Create the root "bsh" system object if it doesn't exist.
0192:                 */
0193:                if (!(getu("bsh") instanceof  org.gjt.sp.jedit.bsh.This))
0194:                    initRootSystemObject();
0195:
0196:                if (interactive)
0197:                    loadRCFiles();
0198:
0199:                long t2 = System.currentTimeMillis();
0200:                if (Interpreter.DEBUG)
0201:                    Interpreter.debug("Time to initialize interpreter: "
0202:                            + (t2 - t1));
0203:            }
0204:
0205:            public Interpreter(Reader in, PrintStream out, PrintStream err,
0206:                    boolean interactive, NameSpace namespace) {
0207:                this (in, out, err, interactive, namespace, null, null);
0208:            }
0209:
0210:            public Interpreter(Reader in, PrintStream out, PrintStream err,
0211:                    boolean interactive) {
0212:                this (in, out, err, interactive, null);
0213:            }
0214:
0215:            /**
0216:            	Construct a new interactive interpreter attached to the specified
0217:            	console using the specified parent namespace.
0218:             */
0219:            public Interpreter(ConsoleInterface console,
0220:                    NameSpace globalNameSpace) {
0221:
0222:                this (console.getIn(), console.getOut(), console.getErr(), true,
0223:                        globalNameSpace);
0224:
0225:                setConsole(console);
0226:            }
0227:
0228:            /**
0229:            	Construct a new interactive interpreter attached to the specified
0230:            	console.
0231:             */
0232:            public Interpreter(ConsoleInterface console) {
0233:                this (console, null);
0234:            }
0235:
0236:            /**
0237:            	Create an interpreter for evaluation only.
0238:             */
0239:            public Interpreter() {
0240:                this (new StringReader(""), System.out, System.err, false, null);
0241:                evalOnly = true;
0242:                setu("bsh.evalOnly", new Primitive(true));
0243:            }
0244:
0245:            // End constructors
0246:
0247:            /**
0248:            	Attach a console
0249:            	Note: this method is incomplete.
0250:             */
0251:            public void setConsole(ConsoleInterface console) {
0252:                this .console = console;
0253:                setu("bsh.console", console);
0254:                // redundant with constructor
0255:                setOut(console.getOut());
0256:                setErr(console.getErr());
0257:                // need to set the input stream - reinit the parser?
0258:            }
0259:
0260:            private void initRootSystemObject() {
0261:                BshClassManager bcm = getClassManager();
0262:                // bsh
0263:                setu("bsh", new NameSpace(bcm, "Bsh Object").getThis(this ));
0264:
0265:                // init the static shared sharedObject if it's not there yet
0266:                if (sharedObject == null)
0267:                    sharedObject = new NameSpace(bcm,
0268:                            "Bsh Shared System Object").getThis(this );
0269:                // bsh.system
0270:                setu("bsh.system", sharedObject);
0271:                setu("bsh.shared", sharedObject); // alias
0272:
0273:                // bsh.help
0274:                This helpText = new NameSpace(bcm, "Bsh Command Help Text")
0275:                        .getThis(this );
0276:                setu("bsh.help", helpText);
0277:
0278:                // bsh.cwd
0279:                try {
0280:                    setu("bsh.cwd", System.getProperty("user.dir"));
0281:                } catch (SecurityException e) {
0282:                    // applets can't see sys props
0283:                    setu("bsh.cwd", ".");
0284:                }
0285:
0286:                // bsh.interactive
0287:                setu("bsh.interactive", new Primitive(interactive));
0288:                // bsh.evalOnly
0289:                setu("bsh.evalOnly", new Primitive(evalOnly));
0290:            }
0291:
0292:            /**
0293:            	Set the global namespace for this interpreter.
0294:            	<p>
0295:
0296:            	Note: This is here for completeness.  If you're using this a lot
0297:            	it may be an indication that you are doing more work than you have
0298:            	to.  For example, caching the interpreter instance rather than the
0299:            	namespace should not add a significant overhead.  No state other
0300:            	than the debug status is stored in the interpreter.
0301:            	<p>
0302:
0303:            	All features of the namespace can also be accessed using the
0304:            	interpreter via eval() and the script variable 'this.namespace'
0305:            	(or global.namespace as necessary).
0306:             */
0307:            public void setNameSpace(NameSpace globalNameSpace) {
0308:                this .globalNameSpace = globalNameSpace;
0309:            }
0310:
0311:            /**
0312:            	Get the global namespace of this interpreter.
0313:            	<p>
0314:
0315:            	Note: This is here for completeness.  If you're using this a lot
0316:            	it may be an indication that you are doing more work than you have
0317:            	to.  For example, caching the interpreter instance rather than the
0318:            	namespace should not add a significant overhead.  No state other than
0319:            	the debug status is stored in the interpreter.
0320:            	<p>
0321:
0322:            	All features of the namespace can also be accessed using the
0323:            	interpreter via eval() and the script variable 'this.namespace'
0324:            	(or global.namespace as necessary).
0325:             */
0326:            public NameSpace getNameSpace() {
0327:                return globalNameSpace;
0328:            }
0329:
0330:            /**
0331:            	Run the text only interpreter on the command line or specify a file.
0332:             */
0333:            public static void main(String[] args) {
0334:                if (args.length > 0) {
0335:                    String filename = args[0];
0336:
0337:                    String[] bshArgs;
0338:                    if (args.length > 1) {
0339:                        bshArgs = new String[args.length - 1];
0340:                        System.arraycopy(args, 1, bshArgs, 0, args.length - 1);
0341:                    } else
0342:                        bshArgs = new String[0];
0343:
0344:                    Interpreter interpreter = new Interpreter();
0345:                    //System.out.println("run i = "+interpreter);
0346:                    interpreter.setu("bsh.args", bshArgs);
0347:                    try {
0348:                        Object result = interpreter.source(filename,
0349:                                interpreter.globalNameSpace);
0350:                        if (result instanceof  Class)
0351:                            try {
0352:                                invokeMain((Class) result, bshArgs);
0353:                            } catch (Exception e) {
0354:                                Object o = e;
0355:                                if (e instanceof  InvocationTargetException)
0356:                                    o = ((InvocationTargetException) e)
0357:                                            .getTargetException();
0358:                                System.err.println("Class: " + result
0359:                                        + " main method threw exception:" + o);
0360:                            }
0361:                    } catch (FileNotFoundException e) {
0362:                        System.out.println("File not found: " + e);
0363:                    } catch (TargetError e) {
0364:                        System.out.println("Script threw exception: " + e);
0365:                        if (e.inNativeCode())
0366:                            e.printStackTrace(DEBUG, System.err);
0367:                    } catch (EvalError e) {
0368:                        System.out.println("Evaluation Error: " + e);
0369:                    } catch (IOException e) {
0370:                        System.out.println("I/O Error: " + e);
0371:                    }
0372:                } else {
0373:                    // Workaround for JDK bug 4071281, where system.in.available()
0374:                    // returns too large a value. This bug has been fixed in JDK 1.2.
0375:                    InputStream src;
0376:                    if (System.getProperty("os.name").startsWith("Windows")
0377:                            && System.getProperty("java.version").startsWith(
0378:                                    "1.1.")) {
0379:                        src = new FilterInputStream(System.in) {
0380:                            public int available() throws IOException {
0381:                                return 0;
0382:                            }
0383:                        };
0384:                    } else
0385:                        src = System.in;
0386:
0387:                    Reader in = new CommandLineReader(
0388:                            new InputStreamReader(src));
0389:                    Interpreter interpreter = new Interpreter(in, System.out,
0390:                            System.err, true);
0391:                    interpreter.run();
0392:                }
0393:            }
0394:
0395:            public static void invokeMain(Class clas, String[] args)
0396:                    throws Exception {
0397:                Method main = Reflect.resolveJavaMethod(
0398:                        null/*BshClassManager*/, clas, "main",
0399:                        new Class[] { String[].class }, true/*onlyStatic*/);
0400:                if (main != null)
0401:                    main.invoke(null, new Object[] { args });
0402:            }
0403:
0404:            /**
0405:            	Run interactively.  (printing prompts, etc.)
0406:             */
0407:            public void run() {
0408:                if (evalOnly)
0409:                    throw new RuntimeException("bsh Interpreter: No stream");
0410:
0411:                /*
0412:                  We'll print our banner using eval(String) in order to
0413:                  exercise the parser and get the basic expression classes loaded...
0414:                  This ameliorates the delay after typing the first statement.
0415:                 */
0416:                if (interactive)
0417:                    try {
0418:                        eval("printBanner();");
0419:                    } catch (EvalError e) {
0420:                        println("BeanShell " + VERSION
0421:                                + " - by Pat Niemeyer (pat@pat.net)");
0422:                    }
0423:
0424:                // init the callstack.
0425:                CallStack callstack = new CallStack(globalNameSpace);
0426:
0427:                boolean eof = false;
0428:                while (!eof) {
0429:                    try {
0430:                        // try to sync up the console
0431:                        System.out.flush();
0432:                        System.err.flush();
0433:                        Thread.yield(); // this helps a little
0434:
0435:                        if (interactive)
0436:                            print(getBshPrompt());
0437:
0438:                        eof = Line();
0439:
0440:                        if (get_jjtree().nodeArity() > 0) // number of child nodes
0441:                        {
0442:                            SimpleNode node = (SimpleNode) (get_jjtree()
0443:                                    .rootNode());
0444:
0445:                            if (DEBUG)
0446:                                node.dump(">");
0447:
0448:                            Object ret = node.eval(callstack, this );
0449:
0450:                            // sanity check during development
0451:                            if (callstack.depth() > 1)
0452:                                throw new InterpreterError(
0453:                                        "Callstack growing: " + callstack);
0454:
0455:                            if (ret instanceof  ReturnControl)
0456:                                ret = ((ReturnControl) ret).value;
0457:
0458:                            if (ret != Primitive.VOID) {
0459:                                setu("$_", ret);
0460:                                if (showResults)
0461:                                    println("<" + ret + ">");
0462:                            }
0463:                        }
0464:                    } catch (ParseException e) {
0465:                        error("Parser Error: " + e.getMessage(DEBUG));
0466:                        if (DEBUG)
0467:                            e.printStackTrace();
0468:                        if (!interactive)
0469:                            eof = true;
0470:
0471:                        parser.reInitInput(in);
0472:                    } catch (InterpreterError e) {
0473:                        error("Internal Error: " + e.getMessage());
0474:                        e.printStackTrace();
0475:                        if (!interactive)
0476:                            eof = true;
0477:                    } catch (TargetError e) {
0478:                        error("// Uncaught Exception: " + e);
0479:                        if (e.inNativeCode())
0480:                            e.printStackTrace(DEBUG, err);
0481:                        if (!interactive)
0482:                            eof = true;
0483:                        setu("$_e", e.getTarget());
0484:                    } catch (EvalError e) {
0485:                        if (interactive)
0486:                            error("EvalError: " + e.toString());
0487:                        else
0488:                            error("EvalError: " + e.getMessage());
0489:
0490:                        if (DEBUG)
0491:                            e.printStackTrace();
0492:
0493:                        if (!interactive)
0494:                            eof = true;
0495:                    } catch (Exception e) {
0496:                        error("Unknown error: " + e);
0497:                        if (DEBUG)
0498:                            e.printStackTrace();
0499:                        if (!interactive)
0500:                            eof = true;
0501:                    } catch (TokenMgrError e) {
0502:                        error("Error parsing input: " + e);
0503:
0504:                        /*
0505:                        	We get stuck in infinite loops here when unicode escapes
0506:                        	fail.  Must re-init the char stream reader
0507:                        	(ASCII_UCodeESC_CharStream.java)
0508:                         */
0509:                        parser.reInitTokenInput(in);
0510:
0511:                        if (!interactive)
0512:                            eof = true;
0513:                    } finally {
0514:                        get_jjtree().reset();
0515:                        // reinit the callstack
0516:                        if (callstack.depth() > 1) {
0517:                            callstack.clear();
0518:                            callstack.push(globalNameSpace);
0519:                        }
0520:                    }
0521:                }
0522:
0523:                if (interactive && exitOnEOF)
0524:                    System.exit(0);
0525:            }
0526:
0527:            // begin source and eval
0528:
0529:            /**
0530:            	Read text from fileName and eval it.
0531:             */
0532:            public Object source(String filename, NameSpace nameSpace)
0533:                    throws FileNotFoundException, IOException, EvalError {
0534:                File file = pathToFile(filename);
0535:                if (Interpreter.DEBUG)
0536:                    debug("Sourcing file: " + file);
0537:                Reader sourceIn = new BufferedReader(new FileReader(file));
0538:                try {
0539:                    return eval(sourceIn, nameSpace, filename);
0540:                } finally {
0541:                    sourceIn.close();
0542:                }
0543:            }
0544:
0545:            /**
0546:            	Read text from fileName and eval it.
0547:            	Convenience method.  Use the global namespace.
0548:             */
0549:            public Object source(String filename) throws FileNotFoundException,
0550:                    IOException, EvalError {
0551:                return source(filename, globalNameSpace);
0552:            }
0553:
0554:            /**
0555:                Spawn a non-interactive local interpreter to evaluate text in the
0556:            	specified namespace.
0557:
0558:            	Return value is the evaluated object (or corresponding primitive
0559:            	wrapper).
0560:
0561:            	@param sourceFileInfo is for information purposes only.  It is used to
0562:            	display error messages (and in the future may be made available to
0563:            	the script).
0564:            	@throws EvalError on script problems
0565:            	@throws TargetError on unhandled exceptions from the script
0566:             */
0567:            /*
0568:            	Note: we need a form of eval that passes the callstack through...
0569:             */
0570:            /*
0571:            Can't this be combined with run() ?
0572:            run seems to have stuff in it for interactive vs. non-interactive...
0573:            compare them side by side and see what they do differently, aside from the
0574:            exception handling.
0575:             */
0576:
0577:            public Object eval(Reader in, NameSpace nameSpace,
0578:                    String sourceFileInfo
0579:            /*, CallStack callstack */) throws EvalError {
0580:                Object retVal = null;
0581:                if (Interpreter.DEBUG)
0582:                    debug("eval: nameSpace = " + nameSpace);
0583:
0584:                /*
0585:                	Create non-interactive local interpreter for this namespace
0586:                	with source from the input stream and out/err same as
0587:                	this interpreter.
0588:                 */
0589:                Interpreter localInterpreter = new Interpreter(in, out, err,
0590:                        false, nameSpace, this , sourceFileInfo);
0591:
0592:                CallStack callstack = new CallStack(nameSpace);
0593:
0594:                boolean eof = false;
0595:                while (!eof) {
0596:                    SimpleNode node = null;
0597:                    try {
0598:                        eof = localInterpreter.Line();
0599:                        if (localInterpreter.get_jjtree().nodeArity() > 0) {
0600:                            node = (SimpleNode) localInterpreter.get_jjtree()
0601:                                    .rootNode();
0602:                            // nodes remember from where they were sourced
0603:                            node.setSourceFile(sourceFileInfo);
0604:
0605:                            if (TRACE)
0606:                                println("// " + node.getText());
0607:
0608:                            retVal = node.eval(callstack, localInterpreter);
0609:
0610:                            // sanity check during development
0611:                            if (callstack.depth() > 1)
0612:                                throw new InterpreterError(
0613:                                        "Callstack growing: " + callstack);
0614:
0615:                            if (retVal instanceof  ReturnControl) {
0616:                                retVal = ((ReturnControl) retVal).value;
0617:                                break; // non-interactive, return control now
0618:                            }
0619:
0620:                            if (localInterpreter.showResults
0621:                                    && retVal != Primitive.VOID)
0622:                                println("<" + retVal + ">");
0623:                        }
0624:                    } catch (ParseException e) {
0625:                        /*
0626:                        throw new EvalError(
0627:                        	"Sourced file: "+sourceFileInfo+" parser Error: "
0628:                        	+ e.getMessage( DEBUG ), node, callstack );
0629:                         */
0630:                        if (DEBUG)
0631:                            // show extra "expecting..." info
0632:                            error(e.getMessage(DEBUG));
0633:
0634:                        // add the source file info and throw again
0635:                        e.setErrorSourceFile(sourceFileInfo);
0636:                        throw e;
0637:
0638:                    } catch (InterpreterError e) {
0639:                        e.printStackTrace();
0640:                        throw new EvalError("Sourced file: " + sourceFileInfo
0641:                                + " internal Error: " + e.getMessage(), node,
0642:                                callstack);
0643:                    } catch (TargetError e) {
0644:                        // failsafe, set the Line as the origin of the error.
0645:                        if (e.getNode() == null)
0646:                            e.setNode(node);
0647:                        e.reThrow("Sourced file: " + sourceFileInfo);
0648:                    } catch (EvalError e) {
0649:                        if (DEBUG)
0650:                            e.printStackTrace();
0651:                        // failsafe, set the Line as the origin of the error.
0652:                        if (e.getNode() == null)
0653:                            e.setNode(node);
0654:                        e.reThrow("Sourced file: " + sourceFileInfo);
0655:                    } catch (Exception e) {
0656:                        if (DEBUG)
0657:                            e.printStackTrace();
0658:                        throw new EvalError("Sourced file: " + sourceFileInfo
0659:                                + " unknown error: " + e.getMessage(), node,
0660:                                callstack);
0661:                    } catch (TokenMgrError e) {
0662:                        throw new EvalError("Sourced file: " + sourceFileInfo
0663:                                + " Token Parsing Error: " + e.getMessage(),
0664:                                node, callstack);
0665:                    } finally {
0666:                        localInterpreter.get_jjtree().reset();
0667:
0668:                        // reinit the callstack
0669:                        if (callstack.depth() > 1) {
0670:                            callstack.clear();
0671:                            callstack.push(nameSpace);
0672:                        }
0673:                    }
0674:                }
0675:                return Primitive.unwrap(retVal);
0676:            }
0677:
0678:            /**
0679:            	Evaluate the inputstream in this interpreter's global namespace.
0680:             */
0681:            public Object eval(Reader in) throws EvalError {
0682:                return eval(in, globalNameSpace, "eval stream");
0683:            }
0684:
0685:            /**
0686:            	Evaluate the string in this interpreter's global namespace.
0687:             */
0688:            public Object eval(String statements) throws EvalError {
0689:                if (Interpreter.DEBUG)
0690:                    debug("eval(String): " + statements);
0691:                return eval(statements, globalNameSpace);
0692:            }
0693:
0694:            /**
0695:            	Evaluate the string in the specified namespace.
0696:             */
0697:            public Object eval(String statements, NameSpace nameSpace)
0698:                    throws EvalError {
0699:
0700:                String s = (statements.endsWith(";") ? statements : statements
0701:                        + ";");
0702:                return eval(new StringReader(s), nameSpace,
0703:                        "inline evaluation of: ``" + showEvalString(s) + "''");
0704:            }
0705:
0706:            private String showEvalString(String s) {
0707:                s = s.replace('\n', ' ');
0708:                s = s.replace('\r', ' ');
0709:                if (s.length() > 80)
0710:                    s = s.substring(0, 80) + " . . . ";
0711:                return s;
0712:            }
0713:
0714:            // end source and eval
0715:
0716:            /**
0717:            	Print an error message in a standard format on the output stream
0718:            	associated with this interpreter. On the GUI console this will appear
0719:            	in red, etc.
0720:             */
0721:            public final void error(Object o) {
0722:                if (console != null)
0723:                    console.error("// Error: " + o + "\n");
0724:                else {
0725:                    err.println("// Error: " + o);
0726:                    err.flush();
0727:                }
0728:            }
0729:
0730:            // ConsoleInterface
0731:            // The interpreter reflexively implements the console interface that it
0732:            // uses.  Should clean this up by using an inner class to implement the
0733:            // console for us.
0734:
0735:            /**
0736:            	Get the input stream associated with this interpreter.
0737:            	This may be be stdin or the GUI console.
0738:             */
0739:            public Reader getIn() {
0740:                return in;
0741:            }
0742:
0743:            /**
0744:            	Get the outptut stream associated with this interpreter.
0745:            	This may be be stdout or the GUI console.
0746:             */
0747:            public PrintStream getOut() {
0748:                return out;
0749:            }
0750:
0751:            /**
0752:            	Get the error output stream associated with this interpreter.
0753:            	This may be be stderr or the GUI console.
0754:             */
0755:            public PrintStream getErr() {
0756:                return err;
0757:            }
0758:
0759:            public final void println(Object o) {
0760:                print(String.valueOf(o) + systemLineSeparator);
0761:            }
0762:
0763:            public final void print(Object o) {
0764:                if (console != null) {
0765:                    console.print(o);
0766:                } else {
0767:                    out.print(o);
0768:                    out.flush();
0769:                }
0770:            }
0771:
0772:            // End ConsoleInterface
0773:
0774:            /**
0775:            	Print a debug message on debug stream associated with this interpreter
0776:            	only if debugging is turned on.
0777:             */
0778:            public final static void debug(String s) {
0779:                if (DEBUG)
0780:                    debug.println("// Debug: " + s);
0781:            }
0782:
0783:            /*
0784:            	Primary interpreter set and get variable methods
0785:            	Note: These are squeltching errors... should they?
0786:             */
0787:
0788:            /**
0789:            	Get the value of the name.
0790:            	name may be any value. e.g. a variable or field
0791:             */
0792:            public Object get(String name) throws EvalError {
0793:                try {
0794:                    Object ret = globalNameSpace.get(name, this );
0795:                    return Primitive.unwrap(ret);
0796:                } catch (UtilEvalError e) {
0797:                    throw e.toEvalError(SimpleNode.JAVACODE, new CallStack());
0798:                }
0799:            }
0800:
0801:            /**
0802:            	Unchecked get for internal use
0803:             */
0804:            Object getu(String name) {
0805:                try {
0806:                    return get(name);
0807:                } catch (EvalError e) {
0808:                    throw new InterpreterError("set: " + e);
0809:                }
0810:            }
0811:
0812:            /**
0813:            	Assign the value to the name.
0814:            	name may evaluate to anything assignable. e.g. a variable or field.
0815:             */
0816:            public void set(String name, Object value) throws EvalError {
0817:                // map null to Primtive.NULL coming in...
0818:                if (value == null)
0819:                    value = Primitive.NULL;
0820:
0821:                CallStack callstack = new CallStack();
0822:                try {
0823:                    if (Name.isCompound(name)) {
0824:                        LHS lhs = globalNameSpace.getNameResolver(name).toLHS(
0825:                                callstack, this );
0826:                        lhs.assign(value, false);
0827:                    } else
0828:                        // optimization for common case
0829:                        globalNameSpace.setVariable(name, value, false);
0830:                } catch (UtilEvalError e) {
0831:                    throw e.toEvalError(SimpleNode.JAVACODE, callstack);
0832:                }
0833:            }
0834:
0835:            /**
0836:            	Unchecked set for internal use
0837:             */
0838:            void setu(String name, Object value) {
0839:                try {
0840:                    set(name, value);
0841:                } catch (EvalError e) {
0842:                    throw new InterpreterError("set: " + e);
0843:                }
0844:            }
0845:
0846:            public void set(String name, long value) throws EvalError {
0847:                set(name, new Primitive(value));
0848:            }
0849:
0850:            public void set(String name, int value) throws EvalError {
0851:                set(name, new Primitive(value));
0852:            }
0853:
0854:            public void set(String name, double value) throws EvalError {
0855:                set(name, new Primitive(value));
0856:            }
0857:
0858:            public void set(String name, float value) throws EvalError {
0859:                set(name, new Primitive(value));
0860:            }
0861:
0862:            public void set(String name, boolean value) throws EvalError {
0863:                set(name, new Primitive(value));
0864:            }
0865:
0866:            /**
0867:            	Unassign the variable name.
0868:            	Name should evaluate to a variable.
0869:             */
0870:            public void unset(String name) throws EvalError {
0871:                /*
0872:                	We jump through some hoops here to handle arbitrary cases like
0873:                	unset("bsh.foo");
0874:                 */
0875:                CallStack callstack = new CallStack();
0876:                try {
0877:                    LHS lhs = globalNameSpace.getNameResolver(name).toLHS(
0878:                            callstack, this );
0879:
0880:                    if (lhs.type != LHS.VARIABLE)
0881:                        throw new EvalError("Can't unset, not a variable: "
0882:                                + name, SimpleNode.JAVACODE, new CallStack());
0883:
0884:                    //lhs.assign( null, false );
0885:                    lhs.nameSpace.unsetVariable(name);
0886:                } catch (UtilEvalError e) {
0887:                    throw new EvalError(e.getMessage(), SimpleNode.JAVACODE,
0888:                            new CallStack());
0889:                }
0890:            }
0891:
0892:            // end primary set and get methods
0893:
0894:            /**
0895:            	Get a reference to the interpreter (global namespace), cast
0896:            	to the specified interface type.  Assuming the appropriate
0897:            	methods of the interface are defined in the interpreter, then you may
0898:            	use this interface from Java, just like any other Java object.
0899:            	<p>
0900:
0901:            	For example:
0902:            	<pre>
0903:            		Interpreter interpreter = new Interpreter();
0904:            		// define a method called run()
0905:            		interpreter.eval("run() { ... }");
0906:
0907:            		// Fetch a reference to the interpreter as a Runnable
0908:            		Runnable runnable =
0909:            			(Runnable)interpreter.getInterface( Runnable.class );
0910:            	</pre>
0911:            	<p>
0912:
0913:            	Note that the interpreter does *not* require that any or all of the
0914:            	methods of the interface be defined at the time the interface is
0915:            	generated.  However if you attempt to invoke one that is not defined
0916:            	you will get a runtime exception.
0917:            	<p>
0918:
0919:            	Note also that this convenience method has exactly the same effect as
0920:            	evaluating the script:
0921:            	<pre>
0922:            		(Type)this;
0923:            	</pre>
0924:            	<p>
0925:
0926:            	For example, the following is identical to the previous example:
0927:            	<p>
0928:
0929:            	<pre>
0930:            		// Fetch a reference to the interpreter as a Runnable
0931:            		Runnable runnable =
0932:            			(Runnable)interpreter.eval( "(Runnable)this" );
0933:            	</pre>
0934:            	<p>
0935:
0936:            	<em>Version requirement</em> Although standard Java interface types
0937:            	are always available, to be used with arbitrary interfaces this
0938:            	feature requires that you are using Java 1.3 or greater.
0939:            	<p>
0940:
0941:            	@throws EvalError if the interface cannot be generated because the
0942:            	version of Java does not support the proxy mechanism.
0943:             */
0944:            public Object getInterface(Class interf) throws EvalError {
0945:                try {
0946:                    return globalNameSpace.getThis(this ).getInterface(interf);
0947:                } catch (UtilEvalError e) {
0948:                    throw e.toEvalError(SimpleNode.JAVACODE, new CallStack());
0949:                }
0950:            }
0951:
0952:            /*	Methods for interacting with Parser */
0953:
0954:            private JJTParserState get_jjtree() {
0955:                return parser.jjtree;
0956:            }
0957:
0958:            private JavaCharStream get_jj_input_stream() {
0959:                return parser.jj_input_stream;
0960:            }
0961:
0962:            private boolean Line() throws ParseException {
0963:                return parser.Line();
0964:            }
0965:
0966:            /*	End methods for interacting with Parser */
0967:
0968:            void loadRCFiles() {
0969:                try {
0970:                    String rcfile =
0971:                    // Default is c:\windows under win98, $HOME under Unix
0972:                    System.getProperty("user.home") + File.separator + ".bshrc";
0973:                    source(rcfile, globalNameSpace);
0974:                } catch (Exception e) {
0975:                    // squeltch security exception, filenotfoundexception
0976:                    if (Interpreter.DEBUG)
0977:                        debug("Could not find rc file: " + e);
0978:                }
0979:            }
0980:
0981:            /**
0982:            	Localize a path to the file name based on the bsh.cwd interpreter
0983:            	working directory.
0984:             */
0985:            public File pathToFile(String fileName) throws IOException {
0986:                File file = new File(fileName);
0987:
0988:                // if relative, fix up to bsh.cwd
0989:                if (!file.isAbsolute()) {
0990:                    String cwd = (String) getu("bsh.cwd");
0991:                    file = new File(cwd + File.separator + fileName);
0992:                }
0993:
0994:                // The canonical file name is also absolute.
0995:                // No need for getAbsolutePath() here...
0996:                return new File(file.getCanonicalPath());
0997:            }
0998:
0999:            public static void redirectOutputToFile(String filename) {
1000:                try {
1001:                    PrintStream pout = new PrintStream(new FileOutputStream(
1002:                            filename));
1003:                    System.setOut(pout);
1004:                    System.setErr(pout);
1005:                } catch (IOException e) {
1006:                    System.err.println("Can't redirect output to file: "
1007:                            + filename);
1008:                }
1009:            }
1010:
1011:            /**
1012:            	Set an external class loader to be used as the base classloader
1013:            	for BeanShell.  The base classloader is used for all classloading
1014:            	unless/until the addClasspath()/setClasspath()/reloadClasses()
1015:            	commands are called to modify the interpreter's classpath.  At that
1016:            	time the new paths /updated paths are added on top of the base
1017:            	classloader.
1018:            	<p>
1019:
1020:            	BeanShell will use this at the same point it would otherwise use the
1021:            	plain Class.forName().
1022:            	i.e. if no explicit classpath management is done from the script
1023:            	(addClassPath(), setClassPath(), reloadClasses()) then BeanShell will
1024:            	only use the supplied classloader.  If additional classpath management
1025:            	is done then BeanShell will perform that in addition to the supplied
1026:            	external classloader.
1027:            	However BeanShell is not currently able to reload
1028:            	classes supplied through the external classloader.
1029:            	<p>
1030:
1031:            	@see BshClassManager#setClassLoader( ClassLoader )
1032:             */
1033:            public void setClassLoader(ClassLoader externalCL) {
1034:                getClassManager().setClassLoader(externalCL);
1035:            }
1036:
1037:            /**
1038:            	Get the class manager associated with this interpreter
1039:            	(the BshClassManager of this interpreter's global namespace).
1040:            	This is primarily a convenience method.
1041:             */
1042:            public BshClassManager getClassManager() {
1043:                return getNameSpace().getClassManager();
1044:            }
1045:
1046:            /**
1047:            	Set strict Java mode on or off.
1048:            	This mode attempts to make BeanShell syntax behave as Java
1049:            	syntax, eliminating conveniences like loose variables, etc.
1050:            	When enabled, variables are required to be declared or initialized
1051:            	before use and method arguments are reqired to have types.
1052:            	<p>
1053:
1054:            	This mode will become more strict in a future release when
1055:            	classes are interpreted and there is an alternative to scripting
1056:            	objects as method closures.
1057:             */
1058:            public void setStrictJava(boolean b) {
1059:                this .strictJava = b;
1060:            }
1061:
1062:            /**
1063:            	@see #setStrictJava( boolean )
1064:             */
1065:            public boolean getStrictJava() {
1066:                return this .strictJava;
1067:            }
1068:
1069:            static void staticInit() {
1070:                /*
1071:                	Apparently in some environments you can't catch the security exception
1072:                	at all...  e.g. as an applet in IE  ... will probably have to work
1073:                	around
1074:                 */
1075:                try {
1076:                    systemLineSeparator = System.getProperty("line.separator");
1077:                    debug = System.err;
1078:                    DEBUG = Boolean.getBoolean("debug");
1079:                    TRACE = Boolean.getBoolean("trace");
1080:                    LOCALSCOPING = Boolean.getBoolean("localscoping");
1081:                    String outfilename = System.getProperty("outfile");
1082:                    if (outfilename != null)
1083:                        redirectOutputToFile(outfilename);
1084:                } catch (SecurityException e) {
1085:                    System.err.println("Could not init static:" + e);
1086:                } catch (Exception e) {
1087:                    System.err.println("Could not init static(2):" + e);
1088:                } catch (Throwable e) {
1089:                    System.err.println("Could not init static(3):" + e);
1090:                }
1091:            }
1092:
1093:            /**
1094:            	Specify the source of the text from which this interpreter is reading.
1095:            	Note: there is a difference between what file the interrpeter is
1096:            	sourcing and from what file a method was originally parsed.  One
1097:            	file may call a method sourced from another file.  See SimpleNode
1098:            	for origination file info.
1099:            	@see org.gjt.sp.jedit.bsh.SimpleNode#getSourceFile()
1100:             */
1101:            public String getSourceFileInfo() {
1102:                if (sourceFileInfo != null)
1103:                    return sourceFileInfo;
1104:                else
1105:                    return "<unknown source>";
1106:            }
1107:
1108:            /**
1109:            	Get the parent Interpreter of this interpreter, if any.
1110:            	Currently this relationship implies the following:
1111:            		1) Parent and child share a BshClassManager
1112:            		2) Children indicate the parent's source file information in error
1113:            		reporting.
1114:            	When created as part of a source() / eval() the child also shares
1115:            	the parent's namespace.  But that is not necessary in general.
1116:             */
1117:            public Interpreter getParent() {
1118:                return parent;
1119:            }
1120:
1121:            public void setOut(PrintStream out) {
1122:                this .out = out;
1123:            }
1124:
1125:            public void setErr(PrintStream err) {
1126:                this .err = err;
1127:            }
1128:
1129:            /**
1130:            	De-serialization setup.
1131:            	Default out and err streams to stdout, stderr if they are null.
1132:             */
1133:            private void readObject(ObjectInputStream stream)
1134:                    throws java.io.IOException, ClassNotFoundException {
1135:                stream.defaultReadObject();
1136:
1137:                // set transient fields
1138:                if (console != null) {
1139:                    setOut(console.getOut());
1140:                    setErr(console.getErr());
1141:                } else {
1142:                    setOut(System.out);
1143:                    setErr(System.err);
1144:                }
1145:            }
1146:
1147:            /**
1148:            	Get the prompt string defined by the getBshPrompt() method in the
1149:            	global namespace.  This may be from the getBshPrompt() command or may
1150:            	be defined by the user as with any other method.
1151:            	Defaults to "bsh % " if the method is not defined or there is an error.
1152:             */
1153:            private String getBshPrompt() {
1154:                try {
1155:                    return (String) eval("getBshPrompt()");
1156:                } catch (Exception e) {
1157:                    return "bsh % ";
1158:                }
1159:            }
1160:
1161:            /**
1162:            	Specify whether, in interactive mode, the interpreter exits Java upon
1163:            	end of input.  If true, when in interactive mode the interpreter will
1164:            	issue a System.exit(0) upon eof.  If false the interpreter no
1165:            	System.exit() will be done.
1166:            	<p/>
1167:            	Note: if you wish to cause an EOF externally you can try closing the
1168:            	input stream.  This is not guaranteed to work in older versions of Java
1169:            	due to Java limitations, but should work in newer JDK/JREs.  (That was
1170:            	the motivation for the Java NIO package).
1171:             */
1172:            public void setExitOnEOF(boolean value) {
1173:                exitOnEOF = value; // ug
1174:            }
1175:
1176:            /**
1177:            	Turn on/off the verbose printing of results as for the show()
1178:            	 command.
1179:             	If this interpreter has a parent the call is delegated.
1180:             	See the BeanShell show() command.
1181:             */
1182:            public void setShowResults(boolean showResults) {
1183:                this .showResults = showResults;
1184:            }
1185:
1186:            /**
1187:             Show on/off verbose printing status for the show() command.
1188:             See the BeanShell show() command.
1189:             If this interpreter has a parent the call is delegated.
1190:             */
1191:            public boolean getShowResults() {
1192:                return showResults;
1193:            }
1194:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.