Source Code Cross Referenced for InteractiveShell.java in  » Scripting » groovy-1.0 » groovy » ui » 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 » Scripting » groovy 1.0 » groovy.ui 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         $Id: InteractiveShell.java 3948 2006-08-01 09:50:46Z glaforge $
003:
004:         Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
005:
006:         Redistribution and use of this software and associated documentation
007:         ("Software"), with or without modification, are permitted provided
008:         that the following conditions are met:
009:
010:         1. Redistributions of source code must retain copyright
011:            statements and notices.  Redistributions must also contain a
012:            copy of this document.
013:
014:         2. Redistributions in binary form must reproduce the
015:            above copyright notice, this list of conditions and the
016:            following disclaimer in the documentation and/or other
017:            materials provided with the distribution.
018:
019:         3. The name "groovy" must not be used to endorse or promote
020:            products derived from this Software without prior written
021:            permission of The Codehaus.  For written permission,
022:            please contact info@codehaus.org.
023:
024:         4. Products derived from this Software may not be called "groovy"
025:            nor may "groovy" appear in their names without prior written
026:            permission of The Codehaus. "groovy" is a registered
027:            trademark of The Codehaus.
028:
029:         5. Due credit should be given to The Codehaus -
030:            http://groovy.codehaus.org/
031:
032:         THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
033:         ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
034:         NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
035:         FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
036:         THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
037:         INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
038:         (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
039:         SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
040:         HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
041:         STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
042:         ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
043:         OF THE POSSIBILITY OF SUCH DAMAGE.
044:
045:         */
046:        package groovy.ui;
047:
048:        import groovy.lang.Binding;
049:        import groovy.lang.GroovyShell;
050:
051:        import java.io.IOException;
052:        import java.io.InputStream;
053:        import java.io.PrintStream;
054:        import java.lang.reflect.Method;
055:        import java.util.HashMap;
056:        import java.util.Iterator;
057:        import java.util.Map;
058:        import java.util.Set;
059:
060:        import org.codehaus.groovy.control.CompilationFailedException;
061:        import org.codehaus.groovy.control.SourceUnit;
062:        import org.codehaus.groovy.runtime.InvokerHelper;
063:        import org.codehaus.groovy.runtime.InvokerInvocationException;
064:        import org.codehaus.groovy.sandbox.ui.Prompt;
065:        import org.codehaus.groovy.sandbox.ui.PromptFactory;
066:        import org.codehaus.groovy.tools.ErrorReporter;
067:
068:        /**
069:         * A simple interactive shell for evaluating groovy expressions
070:         * on the command line
071:         *
072:         * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
073:         * @author <a href="mailto:cpoirier@dreaming.org"   >Chris Poirier</a>
074:         * @author Yuri Schimke
075:         * @author Brian McCallistair
076:         * @author Guillaume Laforge
077:         * @author Dierk Koenig, include the inspect command, June 2005
078:         * @version $Revision: 3948 $
079:         */
080:        public class InteractiveShell {
081:            private final GroovyShell shell;
082:            private final Prompt prompt;
083:            private final InputStream in;
084:            private final PrintStream out;
085:            private final PrintStream err;
086:            private Object lastResult;
087:
088:            /**
089:             * Entry point when called directly.
090:             */
091:            public static void main(String args[]) {
092:                try {
093:                    final InteractiveShell groovy = new InteractiveShell();
094:                    groovy.run(args);
095:                } catch (Exception e) {
096:                    System.err.println("Caught: " + e);
097:                    e.printStackTrace();
098:                }
099:            }
100:
101:            /**
102:             * Default constructor.
103:             */
104:            public InteractiveShell() {
105:                this (System.in, System.out, System.err);
106:            }
107:
108:            public InteractiveShell(final InputStream in,
109:                    final PrintStream out, final PrintStream err) {
110:                this (null, new Binding(), in, out, err);
111:            }
112:
113:            /**
114:             * Constructs a new InteractiveShell instance
115:             * 
116:             * @param binding The binding instance
117:             * @param in The input stream to use
118:             * @param out The output stream to use
119:             * @param err The error stream to use
120:             */
121:            public InteractiveShell(Binding binding, final InputStream in,
122:                    final PrintStream out, final PrintStream err) {
123:                this (null, binding, in, out, err);
124:            }
125:
126:            /**
127:             * Constructs a new InteractiveShell instance
128:             * 
129:             * @param parent The parent ClassLoader
130:             * @param binding The binding instance
131:             * @param in The input stream to use
132:             * @param out The output stream to use
133:             * @param err The error stream to use
134:             */
135:            public InteractiveShell(ClassLoader parent, Binding binding,
136:                    final InputStream in, final PrintStream out,
137:                    final PrintStream err) {
138:                this .in = in;
139:                this .out = out;
140:                this .err = err;
141:                prompt = PromptFactory.buildPrompt(in, out, err);
142:                prompt.setPrompt("groovy> ");
143:                if (parent != null) {
144:                    shell = new GroovyShell(parent, binding);
145:                } else {
146:                    shell = new GroovyShell(binding);
147:                }
148:                Map map = shell.getContext().getVariables();
149:                if (map.get("shell") != null) {
150:                    map.put("shell", shell);
151:                }
152:            }
153:
154:            //---------------------------------------------------------------------------
155:            // COMMAND LINE PROCESSING LOOP
156:
157:            /**
158:             * Reads commands and statements from input stream and processes them.
159:             */
160:            public void run(String[] args) throws Exception {
161:                final String version = InvokerHelper.getVersion();
162:
163:                out.println("Let's get Groovy!");
164:                out.println("================");
165:                out.println("Version: " + version + " JVM: "
166:                        + System.getProperty("java.vm.version"));
167:                out.println("Type 'exit' to terminate the shell");
168:                out.println("Type 'help' for command help");
169:                out.println("Type 'go' to execute the statements");
170:
171:                boolean running = true;
172:                while (running) {
173:                    // Read a single top-level statement from the command line,
174:                    // trapping errors as they happen.  We quit on null.
175:                    final String command = read();
176:                    if (command == null) {
177:                        close();
178:                        break;
179:                    }
180:
181:                    reset();
182:
183:                    if (command.length() > 0) {
184:                        // We have a command that parses, so evaluate it.
185:                        try {
186:                            lastResult = shell.evaluate(command,
187:                                    "CommandLine.groovy");
188:                            out.println("\n===> " + lastResult);
189:                        } catch (CompilationFailedException e) {
190:                            err.println(e);
191:                        } catch (Throwable e) {
192:                            if (e instanceof  InvokerInvocationException) {
193:                                InvokerInvocationException iie = (InvokerInvocationException) e;
194:                                e = iie.getCause();
195:                            }
196:                            filterAndPrintStackTrace(e);
197:                        }
198:                    }
199:                }
200:            }
201:
202:            /**
203:             * Filter stacktraces to show only relevant lines of the exception thrown.
204:             *
205:             * @param e the throwable whose stacktrace needs to be filtered
206:             */
207:            private void filterAndPrintStackTrace(Throwable e) {
208:                err.println("Caught: " + e);
209:                StackTraceElement[] stackTrace = e.getStackTrace();
210:                for (int i = 0; i < stackTrace.length; i++) {
211:                    StackTraceElement element = stackTrace[i];
212:                    String fileName = element.getFileName();
213:                    if ((fileName == null || (!fileName.endsWith(".java"))
214:                            && (!element.getClassName().startsWith("gjdk")))) {
215:                        err.println("\tat " + element);
216:                    }
217:                }
218:            }
219:
220:            protected void close() {
221:                prompt.close();
222:            }
223:
224:            //---------------------------------------------------------------------------
225:            // COMMAND LINE PROCESSING MACHINERY
226:
227:            private StringBuffer accepted = new StringBuffer(); // The statement text accepted to date
228:            private String pending = null; // A line of statement text not yet accepted
229:            private int line = 1; // The current line number
230:
231:            private boolean stale = false; // Set to force clear of accepted
232:
233:            private SourceUnit parser = null; // A SourceUnit used to check the statement
234:            private Exception error = null; // Any actual syntax error caught during parsing
235:
236:            /**
237:             * Resets the command-line processing machinery after use.
238:             */
239:
240:            protected void reset() {
241:                stale = true;
242:                pending = null;
243:                line = 1;
244:
245:                parser = null;
246:                error = null;
247:            }
248:
249:            /**
250:             * Reads a single statement from the command line.  Also identifies
251:             * and processes command shell commands.  Returns the command text
252:             * on success, or null when command processing is complete.
253:             * <p/>
254:             * NOTE: Changed, for now, to read until 'execute' is issued.  At
255:             * 'execute', the statement must be complete.
256:             */
257:
258:            protected String read() {
259:                reset();
260:                out.println("");
261:
262:                boolean complete = false;
263:                boolean done = false;
264:
265:                while (/* !complete && */!done) {
266:
267:                    // Read a line.  If IOException or null, or command "exit", terminate
268:                    // processing.
269:
270:                    try {
271:                        pending = prompt.readLine();
272:                    } catch (IOException e) {
273:                    }
274:
275:                    if (pending == null
276:                            || (COMMAND_MAPPINGS.containsKey(pending) && ((Integer) COMMAND_MAPPINGS
277:                                    .get(pending)).intValue() == COMMAND_ID_EXIT)) {
278:                        return null; // <<<< FLOW CONTROL <<<<<<<<
279:                    }
280:
281:                    // First up, try to process the line as a command and proceed accordingly.
282:                    if (COMMAND_MAPPINGS.containsKey(pending)) {
283:                        int code = ((Integer) COMMAND_MAPPINGS.get(pending))
284:                                .intValue();
285:                        switch (code) {
286:                        case COMMAND_ID_HELP:
287:                            displayHelp();
288:                            break;
289:
290:                        case COMMAND_ID_DISCARD:
291:                            reset();
292:                            done = true;
293:                            break;
294:
295:                        case COMMAND_ID_DISPLAY:
296:                            displayStatement();
297:                            break;
298:
299:                        case COMMAND_ID_EXPLAIN:
300:                            explainStatement();
301:                            break;
302:
303:                        case COMMAND_ID_BINDING:
304:                            displayBinding();
305:                            break;
306:
307:                        case COMMAND_ID_EXECUTE:
308:                            if (complete) {
309:                                done = true;
310:                            } else {
311:                                err.println("statement not complete");
312:                            }
313:                            break;
314:                        case COMMAND_ID_DISCARD_LOADED_CLASSES:
315:                            resetLoadedClasses();
316:                            break;
317:                        case COMMAND_ID_INSPECT:
318:                            inspect();
319:                            break;
320:                        }
321:
322:                        continue; // <<<< LOOP CONTROL <<<<<<<<
323:                    }
324:
325:                    // Otherwise, it's part of a statement.  If it's just whitespace,
326:                    // we'll just accept it and move on.  Otherwise, parsing is attempted
327:                    // on the cumulated statement text, and errors are reported.  The
328:                    // pending input is accepted or rejected based on that parsing.
329:
330:                    freshen();
331:
332:                    if (pending.trim().length() == 0) {
333:                        accept();
334:                        continue; // <<<< LOOP CONTROL <<<<<<<<
335:                    }
336:
337:                    final String code = current();
338:
339:                    if (parse(code, 1)) {
340:                        accept();
341:                        complete = true;
342:                    } else if (error == null) {
343:                        accept();
344:                    } else {
345:                        report();
346:                    }
347:
348:                }
349:
350:                // Get and return the statement.
351:                return accepted(complete);
352:            }
353:
354:            private void inspect() {
355:                if (null == lastResult) {
356:                    err
357:                            .println("nothing to inspect (preceding \"go\" missing?)");
358:                    return;
359:                }
360:                // this should read: groovy.inspect.swingui.ObjectBrowser.inspect(lastResult)
361:                // but this doesnt compile since ObjectBrowser.groovy is compiled after this class.
362:                try {
363:                    Class browserClass = Class
364:                            .forName("groovy.inspect.swingui.ObjectBrowser");
365:                    Method inspectMethod = browserClass.getMethod("inspect",
366:                            new Class[] { Object.class });
367:                    inspectMethod.invoke(browserClass,
368:                            new Object[] { lastResult });
369:                } catch (Exception e) {
370:                    err.println("cannot invoke ObjectBrowser");
371:                    e.printStackTrace();
372:                }
373:            }
374:
375:            /**
376:             * Returns the accepted statement as a string.  If not <code>complete</code>,
377:             * returns the empty string.
378:             */
379:            private String accepted(boolean complete) {
380:                if (complete) {
381:                    return accepted.toString();
382:                }
383:                return "";
384:            }
385:
386:            /**
387:             * Returns the current statement, including pending text.
388:             */
389:            private String current() {
390:                return accepted.toString() + pending + "\n";
391:            }
392:
393:            /**
394:             * Accepts the pending text into the statement.
395:             */
396:            private void accept() {
397:                accepted.append(pending).append("\n");
398:                line += 1;
399:            }
400:
401:            /**
402:             * Clears accepted if stale.
403:             */
404:            private void freshen() {
405:                if (stale) {
406:                    accepted.setLength(0);
407:                    stale = false;
408:                }
409:            }
410:
411:            //---------------------------------------------------------------------------
412:            // SUPPORT ROUTINES
413:
414:            /**
415:             * Attempts to parse the specified code with the specified tolerance.
416:             * Updates the <code>parser</code> and <code>error</code> members
417:             * appropriately.  Returns true if the text parsed, false otherwise.
418:             * The attempts to identify and suppress errors resulting from the
419:             * unfinished source text.
420:             */
421:            private boolean parse(String code, int tolerance) {
422:                boolean parsed = false;
423:
424:                parser = null;
425:                error = null;
426:
427:                // Create the parser and attempt to parse the text as a top-level statement.
428:                try {
429:                    parser = SourceUnit.create("groovysh script", code,
430:                            tolerance);
431:                    parser.parse();
432:
433:                    parsed = true;
434:                }
435:
436:                // We report errors other than unexpected EOF to the user.
437:                catch (CompilationFailedException e) {
438:                    if (parser.getErrorCollector().getErrorCount() > 1
439:                            || !parser.failedWithUnexpectedEOF()) {
440:                        error = e;
441:                    }
442:                } catch (Exception e) {
443:                    error = e;
444:                }
445:
446:                return parsed;
447:            }
448:
449:            /**
450:             * Reports the last parsing error to the user.
451:             */
452:
453:            private void report() {
454:                err.println("Discarding invalid text:");
455:                new ErrorReporter(error, false).write(err);
456:            }
457:
458:            //-----------------------------------------------------------------------
459:            // COMMANDS
460:
461:            private static final int COMMAND_ID_EXIT = 0;
462:            private static final int COMMAND_ID_HELP = 1;
463:            private static final int COMMAND_ID_DISCARD = 2;
464:            private static final int COMMAND_ID_DISPLAY = 3;
465:            private static final int COMMAND_ID_EXPLAIN = 4;
466:            private static final int COMMAND_ID_EXECUTE = 5;
467:            private static final int COMMAND_ID_BINDING = 6;
468:            private static final int COMMAND_ID_DISCARD_LOADED_CLASSES = 7;
469:            private static final int COMMAND_ID_INSPECT = 8;
470:
471:            private static final int LAST_COMMAND_ID = 8;
472:
473:            private static final String[] COMMANDS = { "exit", "help",
474:                    "discard", "display", "explain", "execute", "binding",
475:                    "discardclasses", "inspect" };
476:
477:            private static final Map COMMAND_MAPPINGS = new HashMap();
478:
479:            static {
480:                for (int i = 0; i <= LAST_COMMAND_ID; i++) {
481:                    COMMAND_MAPPINGS.put(COMMANDS[i], new Integer(i));
482:                }
483:
484:                // A few synonyms
485:
486:                COMMAND_MAPPINGS.put("quit", new Integer(COMMAND_ID_EXIT));
487:                COMMAND_MAPPINGS.put("go", new Integer(COMMAND_ID_EXECUTE));
488:            }
489:
490:            private static final Map COMMAND_HELP = new HashMap();
491:
492:            static {
493:                COMMAND_HELP.put(COMMANDS[COMMAND_ID_EXIT],
494:                        "exit/quit         - terminates processing");
495:                COMMAND_HELP.put(COMMANDS[COMMAND_ID_HELP],
496:                        "help              - displays this help text");
497:                COMMAND_HELP.put(COMMANDS[COMMAND_ID_DISCARD],
498:                        "discard           - discards the current statement");
499:                COMMAND_HELP.put(COMMANDS[COMMAND_ID_DISPLAY],
500:                        "display           - displays the current statement");
501:                COMMAND_HELP
502:                        .put(
503:                                COMMANDS[COMMAND_ID_EXPLAIN],
504:                                "explain           - explains the parsing of the current statement (currently disabled)");
505:                COMMAND_HELP
506:                        .put(COMMANDS[COMMAND_ID_EXECUTE],
507:                                "execute/go        - temporary command to cause statement execution");
508:                COMMAND_HELP
509:                        .put(COMMANDS[COMMAND_ID_BINDING],
510:                                "binding           - shows the binding used by this interactive shell");
511:                COMMAND_HELP
512:                        .put(COMMANDS[COMMAND_ID_DISCARD_LOADED_CLASSES],
513:                                "discardclasses    - discards all former unbound class definitions");
514:                COMMAND_HELP
515:                        .put(
516:                                COMMANDS[COMMAND_ID_INSPECT],
517:                                "inspect           - opens ObjectBrowser on expression returned from previous \"go\"");
518:            }
519:
520:            /**
521:             * Displays help text about available commands.
522:             */
523:            private void displayHelp() {
524:                out
525:                        .println("Available commands (must be entered without extraneous characters):");
526:                for (int i = 0; i <= LAST_COMMAND_ID; i++) {
527:                    out.println((String) COMMAND_HELP.get(COMMANDS[i]));
528:                }
529:            }
530:
531:            /**
532:             * Displays the accepted statement.
533:             */
534:            private void displayStatement() {
535:                final String[] lines = accepted.toString().split("\n");
536:                for (int i = 0; i < lines.length; i++) {
537:                    out.println((i + 1) + "> " + lines[i]);
538:                }
539:            }
540:
541:            /**
542:             * Displays the current binding used when instanciating the shell.
543:             */
544:            private void displayBinding() {
545:                out.println("Available variables in the current binding");
546:                Binding context = shell.getContext();
547:                Map variables = context.getVariables();
548:                Set set = variables.keySet();
549:                if (set.isEmpty()) {
550:                    out.println("The current binding is empty.");
551:                } else {
552:                    for (Iterator it = set.iterator(); it.hasNext();) {
553:                        String key = (String) it.next();
554:                        out.println(key + " = " + variables.get(key));
555:                    }
556:                }
557:            }
558:
559:            /**
560:             * Attempts to parse the accepted statement and display the
561:             * parse tree for it.
562:             */
563:            private void explainStatement() {
564:                if (parse(accepted(true), 10) || error == null) {
565:                    out.println("Parse tree:");
566:                    //out.println(tree);
567:                } else {
568:                    out.println("Statement does not parse");
569:                }
570:            }
571:
572:            private void resetLoadedClasses() {
573:                shell.resetLoadedClasses();
574:                out
575:                        .println("all former unbound class definitions are discarded");
576:            }
577:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.