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


001:        /*
002:         * $Id: GroovyScriptEngine.java 3669 2006-02-26 22:11:48Z glaforge $version Jan 9, 2004 12:19:58 PM $user Exp $
003:         * 
004:         * Copyright 2003 (C) Sam Pullara. All Rights Reserved.
005:         * 
006:         * Redistribution and use of this software and associated documentation
007:         * ("Software"), with or without modification, are permitted provided that the
008:         * following conditions are met: 1. Redistributions of source code must retain
009:         * copyright statements and notices. Redistributions must also contain a copy
010:         * of this document. 2. Redistributions in binary form must reproduce the above
011:         * copyright notice, this list of conditions and the following disclaimer in
012:         * the documentation and/or other materials provided with the distribution. 3.
013:         * The name "groovy" must not be used to endorse or promote products derived
014:         * from this Software without prior written permission of The Codehaus. For
015:         * written permission, please contact info@codehaus.org. 4. Products derived
016:         * from this Software may not be called "groovy" nor may "groovy" appear in
017:         * their names without prior written permission of The Codehaus. "groovy" is a
018:         * registered trademark of The Codehaus. 5. Due credit should be given to The
019:         * Codehaus - http://groovy.codehaus.org/
020:         * 
021:         * THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS ``AS IS'' AND ANY
022:         * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
023:         * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
024:         * DISCLAIMED. IN NO EVENT SHALL THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR
025:         * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
026:         * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
027:         * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
028:         * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
029:         * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
030:         * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
031:         * DAMAGE.
032:         *  
033:         */
034:        package groovy.util;
035:
036:        import groovy.lang.Binding;
037:        import groovy.lang.GroovyClassLoader;
038:        import groovy.lang.Script;
039:
040:        import java.io.BufferedReader;
041:        import java.io.File;
042:        import java.io.IOException;
043:        import java.io.InputStreamReader;
044:        import java.net.MalformedURLException;
045:        import java.net.URL;
046:        import java.net.URLConnection;
047:        import java.security.AccessController;
048:        import java.security.PrivilegedAction;
049:        import java.util.Collections;
050:        import java.util.HashMap;
051:        import java.util.Iterator;
052:        import java.util.Map;
053:
054:        import org.codehaus.groovy.control.CompilationFailedException;
055:        import org.codehaus.groovy.runtime.InvokerHelper;
056:
057:        /**
058:         * Specific script engine able to reload modified scripts as well as dealing properly with dependent scripts.
059:         *
060:         * @author sam
061:         * @author Marc Palmer
062:         * @author Guillaume Laforge
063:         */
064:        public class GroovyScriptEngine implements  ResourceConnector {
065:
066:            /**
067:             * Simple testing harness for the GSE. Enter script roots as arguments and
068:             * then input script names to run them.
069:             *
070:             * @param urls
071:             * @throws Exception
072:             */
073:            public static void main(String[] urls) throws Exception {
074:                URL[] roots = new URL[urls.length];
075:                for (int i = 0; i < roots.length; i++) {
076:                    roots[i] = new File(urls[i]).toURL();
077:                }
078:                GroovyScriptEngine gse = new GroovyScriptEngine(roots);
079:                BufferedReader br = new BufferedReader(new InputStreamReader(
080:                        System.in));
081:                String line;
082:                while (true) {
083:                    System.out.print("groovy> ");
084:                    if ((line = br.readLine()) == null || line.equals("quit"))
085:                        break;
086:                    try {
087:                        System.out.println(gse.run(line, new Binding()));
088:                    } catch (Exception e) {
089:                        e.printStackTrace();
090:                    }
091:                }
092:            }
093:
094:            private URL[] roots;
095:            private Map scriptCache = Collections
096:                    .synchronizedMap(new HashMap());
097:            private ResourceConnector rc;
098:            private ClassLoader parentClassLoader = getClass().getClassLoader();
099:
100:            private static class ScriptCacheEntry {
101:                private Class scriptClass;
102:                private long lastModified;
103:                private Map dependencies = new HashMap();
104:            }
105:
106:            /**
107:             * Get a resource connection as a <code>URLConnection</code> to retrieve a script
108:             * from the <code>ResourceConnector</code>
109:             *
110:             * @param resourceName name of the resource to be retrieved
111:             * @return a URLConnection to the resource
112:             * @throws ResourceException
113:             */
114:            public URLConnection getResourceConnection(String resourceName)
115:                    throws ResourceException {
116:                // Get the URLConnection
117:                URLConnection groovyScriptConn = null;
118:
119:                ResourceException se = null;
120:                for (int i = 0; i < roots.length; i++) {
121:                    URL scriptURL = null;
122:                    try {
123:                        scriptURL = new URL(roots[i], resourceName);
124:
125:                        groovyScriptConn = scriptURL.openConnection();
126:
127:                        // Make sure we can open it, if we can't it doesn't exist.
128:                        // Could be very slow if there are any non-file:// URLs in there
129:                        groovyScriptConn.getInputStream();
130:
131:                        break; // Now this is a bit unusual
132:
133:                    } catch (MalformedURLException e) {
134:                        String message = "Malformed URL: " + roots[i] + ", "
135:                                + resourceName;
136:                        if (se == null) {
137:                            se = new ResourceException(message);
138:                        } else {
139:                            se = new ResourceException(message, se);
140:                        }
141:                    } catch (IOException e1) {
142:                        String message = "Cannot open URL: " + scriptURL;
143:                        if (se == null) {
144:                            se = new ResourceException(message);
145:                        } else {
146:                            se = new ResourceException(message, se);
147:                        }
148:                    }
149:                }
150:
151:                // If we didn't find anything, report on all the exceptions that occurred.
152:                if (groovyScriptConn == null) {
153:                    throw se;
154:                }
155:
156:                return groovyScriptConn;
157:            }
158:
159:            /**
160:             * The groovy script engine will run groovy scripts and reload them and
161:             * their dependencies when they are modified. This is useful for embedding
162:             * groovy in other containers like games and application servers.
163:             *
164:             * @param roots This an array of URLs where Groovy scripts will be stored. They should
165:             * be layed out using their package structure like Java classes 
166:             */
167:            public GroovyScriptEngine(URL[] roots) {
168:                this .roots = roots;
169:                this .rc = this ;
170:            }
171:
172:            public GroovyScriptEngine(URL[] roots, ClassLoader parentClassLoader) {
173:                this (roots);
174:                this .parentClassLoader = parentClassLoader;
175:            }
176:
177:            public GroovyScriptEngine(String[] urls) throws IOException {
178:                roots = new URL[urls.length];
179:                for (int i = 0; i < roots.length; i++) {
180:                    roots[i] = new File(urls[i]).toURL();
181:                }
182:                this .rc = this ;
183:            }
184:
185:            public GroovyScriptEngine(String[] urls,
186:                    ClassLoader parentClassLoader) throws IOException {
187:                this (urls);
188:                this .parentClassLoader = parentClassLoader;
189:            }
190:
191:            public GroovyScriptEngine(String url) throws IOException {
192:                roots = new URL[1];
193:                roots[0] = new File(url).toURL();
194:                this .rc = this ;
195:            }
196:
197:            public GroovyScriptEngine(String url, ClassLoader parentClassLoader)
198:                    throws IOException {
199:                this (url);
200:                this .parentClassLoader = parentClassLoader;
201:            }
202:
203:            public GroovyScriptEngine(ResourceConnector rc) {
204:                this .rc = rc;
205:            }
206:
207:            public GroovyScriptEngine(ResourceConnector rc,
208:                    ClassLoader parentClassLoader) {
209:                this (rc);
210:                this .parentClassLoader = parentClassLoader;
211:            }
212:
213:            /**
214:             * Get the <code>ClassLoader</code> that will serve as the parent ClassLoader of the
215:             * {@link GroovyClassLoader} in which scripts will be executed. By default, this is the
216:             * ClassLoader that loaded the <code>GroovyScriptEngine</code> class.
217:             *
218:             * @return parent classloader used to load scripts
219:             */
220:            public ClassLoader getParentClassLoader() {
221:                return parentClassLoader;
222:            }
223:
224:            /**
225:             * @param parentClassLoader ClassLoader to be used as the parent ClassLoader for scripts executed by the engine
226:             */
227:            public void setParentClassLoader(ClassLoader parentClassLoader) {
228:                if (parentClassLoader == null) {
229:                    throw new IllegalArgumentException(
230:                            "The parent class loader must not be null.");
231:                }
232:                this .parentClassLoader = parentClassLoader;
233:            }
234:
235:            /**
236:             * Get the class of the scriptName in question, so that you can instantiate Groovy objects with caching and reloading.
237:             *
238:             * @param scriptName
239:             * @return the loaded scriptName as a compiled class
240:             * @throws ResourceException
241:             * @throws ScriptException
242:             */
243:            public Class loadScriptByName(String scriptName)
244:                    throws ResourceException, ScriptException {
245:                return loadScriptByName(scriptName, getClass().getClassLoader());
246:            }
247:
248:            /**
249:             * Get the class of the scriptName in question, so that you can instantiate Groovy objects with caching and reloading.
250:             *
251:             * @param scriptName
252:             * @return the loaded scriptName as a compiled class
253:             * @throws ResourceException
254:             * @throws ScriptException
255:             */
256:            public Class loadScriptByName(String scriptName,
257:                    ClassLoader parentClassLoader) throws ResourceException,
258:                    ScriptException {
259:                scriptName = scriptName.replace('.', File.separatorChar)
260:                        + ".groovy";
261:                ScriptCacheEntry entry = updateCacheEntry(scriptName,
262:                        parentClassLoader);
263:                return entry.scriptClass;
264:            }
265:
266:            /**
267:             * Locate the class and reload it or any of its dependencies
268:             *
269:             * @param scriptName
270:             * @param parentClassLoader
271:             * @return the scriptName cache entry
272:             * @throws ResourceException
273:             * @throws ScriptException
274:             */
275:            private ScriptCacheEntry updateCacheEntry(String scriptName,
276:                    final ClassLoader parentClassLoader)
277:                    throws ResourceException, ScriptException {
278:                ScriptCacheEntry entry;
279:
280:                scriptName = scriptName.intern();
281:                synchronized (scriptName) {
282:
283:                    URLConnection groovyScriptConn = rc
284:                            .getResourceConnection(scriptName);
285:
286:                    // URL last modified
287:                    long lastModified = groovyScriptConn.getLastModified();
288:                    // Check the cache for the scriptName
289:                    entry = (ScriptCacheEntry) scriptCache.get(scriptName);
290:                    // If the entry isn't null check all the dependencies
291:
292:                    boolean dependencyOutOfDate = false;
293:                    if (entry != null) {
294:
295:                        for (Iterator i = entry.dependencies.keySet()
296:                                .iterator(); i.hasNext();) {
297:                            URLConnection urlc = null;
298:                            URL url = (URL) i.next();
299:                            try {
300:                                urlc = url.openConnection();
301:                                urlc.setDoInput(false);
302:                                urlc.setDoOutput(false);
303:                                long dependentLastModified = urlc
304:                                        .getLastModified();
305:                                if (dependentLastModified > ((Long) entry.dependencies
306:                                        .get(url)).longValue()) {
307:                                    dependencyOutOfDate = true;
308:                                    break;
309:                                }
310:                            } catch (IOException ioe) {
311:                                dependencyOutOfDate = true;
312:                                break;
313:                            }
314:                        }
315:                    }
316:
317:                    if (entry == null || entry.lastModified < lastModified
318:                            || dependencyOutOfDate) {
319:                        // Make a new entry
320:                        entry = new ScriptCacheEntry();
321:
322:                        // Closure variable
323:                        final ScriptCacheEntry finalEntry = entry;
324:
325:                        // Compile the scriptName into an object
326:                        GroovyClassLoader groovyLoader = (GroovyClassLoader) AccessController
327:                                .doPrivileged(new PrivilegedAction() {
328:                                    public Object run() {
329:                                        return new GroovyClassLoader(
330:                                                parentClassLoader) {
331:                                            protected Class findClass(
332:                                                    String className)
333:                                                    throws ClassNotFoundException {
334:                                                String filename = className
335:                                                        .replace(
336:                                                                '.',
337:                                                                File.separatorChar)
338:                                                        + ".groovy";
339:                                                URLConnection dependentScriptConn = null;
340:                                                try {
341:                                                    dependentScriptConn = rc
342:                                                            .getResourceConnection(filename);
343:                                                    finalEntry.dependencies
344:                                                            .put(
345:                                                                    dependentScriptConn
346:                                                                            .getURL(),
347:                                                                    new Long(
348:                                                                            dependentScriptConn
349:                                                                                    .getLastModified()));
350:                                                } catch (ResourceException e1) {
351:                                                    throw new ClassNotFoundException(
352:                                                            "Could not read "
353:                                                                    + className
354:                                                                    + ": " + e1);
355:                                                }
356:                                                try {
357:                                                    return parseClass(
358:                                                            dependentScriptConn
359:                                                                    .getInputStream(),
360:                                                            filename);
361:                                                } catch (CompilationFailedException e2) {
362:                                                    throw new ClassNotFoundException(
363:                                                            "Syntax error in "
364:                                                                    + className
365:                                                                    + ": " + e2);
366:                                                } catch (IOException e2) {
367:                                                    throw new ClassNotFoundException(
368:                                                            "Problem reading "
369:                                                                    + className
370:                                                                    + ": " + e2);
371:                                                }
372:                                            }
373:                                        };
374:                                    }
375:                                });
376:
377:                        try {
378:                            entry.scriptClass = groovyLoader.parseClass(
379:                                    groovyScriptConn.getInputStream(),
380:                                    scriptName);
381:                        } catch (Exception e) {
382:                            throw new ScriptException(
383:                                    "Could not parse scriptName: " + scriptName,
384:                                    e);
385:                        }
386:                        entry.lastModified = lastModified;
387:                        scriptCache.put(scriptName, entry);
388:                    }
389:                }
390:                return entry;
391:            }
392:
393:            /**
394:             * Run a script identified by name.
395:             *
396:             * @param scriptName name of the script to run
397:             * @param argument a single argument passed as a variable named <code>arg</code> in the binding
398:             * @return a <code>toString()</code> representation of the result of the execution of the script
399:             * @throws ResourceException
400:             * @throws ScriptException
401:             */
402:            public String run(String scriptName, String argument)
403:                    throws ResourceException, ScriptException {
404:                Binding binding = new Binding();
405:                binding.setVariable("arg", argument);
406:                Object result = run(scriptName, binding);
407:                return result == null ? "" : result.toString();
408:            }
409:
410:            /**
411:             * Run a script identified by name.
412:             *
413:             * @param scriptName name of the script to run
414:             * @param binding binding to pass to the script
415:             * @return an object
416:             * @throws ResourceException
417:             * @throws ScriptException
418:             */
419:            public Object run(String scriptName, Binding binding)
420:                    throws ResourceException, ScriptException {
421:
422:                ScriptCacheEntry entry = updateCacheEntry(scriptName,
423:                        getParentClassLoader());
424:                Script scriptObject = InvokerHelper.createScript(
425:                        entry.scriptClass, binding);
426:                return scriptObject.run();
427:            }
428:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.