Source Code Cross Referenced for JellyContext.java in  » Library » Apache-commons-jelly-1.0-src » org » apache » commons » jelly » 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 » Library » Apache commons jelly 1.0 src » org.apache.commons.jelly 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2002,2004 The Apache Software Foundation.
003:         *
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         *
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:        package org.apache.commons.jelly;
017:
018:        import java.io.File;
019:        import java.io.IOException;
020:        import java.io.InputStream;
021:        import java.net.MalformedURLException;
022:        import java.net.URL;
023:        import java.util.Collections;
024:        import java.util.HashMap;
025:        import java.util.Hashtable;
026:        import java.util.Iterator;
027:        import java.util.Map;
028:        import java.util.WeakHashMap;
029:
030:        import org.apache.commons.jelly.parser.XMLParser;
031:        import org.apache.commons.jelly.util.ClassLoaderUtils;
032:        import org.apache.commons.logging.Log;
033:        import org.apache.commons.logging.LogFactory;
034:        import org.xml.sax.InputSource;
035:        import org.xml.sax.SAXException;
036:
037:        /**
038:         * <p><code>JellyContext</code> represents the Jelly context.</p>
039:         *
040:         * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
041:         * @version $Revision: 165507 $
042:         */
043:        public class JellyContext {
044:
045:            /** The Log to which logging calls will be made. */
046:            private static final Log log = LogFactory
047:                    .getLog(JellyContext.class);
048:
049:            /** Default for inheritance of variables **/
050:            private static final boolean DEFAULT_INHERIT = true;
051:
052:            /** Default for export of variables **/
053:            private static final boolean DEFAULT_EXPORT = false;
054:
055:            /** String used to denote a script can't be parsed */
056:            private static final String BAD_PARSE = "Could not parse Jelly script";
057:
058:            /**
059:             * The class loader to use for instantiating application objects.
060:             * If not specified, the context class loader, or the class loader
061:             * used to load this class itself, is used, based on the value of the
062:             * <code>useContextClassLoader</code> variable.
063:             */
064:            protected ClassLoader classLoader;
065:
066:            /**
067:             * Do we want to use the Context ClassLoader when loading classes
068:             * for instantiating new objects?  Default is <code>false</code>.
069:             */
070:            protected boolean useContextClassLoader = false;
071:
072:            /** The root URL context (where scripts are located from) */
073:            private URL rootURL;
074:
075:            /** The current URL context (where relative scripts are located from) */
076:            private URL currentURL;
077:
078:            /** Tag libraries found so far */
079:            private Map taglibs = new Hashtable();
080:
081:            /** synchronized access to the variables in scope */
082:            private Map variables = new Hashtable();
083:
084:            /** The parent context */
085:            private JellyContext parent;
086:
087:            /** Do we inherit variables from parent context? */
088:            private boolean inherit = JellyContext.DEFAULT_INHERIT;
089:
090:            /** Do we export our variables to parent context? */
091:            private boolean export = JellyContext.DEFAULT_EXPORT;
092:
093:            /** Should we export tag libraries to our parents context */
094:            private boolean exportLibraries = true;
095:
096:            /**
097:             * Create a new context with the currentURL set to the rootURL
098:             */
099:            public JellyContext() {
100:                this .currentURL = rootURL;
101:                init();
102:            }
103:
104:            /**
105:             * Create a new context with the given rootURL
106:             * @param rootURL the root URL used in resolving absolute resources i.e. those starting with '/'
107:             */
108:            public JellyContext(URL rootURL) {
109:                this (rootURL, rootURL);
110:            }
111:
112:            /**
113:             * Create a new context with the given rootURL and currentURL
114:             * @param rootURL the root URL used in resolving absolute resources i.e. those starting with '/'
115:             * @param currentURL the root URL used in resolving relative resources
116:             */
117:            public JellyContext(URL rootURL, URL currentURL) {
118:                this .rootURL = rootURL;
119:                this .currentURL = currentURL;
120:                init();
121:            }
122:
123:            /**
124:             * Create a new context with the given parent context.
125:             * The parent's rootURL and currentURL are set on the child, and the parent's variables are
126:             * available in the child context under the name <code>parentScope</code>.
127:             *
128:             * @param parent the parent context for the newly created context.
129:             */
130:            public JellyContext(JellyContext parent) {
131:                this .parent = parent;
132:                this .rootURL = parent.rootURL;
133:                this .currentURL = parent.currentURL;
134:                this .variables.put("parentScope", parent.variables);
135:                init();
136:            }
137:
138:            /**
139:             * Create a new context with the given parent context.
140:             * The parent's rootURL are set on the child, and the parent's variables are
141:             * available in the child context under the name <code>parentScope</code>.
142:             *
143:             * @param parentJellyContext the parent context for the newly created context.
144:             * @param currentURL the root URL used in resolving relative resources
145:             */
146:            public JellyContext(JellyContext parentJellyContext, URL currentURL) {
147:                this (parentJellyContext);
148:                this .currentURL = currentURL;
149:            }
150:
151:            /**
152:             * Create a new context with the given parent context.
153:             * The parent's variables are available in the child context under the name <code>parentScope</code>.
154:             *
155:             * @param parentJellyContext the parent context for the newly created context.
156:             * @param rootURL the root URL used in resolving absolute resources i.e. those starting with '/'
157:             * @param currentURL the root URL used in resolving relative resources
158:             */
159:            public JellyContext(JellyContext parentJellyContext, URL rootURL,
160:                    URL currentURL) {
161:                this (parentJellyContext, currentURL);
162:                this .rootURL = rootURL;
163:            }
164:
165:            /**
166:             * Initialize the context.
167:             * This includes adding the context to itself under the name <code>context</code> and
168:             * making the System Properties available as <code>systemScope</code>
169:             */
170:            private void init() {
171:                variables.put("context", this );
172:                try {
173:                    variables.put("systemScope", System.getProperties());
174:                } catch (SecurityException e) {
175:                    log.debug("security exception accessing system properties",
176:                            e);
177:                }
178:            }
179:
180:            /**
181:             * @return the parent context for this context
182:             */
183:            public JellyContext getParent() {
184:                return parent;
185:            }
186:
187:            /**
188:             * @return the scope of the given name, such as the 'parent' scope.
189:             * If Jelly is used in a Servlet situation then 'request', 'session' and 'application' are other names
190:             * for scopes
191:             */
192:            public JellyContext getScope(String name) {
193:                if ("parent".equals(name)) {
194:                    return getParent();
195:                }
196:                return null;
197:            }
198:
199:            /**
200:             * Finds the variable value of the given name in this context or in any other parent context.
201:             * If this context does not contain the variable, then its parent is used and then its parent
202:             * and so forth until the context with no parent is found.
203:             *
204:             * @return the value of the variable in this or one of its descendant contexts or null
205:             *  if the variable could not be found.
206:             */
207:            public Object findVariable(String name) {
208:                Object answer = variables.get(name);
209:                boolean definedHere = answer != null
210:                        || variables.containsKey(name);
211:
212:                if (definedHere)
213:                    return answer;
214:
215:                if (answer == null && parent != null) {
216:                    answer = parent.findVariable(name);
217:                }
218:                // ### this is a hack - remove this when we have support for pluggable Scopes
219:                if (answer == null) {
220:                    answer = getSystemProperty(name);
221:                }
222:
223:                if (log.isDebugEnabled()) {
224:                    log.debug("findVariable: " + name + " value: " + answer);
225:                }
226:                return answer;
227:            }
228:
229:            /** @return the value of the given variable name */
230:            public Object getVariable(String name) {
231:                Object value = variables.get(name);
232:                boolean definedHere = value != null
233:                        || variables.containsKey(name);
234:
235:                if (definedHere)
236:                    return value;
237:
238:                if (value == null && isInherit()) {
239:                    JellyContext parentContext = getParent();
240:                    if (parentContext != null) {
241:                        value = parentContext.getVariable(name);
242:                    }
243:                }
244:
245:                // ### this is a hack - remove this when we have support for pluggable Scopes
246:                if (value == null) {
247:                    value = getSystemProperty(name);
248:                }
249:
250:                return value;
251:            }
252:
253:            /**
254:             * Get a system property and handle security exceptions
255:             * @param name the name of the property to retrieve
256:             * @return the value of the property, or null if a SecurityException occurs
257:             */
258:            private Object getSystemProperty(String name) {
259:                try {
260:                    return System.getProperty(name);
261:                } catch (SecurityException e) {
262:                    log.debug("security exception accessing system properties",
263:                            e);
264:                }
265:                return null;
266:            }
267:
268:            /**
269:             * @return the value of the given variable name in the given variable scope
270:             * @param name is the name of the variable
271:             * @param scopeName is the optional scope name such as 'parent'. For servlet environments
272:             * this could be 'application', 'session' or 'request'.
273:             */
274:            public Object getVariable(String name, String scopeName) {
275:                JellyContext scope = getScope(scopeName);
276:                if (scope != null) {
277:                    return scope.getVariable(name);
278:                }
279:                return null;
280:            }
281:
282:            /** Sets the value of the named variable */
283:            public void setVariable(String name, Object value) {
284:                if (isExport()) {
285:                    getParent().setVariable(name, value);
286:                    return;
287:                }
288:                if (value == null) {
289:                    variables.remove(name);
290:                } else {
291:                    variables.put(name, value);
292:                }
293:            }
294:
295:            /**
296:             * Sets the value of the given variable name in the given variable scope
297:             * @param name is the name of the variable
298:             * @param scopeName is the optional scope name such as 'parent'. For servlet environments
299:             *  this could be 'application', 'session' or 'request'.
300:             * @param value is the value of the attribute
301:             */
302:            public void setVariable(String name, String scopeName, Object value) {
303:                JellyContext scope = getScope(scopeName);
304:                if (scope != null) {
305:                    scope.setVariable(name, value);
306:                }
307:            }
308:
309:            /** Removes the given variable */
310:            public void removeVariable(String name) {
311:                variables.remove(name);
312:            }
313:
314:            /**
315:             * Removes the given variable in the specified scope.
316:             *
317:             * @param name is the name of the variable
318:             * @param scopeName is the optional scope name such as 'parent'. For servlet environments
319:             *  this could be 'application', 'session' or 'request'.
320:             */
321:            public void removeVariable(String name, String scopeName) {
322:                JellyContext scope = getScope(scopeName);
323:                if (scope != null) {
324:                    scope.removeVariable(name);
325:                }
326:            }
327:
328:            /**
329:             * @return an Iterator over the current variable names in this
330:             * context
331:             */
332:            public Iterator getVariableNames() {
333:                return variables.keySet().iterator();
334:            }
335:
336:            /**
337:             * @return the Map of variables in this scope
338:             */
339:            public Map getVariables() {
340:                return variables;
341:            }
342:
343:            /**
344:             * Sets the Map of variables to use
345:             */
346:            public void setVariables(Map variables) {
347:                // I have seen this fail when the passed Map contains a key, value
348:                // pair where the value is null
349:                for (Iterator iter = variables.entrySet().iterator(); iter
350:                        .hasNext();) {
351:                    Map.Entry element = (Map.Entry) iter.next();
352:                    if (element.getValue() != null) {
353:                        this .variables
354:                                .put(element.getKey(), element.getValue());
355:                    }
356:                }
357:                //this.variables.putAll( variables );
358:            }
359:
360:            /**
361:             * A factory method to create a new child context of the
362:             * current context.
363:             */
364:            public JellyContext newJellyContext(Map newVariables) {
365:                // XXXX: should allow this new context to
366:                // XXXX: inherit parent contexts?
367:                // XXXX: Or at least publish the parent scope
368:                // XXXX: as a Map in this new variable scope?
369:                newVariables.put("parentScope", variables);
370:                JellyContext answer = createChildContext();
371:                answer.setVariables(newVariables);
372:                return answer;
373:            }
374:
375:            /**
376:             * A factory method to create a new child context of the
377:             * current context.
378:             */
379:            public JellyContext newJellyContext() {
380:                return createChildContext();
381:            }
382:
383:            /** Clears variables set by Tags.
384:             * @see #clearVariables()
385:             */
386:            public void clear() {
387:                clearVariables();
388:            }
389:
390:            /** Clears variables set by Tags (variables set while running a Jelly script)
391:             * @see #clear()
392:             */
393:            protected void clearVariables() {
394:                variables.clear();
395:            }
396:
397:            /** Registers the given tag library against the given namespace URI.
398:             * This should be called before the parser is used.
399:             */
400:            public void registerTagLibrary(String namespaceURI,
401:                    TagLibrary taglib) {
402:                if (log.isDebugEnabled()) {
403:                    log.debug("Registering tag library to: " + namespaceURI
404:                            + " taglib: " + taglib);
405:                }
406:                taglibs.put(namespaceURI, taglib);
407:
408:                if (isExportLibraries() && parent != null) {
409:                    parent.registerTagLibrary(namespaceURI, taglib);
410:                }
411:            }
412:
413:            /** Registers the given tag library class name against the given namespace URI.
414:             * The class will be loaded via the given ClassLoader
415:             * This should be called before the parser is used.
416:             */
417:            public void registerTagLibrary(String namespaceURI, String className) {
418:
419:                if (log.isDebugEnabled()) {
420:                    log.debug("Registering tag library to: " + namespaceURI
421:                            + " taglib: " + className);
422:                }
423:                taglibs.put(namespaceURI, className);
424:
425:                if (isExportLibraries() && parent != null) {
426:                    parent.registerTagLibrary(namespaceURI, className);
427:                }
428:            }
429:
430:            public boolean isTagLibraryRegistered(String namespaceURI) {
431:                boolean answer = taglibs.containsKey(namespaceURI);
432:                if (answer) {
433:                    return true;
434:                } else if (parent != null) {
435:                    return parent.isTagLibraryRegistered(namespaceURI);
436:                } else {
437:                    return false;
438:                }
439:            }
440:
441:            /**
442:             * @return the TagLibrary for the given namespace URI or null if one could not be found
443:             */
444:            public TagLibrary getTagLibrary(String namespaceURI) {
445:
446:                // use my own mapping first, so that namespaceURIs can
447:                // be redefined inside child contexts...
448:
449:                Object answer = taglibs.get(namespaceURI);
450:
451:                if (answer == null && parent != null) {
452:                    answer = parent.getTagLibrary(namespaceURI);
453:                }
454:
455:                if (answer instanceof  TagLibrary) {
456:                    return (TagLibrary) answer;
457:                } else if (answer instanceof  String) {
458:                    String className = (String) answer;
459:                    Class theClass = null;
460:                    try {
461:                        theClass = getClassLoader().loadClass(className);
462:                    } catch (ClassNotFoundException e) {
463:                        log.error("Could not find the class: " + className, e);
464:                    }
465:                    if (theClass != null) {
466:                        try {
467:                            Object object = theClass.newInstance();
468:                            if (object instanceof  TagLibrary) {
469:                                taglibs.put(namespaceURI, object);
470:                                return (TagLibrary) object;
471:                            } else {
472:                                log.error("The tag library object mapped to: "
473:                                        + namespaceURI
474:                                        + " is not a TagLibrary. Object = "
475:                                        + object);
476:                            }
477:                        } catch (Exception e) {
478:                            log.error(
479:                                    "Could not instantiate instance of class: "
480:                                            + className + ". Reason: " + e, e);
481:                        }
482:                    }
483:                }
484:
485:                return null;
486:            }
487:
488:            /**
489:             * Attempts to parse the script from the given uri using the
490:             * {@link #getResource} method then returns the compiled script.
491:             */
492:            public Script compileScript(String uri) throws JellyException {
493:                XMLParser parser = getXMLParser();
494:                parser.setContext(this );
495:                InputStream in = getResourceAsStream(uri);
496:                if (in == null) {
497:                    throw new JellyException("Could not find Jelly script: "
498:                            + uri);
499:                }
500:                Script script = null;
501:                try {
502:                    script = parser.parse(in);
503:                } catch (IOException e) {
504:                    throw new JellyException(JellyContext.BAD_PARSE, e);
505:                } catch (SAXException e) {
506:                    throw new JellyException(JellyContext.BAD_PARSE, e);
507:                }
508:
509:                return script.compile();
510:            }
511:
512:            /**
513:             * Attempts to parse the script from the given URL using the
514:             * {@link #getResource} method then returns the compiled script.
515:             */
516:            public Script compileScript(URL url) throws JellyException {
517:                XMLParser parser = getXMLParser();
518:                parser.setContext(this );
519:
520:                Script script = null;
521:                try {
522:                    script = parser.parse(url.toString());
523:                } catch (IOException e) {
524:                    throw new JellyException(JellyContext.BAD_PARSE, e);
525:                } catch (SAXException e) {
526:                    throw new JellyException(JellyContext.BAD_PARSE, e);
527:                }
528:
529:                return script.compile();
530:            }
531:
532:            /**
533:             * Attempts to parse the script from the given InputSource using the
534:             * {@link #getResource} method then returns the compiled script.
535:             */
536:            public Script compileScript(InputSource source)
537:                    throws JellyException {
538:                XMLParser parser = getXMLParser();
539:                parser.setContext(this );
540:
541:                Script script = null;
542:                try {
543:                    script = parser.parse(source);
544:                } catch (IOException e) {
545:                    throw new JellyException(JellyContext.BAD_PARSE, e);
546:                } catch (SAXException e) {
547:                    throw new JellyException(JellyContext.BAD_PARSE, e);
548:                }
549:
550:                return script.compile();
551:            }
552:
553:            /**
554:             * @return a thread pooled XMLParser to avoid the startup overhead
555:             * of the XMLParser
556:             */
557:            protected XMLParser getXMLParser() {
558:                XMLParser parser = createXMLParser();
559:                return parser;
560:            }
561:
562:            /**
563:             * Factory method to allow JellyContext implementations to overload how an XMLParser
564:             * is created - such as to overload what the default ExpressionFactory should be.
565:             */
566:            protected XMLParser createXMLParser() {
567:                return new XMLParser();
568:            }
569:
570:            /**
571:             * Parses the script from the given File then compiles it and runs it.
572:             *
573:             * @return the new child context that was used to run the script
574:             */
575:            public JellyContext runScript(File file, XMLOutput output)
576:                    throws JellyException {
577:                try {
578:                    return runScript(file.toURL(), output,
579:                            JellyContext.DEFAULT_EXPORT,
580:                            JellyContext.DEFAULT_INHERIT);
581:                } catch (MalformedURLException e) {
582:                    throw new JellyException(e.toString());
583:                }
584:            }
585:
586:            /**
587:             * Parses the script from the given URL then compiles it and runs it.
588:             *
589:             * @return the new child context that was used to run the script
590:             */
591:            public JellyContext runScript(URL url, XMLOutput output)
592:                    throws JellyException {
593:                return runScript(url, output, JellyContext.DEFAULT_EXPORT,
594:                        JellyContext.DEFAULT_INHERIT);
595:            }
596:
597:            /**
598:             * Parses the script from the given InputSource then compiles it and runs it.
599:             *
600:             * @return the new child context that was used to run the script
601:             */
602:            public JellyContext runScript(InputSource source, XMLOutput output)
603:                    throws JellyException {
604:                return runScript(source, output, JellyContext.DEFAULT_EXPORT,
605:                        JellyContext.DEFAULT_INHERIT);
606:            }
607:
608:            /**
609:             * Parses the script from the given uri using the
610:             * JellyContext.getResource() API then compiles it and runs it.
611:             *
612:             * @return the new child context that was used to run the script
613:             */
614:            public JellyContext runScript(String uri, XMLOutput output)
615:                    throws JellyException {
616:                URL url = null;
617:                try {
618:                    url = getResource(uri);
619:                } catch (MalformedURLException e) {
620:                    throw new JellyException(e.toString());
621:                }
622:
623:                if (url == null) {
624:                    throw new JellyException("Could not find Jelly script: "
625:                            + url);
626:                }
627:                return runScript(url, output, JellyContext.DEFAULT_EXPORT,
628:                        JellyContext.DEFAULT_INHERIT);
629:            }
630:
631:            /**
632:             * Parses the script from the given uri using the
633:             * JellyContext.getResource() API then compiles it and runs it.
634:             *
635:             * @return the new child context that was used to run the script
636:             */
637:            public JellyContext runScript(String uri, XMLOutput output,
638:                    boolean export, boolean inherit) throws JellyException {
639:                URL url = null;
640:                try {
641:                    url = getResource(uri);
642:                } catch (MalformedURLException e) {
643:                    throw new JellyException(e.toString());
644:                }
645:
646:                if (url == null) {
647:                    throw new JellyException("Could not find Jelly script: "
648:                            + url);
649:                }
650:
651:                return runScript(url, output, export, inherit);
652:            }
653:
654:            /**
655:             * Parses the script from the given file then compiles it and runs it.
656:             *
657:             * @return the new child context that was used to run the script
658:             */
659:            public JellyContext runScript(File file, XMLOutput output,
660:                    boolean export, boolean inherit) throws JellyException {
661:                try {
662:                    return runScript(file.toURL(), output, export, inherit);
663:                } catch (MalformedURLException e) {
664:                    throw new JellyException(e.toString());
665:                }
666:            }
667:
668:            /**
669:             * Parses the script from the given URL then compiles it and runs it.
670:             *
671:             * @return the new child context that was used to run the script
672:             */
673:            public JellyContext runScript(URL url, XMLOutput output,
674:                    boolean export, boolean inherit) throws JellyException {
675:                return runScript(new InputSource(url.toString()), output,
676:                        export, inherit);
677:            }
678:
679:            /**
680:             * Parses the script from the given InputSource then compiles it and runs it.
681:             *
682:             * @return the new child context that was used to run the script
683:             */
684:            public JellyContext runScript(InputSource source, XMLOutput output,
685:                    boolean export, boolean inherit) throws JellyException {
686:                Script script = compileScript(source);
687:
688:                URL newJellyContextURL = null;
689:                try {
690:                    newJellyContextURL = getJellyContextURL(source);
691:                } catch (MalformedURLException e) {
692:                    throw new JellyException(e.toString());
693:                }
694:
695:                JellyContext newJellyContext = newJellyContext();
696:                newJellyContext.setRootURL(newJellyContextURL);
697:                newJellyContext.setCurrentURL(newJellyContextURL);
698:                newJellyContext.setExport(export);
699:                newJellyContext.setInherit(inherit);
700:
701:                if (inherit) {
702:                    // use the same variable scopes
703:                    newJellyContext.variables = this .variables;
704:                }
705:
706:                if (log.isDebugEnabled()) {
707:                    log.debug("About to run script: " + source.getSystemId());
708:                    log.debug("root context URL: " + newJellyContext.rootURL);
709:                    log.debug("current context URL: "
710:                            + newJellyContext.currentURL);
711:                }
712:
713:                script.run(newJellyContext, output);
714:
715:                return newJellyContext;
716:            }
717:
718:            /**
719:             * Returns a URL for the given resource from the specified path.
720:             * If the uri starts with "/" then the path is taken as relative to
721:             * the current context root.
722:             * If the uri is a well formed URL then it is used.
723:             * If the uri is a file that exists and can be read then it is used.
724:             * Otherwise the uri is interpreted as relative to the current context (the
725:             * location of the current script).
726:             */
727:            public URL getResource(String uri) throws MalformedURLException {
728:                if (uri.startsWith("/")) {
729:                    // append this uri to the context root
730:                    return createRelativeURL(rootURL, uri.substring(1));
731:                } else {
732:                    try {
733:                        return new URL(uri);
734:                    } catch (MalformedURLException e) {
735:                        // lets try find a relative resource
736:                        try {
737:                            return createRelativeURL(currentURL, uri);
738:                        } catch (MalformedURLException e2) {
739:                            throw e;
740:                        }
741:                    }
742:                }
743:            }
744:
745:            /**
746:             * Attempts to open an InputStream to the given resource at the specified path.
747:             * If the uri starts with "/" then the path is taken as relative to
748:             * the current context root. If the uri is a well formed URL then it
749:             * is used. Otherwise the uri is interpreted as relative to the current
750:             * context (the location of the current script).
751:             *
752:             * @return null if this resource could not be loaded, otherwise the resources
753:             *  input stream is returned.
754:             */
755:            public InputStream getResourceAsStream(String uri) {
756:                try {
757:                    URL url = getResource(uri);
758:                    return url.openStream();
759:                } catch (Exception e) {
760:                    if (log.isTraceEnabled()) {
761:                        log.trace("Caught exception attempting to open: " + uri
762:                                + ". Exception: " + e, e);
763:                    }
764:                    return null;
765:                }
766:            }
767:
768:            // Properties
769:            //-------------------------------------------------------------------------
770:
771:            /**
772:             * @return the current root context URL from which all absolute resource URIs
773:             *  will be relative to. For example in a web application the root URL will
774:             *  map to the web directory which contains the WEB-INF directory.
775:             */
776:            public URL getRootURL() {
777:                return rootURL;
778:            }
779:
780:            /**
781:             * Sets the current root context URL from which all absolute resource URIs
782:             *  will be relative to. For example in a web application the root URL will
783:             *  map to the web directory which contains the WEB-INF directory.
784:             */
785:            public void setRootURL(URL rootURL) {
786:                this .rootURL = rootURL;
787:            }
788:
789:            /**
790:             * @return the current URL context of the current script that is executing.
791:             *  This URL context is used to deduce relative scripts when relative URIs are
792:             *  used in calls to {@link #getResource} to process relative scripts.
793:             */
794:            public URL getCurrentURL() {
795:                return currentURL;
796:            }
797:
798:            /**
799:             * Sets the current URL context of the current script that is executing.
800:             *  This URL context is used to deduce relative scripts when relative URIs are
801:             *  used in calls to {@link #getResource} to process relative scripts.
802:             */
803:            public void setCurrentURL(URL currentURL) {
804:                this .currentURL = currentURL;
805:            }
806:
807:            /**
808:             * Returns whether we export tag libraries to our parents context
809:             * @return boolean
810:             */
811:            public boolean isExportLibraries() {
812:                return exportLibraries;
813:            }
814:
815:            /**
816:             * Sets whether we export tag libraries to our parents context
817:             * @param exportLibraries The exportLibraries to set
818:             */
819:            public void setExportLibraries(boolean exportLibraries) {
820:                this .exportLibraries = exportLibraries;
821:            }
822:
823:            /**
824:             * Sets whether we should export variable definitions to our parent context
825:             */
826:            public void setExport(boolean export) {
827:                this .export = export;
828:            }
829:
830:            /**
831:             * @return whether we should export variable definitions to our parent context
832:             */
833:            public boolean isExport() {
834:                return this .export;
835:            }
836:
837:            /**
838:             * Sets whether we should inherit variables from our parent context
839:             */
840:            public void setInherit(boolean inherit) {
841:                this .inherit = inherit;
842:            }
843:
844:            /**
845:             * @return whether we should inherit variables from our parent context
846:             */
847:            public boolean isInherit() {
848:                return this .inherit;
849:            }
850:
851:            /**
852:             * Return the class loader to be used for instantiating application objects
853:             * when required.  This is determined based upon the following rules:
854:             * <ul>
855:             * <li>The class loader set by <code>setClassLoader()</code>, if any</li>
856:             * <li>The thread context class loader, if it exists and the
857:             *     <code>useContextClassLoader</code> property is set to true</li>
858:             * <li>The class loader used to load the XMLParser class itself.
859:             * </ul>
860:             */
861:            public ClassLoader getClassLoader() {
862:                return ClassLoaderUtils.getClassLoader(classLoader,
863:                        useContextClassLoader, getClass());
864:            }
865:
866:            /**
867:             * Set the class loader to be used for instantiating application objects
868:             * when required.
869:             *
870:             * @param classLoader The new class loader to use, or <code>null</code>
871:             *  to revert to the standard rules
872:             */
873:            public void setClassLoader(ClassLoader classLoader) {
874:                this .classLoader = classLoader;
875:            }
876:
877:            /**
878:             * Return the boolean as to whether the context classloader should be used.
879:             */
880:            public boolean getUseContextClassLoader() {
881:                return useContextClassLoader;
882:            }
883:
884:            /**
885:             * Determine whether to use the Context ClassLoader (the one found by
886:             * calling <code>Thread.currentThread().getContextClassLoader()</code>)
887:             * to resolve/load classes.  If not
888:             * using Context ClassLoader, then the class-loading defaults to
889:             * using the calling-class' ClassLoader.
890:             *
891:             * @param use determines whether to use JellyContext ClassLoader.
892:             */
893:            public void setUseContextClassLoader(boolean use) {
894:                useContextClassLoader = use;
895:            }
896:
897:            // Implementation methods
898:            //-------------------------------------------------------------------------
899:            /**
900:             * @return a new relative URL from the given root and with the addition of the
901:             * extra relative URI
902:             *
903:             * @param rootURL is the root context from which the relative URI will be applied
904:             * @param relativeURI is the relative URI (without a leading "/")
905:             * @throws MalformedURLException if the URL is invalid.
906:             */
907:            protected URL createRelativeURL(URL rootURL, String relativeURI)
908:                    throws MalformedURLException {
909:                URL url = rootURL;
910:                if (url == null) {
911:                    File file = new File(System.getProperty("user.dir"));
912:                    url = file.toURL();
913:                }
914:                String urlText = url.toString() + relativeURI;
915:                if (log.isDebugEnabled()) {
916:                    log.debug("Attempting to open url: " + urlText);
917:                }
918:                return new URL(urlText);
919:            }
920:
921:            /**
922:             * Strips off the name of a script to create a new context URL
923:             */
924:            protected URL getJellyContextURL(URL url)
925:                    throws MalformedURLException {
926:                String text = url.toString();
927:                int idx = text.lastIndexOf('/');
928:                text = text.substring(0, idx + 1);
929:                return new URL(text);
930:            }
931:
932:            /**
933:             * Strips off the name of a script to create a new context URL
934:             */
935:            protected URL getJellyContextURL(InputSource source)
936:                    throws MalformedURLException {
937:                String text = source.getSystemId();
938:                if (text != null) {
939:                    int idx = text.lastIndexOf('/');
940:                    text = text.substring(0, idx + 1);
941:                    return new URL(text);
942:                } else {
943:                    return null;
944:                }
945:
946:            }
947:
948:            /**
949:             * Factory method to create a new child of this context
950:             */
951:            protected JellyContext createChildContext() {
952:                return new JellyContext(this );
953:            }
954:
955:            /**
956:             * Change the parent context to the one provided
957:             * @param context the new parent context
958:             */
959:            protected void setParent(JellyContext context) {
960:                parent = context;
961:                this .variables.put("parentScope", parent.variables);
962:                // need to re-export tag libraries to the new parent
963:                if (isExportLibraries() && parent != null) {
964:                    for (Iterator keys = taglibs.keySet().iterator(); keys
965:                            .hasNext();) {
966:                        String namespaceURI = (String) keys.next();
967:                        Object tagLibOrClassName = taglibs.get(namespaceURI);
968:                        if (tagLibOrClassName instanceof  TagLibrary) {
969:                            parent.registerTagLibrary(namespaceURI,
970:                                    (TagLibrary) tagLibOrClassName);
971:                        } else {
972:                            parent.registerTagLibrary(namespaceURI,
973:                                    (String) tagLibOrClassName);
974:                        }
975:                    }
976:                }
977:
978:            }
979:
980:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.