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


0001:        /*
0002:         * Copyright 2002,2004 The Apache Software Foundation.
0003:         *
0004:         * Licensed under the Apache License, Version 2.0 (the "License");
0005:         * you may not use this file except in compliance with the License.
0006:         * You may obtain a copy of the License at
0007:         *
0008:         *      http://www.apache.org/licenses/LICENSE-2.0
0009:         *
0010:         * Unless required by applicable law or agreed to in writing, software
0011:         * distributed under the License is distributed on an "AS IS" BASIS,
0012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         * See the License for the specific language governing permissions and
0014:         * limitations under the License.
0015:         */
0016:        package org.apache.commons.jelly.parser;
0017:
0018:        import java.io.File;
0019:        import java.io.InputStream;
0020:        import java.io.IOException;
0021:        import java.io.Reader;
0022:        import java.net.URL;
0023:        import java.util.ArrayList;
0024:        import java.util.EmptyStackException;
0025:        import java.util.HashMap;
0026:        import java.util.Iterator;
0027:        import java.util.Map;
0028:        import java.util.Properties;
0029:
0030:        import javax.xml.parsers.SAXParser;
0031:        import javax.xml.parsers.SAXParserFactory;
0032:
0033:        import org.apache.commons.collections.ArrayStack;
0034:
0035:        import org.apache.commons.jelly.JellyContext;
0036:        import org.apache.commons.jelly.JellyException;
0037:        import org.apache.commons.jelly.Script;
0038:        import org.apache.commons.jelly.Tag;
0039:        import org.apache.commons.jelly.TagLibrary;
0040:        import org.apache.commons.jelly.impl.CompositeTextScriptBlock;
0041:        import org.apache.commons.jelly.impl.ExpressionScript;
0042:        import org.apache.commons.jelly.impl.StaticTag;
0043:        import org.apache.commons.jelly.impl.ScriptBlock;
0044:        import org.apache.commons.jelly.impl.StaticTagScript;
0045:        import org.apache.commons.jelly.impl.TagFactory;
0046:        import org.apache.commons.jelly.impl.TagScript;
0047:        import org.apache.commons.jelly.impl.TextScript;
0048:        import org.apache.commons.jelly.util.ClassLoaderUtils;
0049:        import org.apache.commons.jelly.expression.CompositeExpression;
0050:        import org.apache.commons.jelly.expression.ConstantExpression;
0051:        import org.apache.commons.jelly.expression.Expression;
0052:        import org.apache.commons.jelly.expression.ExpressionFactory;
0053:        import org.apache.commons.jelly.expression.jexl.JexlExpressionFactory;
0054:
0055:        import org.apache.commons.logging.Log;
0056:        import org.apache.commons.logging.LogFactory;
0057:
0058:        import org.xml.sax.Attributes;
0059:        import org.xml.sax.ErrorHandler;
0060:        import org.xml.sax.helpers.DefaultHandler;
0061:        import org.xml.sax.InputSource;
0062:        import org.xml.sax.Locator;
0063:        import org.xml.sax.SAXException;
0064:        import org.xml.sax.SAXParseException;
0065:        import org.xml.sax.XMLReader;
0066:        import org.xml.sax.helpers.AttributesImpl;
0067:
0068:        /** <p><code>XMLParser</code> parses the XML Jelly format.
0069:         * The SAXParser and XMLReader portions of this code come from Digester.</p>
0070:         *
0071:         * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
0072:         * @version $Revision: 155420 $
0073:         */
0074:        public class XMLParser extends DefaultHandler {
0075:
0076:            /**
0077:             * Share the Jelly properties across parsers
0078:             */
0079:            private static Properties jellyProperties;
0080:
0081:            /** JellyContext which is used to locate tag libraries*/
0082:            private JellyContext context = new JellyContext();
0083:
0084:            /** the expression factory used to evaluate tag attributes */
0085:            private ExpressionFactory expressionFactory;
0086:
0087:            /** The current script block */
0088:            private ScriptBlock script;
0089:
0090:            /** The current, parent tagScript */
0091:            private TagScript tagScript;
0092:
0093:            /** The stack of body scripts. */
0094:            private ArrayStack scriptStack = new ArrayStack();
0095:
0096:            /** The stack of tagScripts - use ArrayList as it allows null. */
0097:            private ArrayList tagScriptStack = new ArrayList();
0098:
0099:            /** The current text buffer where non-custom tags get written */
0100:            private StringBuffer textBuffer;
0101:
0102:            /**
0103:             * The class loader to use for instantiating application objects.
0104:             * If not specified, the context class loader, or the class loader
0105:             * used to load XMLParser itself, is used, based on the value of the
0106:             * <code>useContextClassLoader</code> variable.
0107:             */
0108:            protected ClassLoader classLoader = null;
0109:
0110:            /**
0111:             * Do we want to use the Context ClassLoader when loading classes
0112:             * for instantiating new objects?  Default is <code>false</code>.
0113:             */
0114:            protected boolean useContextClassLoader = false;
0115:
0116:            /**
0117:             * The application-supplied error handler that is notified when parsing
0118:             * warnings, errors, or fatal errors occur.
0119:             */
0120:            protected ErrorHandler errorHandler = null;
0121:
0122:            /**
0123:             * The SAXParserFactory that is created the first time we need it.
0124:             */
0125:            protected static SAXParserFactory factory = null;
0126:
0127:            /**
0128:             * The SAXParser we will use to parse the input stream.
0129:             */
0130:            protected SAXParser parser = null;
0131:
0132:            /**
0133:             * The XMLReader used to parse digester rules.
0134:             */
0135:            protected XMLReader reader = null;
0136:
0137:            /**
0138:             * The Locator associated with our parser.
0139:             */
0140:            protected Locator locator = null;
0141:
0142:            /**
0143:             * Registered namespaces we are currently processing.  The key is the
0144:             * namespace prefix that was declared in the document.  The value is an
0145:             * ArrayStack of the namespace URIs this prefix has been mapped to --
0146:             * the top Stack element is the most current one.  (This architecture
0147:             * is required because documents can declare nested uses of the same
0148:             * prefix for different Namespace URIs).
0149:             */
0150:            protected Map namespaces = new HashMap();
0151:
0152:            /** The Map of the namespace prefix -&gt; URIs defined for the current element */
0153:            private Map elementNamespaces;
0154:
0155:            /**
0156:             * The name of the file being parsed that is passed to the TagScript objects
0157:             * for error reporting
0158:             */
0159:            private String fileName;
0160:
0161:            /**
0162:             * Do we want to use a validating parser?
0163:             */
0164:            protected boolean validating = false;
0165:
0166:            /** Flag to indicate if this object has been configured */
0167:            private boolean configured;
0168:
0169:            /**
0170:             * when not null, set the default namespace for
0171:             * unprefixed elements via the DefaultNamespaceFilter
0172:             * class
0173:             */
0174:            private String defaultNamespaceURI = null;
0175:
0176:            /**
0177:             * The Log to which logging calls will be made.
0178:             */
0179:            private Log log = LogFactory.getLog(XMLParser.class);
0180:
0181:            /**
0182:             * Construct a new XMLParser with default properties.
0183:             */
0184:            public XMLParser() {
0185:            }
0186:
0187:            /**
0188:             * Construct a new XMLParser, allowing a SAXParser to be passed in.  This
0189:             * allows XMLParser to be used in environments which are unfriendly to
0190:             * JAXP1.1 (such as WebLogic 6.0).  Thanks for the request to change go to
0191:             * James House (james@interobjective.com).  This may help in places where
0192:             * you are able to load JAXP 1.1 classes yourself.
0193:             */
0194:            public XMLParser(SAXParser parser) {
0195:                this .parser = parser;
0196:            }
0197:
0198:            /**
0199:             * Construct a new XMLParser, allowing an XMLReader to be passed in.  This
0200:             * allows XMLParser to be used in environments which are unfriendly to
0201:             * JAXP1.1 (such as WebLogic 6.0).  Note that if you use this option you
0202:             * have to configure namespace and validation support yourself, as these
0203:             * properties only affect the SAXParser and emtpy constructor.
0204:             */
0205:            public XMLParser(XMLReader reader) {
0206:                this .reader = reader;
0207:            }
0208:
0209:            /**
0210:             * Parse the content of the specified file using this XMLParser.  Returns
0211:             * the root element from the object stack (if any).
0212:             *
0213:             * @param file File containing the XML data to be parsed
0214:             *
0215:             * @exception IOException if an input/output error occurs
0216:             * @exception SAXException if a parsing exception occurs
0217:             */
0218:            public Script parse(File file) throws IOException, SAXException {
0219:                return parse(file.toURL());
0220:            }
0221:
0222:            /**
0223:             * Parse the content of the specified file using this XMLParser.  Returns
0224:             * the root element from the object stack (if any).
0225:             *
0226:             * @param url URL containing the XML data to be parsed
0227:             *
0228:             * @exception IOException if an input/output error occurs
0229:             * @exception SAXException if a parsing exception occurs
0230:             */
0231:            public Script parse(URL url) throws IOException, SAXException {
0232:                ensureConfigured();
0233:                this .fileName = url.toString();
0234:
0235:                InputSource source = new InputSource(url.toString());
0236:
0237:                getXMLReader().parse(source);
0238:                return script;
0239:            }
0240:
0241:            /**
0242:             * Parse the content of the specified input source using this XMLParser.
0243:             * Returns the root element from the object stack (if any).
0244:             *
0245:             * @param input Input source containing the XML data to be parsed
0246:             *
0247:             * @exception IOException if an input/output error occurs
0248:             * @exception SAXException if a parsing exception occurs
0249:             */
0250:            public Script parse(InputSource input) throws IOException,
0251:                    SAXException {
0252:                ensureConfigured();
0253:                this .fileName = input.getSystemId();
0254:                getXMLReader().parse(input);
0255:                return script;
0256:            }
0257:
0258:            /**
0259:             * Parse the content of the specified input stream using this XMLParser.
0260:             * Returns the root element from the object stack (if any).
0261:             * (Note: if reading a File or URL, use one of the URL-based
0262:             * parse methods instead.  This method will not be able
0263:             * to resolve any relative paths inside a DTD.)
0264:             *
0265:             * @param input  Input stream containing the XML data to be parsed
0266:             * @return
0267:             * @exception IOException
0268:             *                   if an input/output error occurs
0269:             * @exception SAXException
0270:             *                   if a parsing exception occurs
0271:             */
0272:            public Script parse(InputStream input) throws IOException,
0273:                    SAXException {
0274:                ensureConfigured();
0275:                this .fileName = getCurrentURI();
0276:                getXMLReader().parse(new InputSource(input));
0277:                return script;
0278:            }
0279:
0280:            /**
0281:             * Parse the content of the specified reader using this XMLParser.
0282:             * Returns the root element from the object stack (if any).
0283:             * (Note: if reading a File or URL, use one of the URL-based
0284:             * parse methods instead.  This method will not be able
0285:             * to resolve any relative paths inside a DTD.)
0286:             *
0287:             * @param reader Reader containing the XML data to be parsed
0288:             * @return
0289:             * @exception IOException
0290:             *                   if an input/output error occurs
0291:             * @exception SAXException
0292:             *                   if a parsing exception occurs
0293:             */
0294:            public Script parse(Reader reader) throws IOException, SAXException {
0295:                ensureConfigured();
0296:                this .fileName = getCurrentURI();
0297:                getXMLReader().parse(new InputSource(reader));
0298:                return script;
0299:            }
0300:
0301:            /**
0302:             * Parse the content of the specified URI using this XMLParser.
0303:             * Returns the root element from the object stack (if any).
0304:             *
0305:             * @param uri URI containing the XML data to be parsed
0306:             *
0307:             * @exception IOException if an input/output error occurs
0308:             * @exception SAXException if a parsing exception occurs
0309:             */
0310:            public Script parse(String uri) throws IOException, SAXException {
0311:                ensureConfigured();
0312:                this .fileName = uri;
0313:                getXMLReader().parse(uri);
0314:                return script;
0315:            }
0316:
0317:            /**
0318:             * Return the currently mapped namespace URI for the specified prefix,
0319:             * if any; otherwise return <code>null</code>.  These mappings come and
0320:             * go dynamically as the document is parsed.
0321:             *
0322:             * @param prefix Prefix to look up
0323:             */
0324:            public String findNamespaceURI(String prefix) {
0325:                ArrayStack stack = (ArrayStack) namespaces.get(prefix);
0326:                if (stack == null) {
0327:                    return (null);
0328:                }
0329:                try {
0330:                    return ((String) stack.peek());
0331:                } catch (EmptyStackException e) {
0332:                    return (null);
0333:                }
0334:            }
0335:
0336:            // Properties
0337:            //-------------------------------------------------------------------------
0338:            public JellyContext getContext() {
0339:                return context;
0340:            }
0341:
0342:            public void setContext(JellyContext context) {
0343:                this .context = context;
0344:            }
0345:
0346:            /**
0347:             * Set the jelly namespace to use for unprefixed elements.
0348:             * Will be overridden by an explicit namespace in the
0349:             * XML document.
0350:             *
0351:             * @param namespace jelly namespace to use (e.g. 'jelly:core')
0352:             */
0353:            public void setDefaultNamespaceURI(String namespace) {
0354:                this .defaultNamespaceURI = namespace;
0355:            }
0356:
0357:            /**
0358:             * Return the class loader to be used for instantiating application objects
0359:             * when required.  This is determined based upon the following rules:
0360:             * <ul>
0361:             * <li>The class loader set by <code>setClassLoader()</code>, if any</li>
0362:             * <li>The thread context class loader, if it exists and the
0363:             *     <code>useContextClassLoader</code> property is set to true</li>
0364:             * <li>The class loader used to load the XMLParser class itself.
0365:             * </ul>
0366:             */
0367:            public ClassLoader getClassLoader() {
0368:                return ClassLoaderUtils.getClassLoader(classLoader,
0369:                        useContextClassLoader, getClass());
0370:            }
0371:
0372:            /**
0373:             * Set the class loader to be used for instantiating application objects
0374:             * when required.
0375:             *
0376:             * @param classLoader The new class loader to use, or <code>null</code>
0377:             *  to revert to the standard rules
0378:             */
0379:            public void setClassLoader(ClassLoader classLoader) {
0380:                this .classLoader = classLoader;
0381:            }
0382:
0383:            /**
0384:             * Return the boolean as to whether the context classloader should be used.
0385:             */
0386:            public boolean getUseContextClassLoader() {
0387:                return useContextClassLoader;
0388:            }
0389:
0390:            /**
0391:             * Determine whether to use the Context ClassLoader (the one found by
0392:             * calling <code>Thread.currentThread().getContextClassLoader()</code>)
0393:             * to resolve/load classes.  If not
0394:             * using Context ClassLoader, then the class-loading defaults to
0395:             * using the calling-class' ClassLoader.
0396:             *
0397:             * @param use determines whether to use JellyContext ClassLoader.
0398:             */
0399:            public void setUseContextClassLoader(boolean use) {
0400:                useContextClassLoader = use;
0401:            }
0402:
0403:            /**
0404:             * Return the error handler for this XMLParser.
0405:             */
0406:            public ErrorHandler getErrorHandler() {
0407:                return (this .errorHandler);
0408:            }
0409:
0410:            /**
0411:             * Set the error handler for this XMLParser.
0412:             *
0413:             * @param errorHandler The new error handler
0414:             */
0415:            public void setErrorHandler(ErrorHandler errorHandler) {
0416:                this .errorHandler = errorHandler;
0417:            }
0418:
0419:            /**
0420:             * Return the current Logger associated with this instance of the XMLParser
0421:             */
0422:            public Log getLogger() {
0423:                return log;
0424:            }
0425:
0426:            /**
0427:             * Set the current logger for this XMLParser.
0428:             */
0429:            public void setLogger(Log log) {
0430:                this .log = log;
0431:            }
0432:
0433:            /** @return the expression factory used to evaluate tag attributes */
0434:            public ExpressionFactory getExpressionFactory() {
0435:                if (expressionFactory == null) {
0436:                    expressionFactory = createExpressionFactory();
0437:                }
0438:                return expressionFactory;
0439:            }
0440:
0441:            /** Sets the expression factory used to evaluate tag attributes */
0442:            public void setExpressionFactory(ExpressionFactory expressionFactory) {
0443:                this .expressionFactory = expressionFactory;
0444:            }
0445:
0446:            /**
0447:             * Return the SAXParser we will use to parse the input stream.  If there
0448:             * is a problem creating the parser, return <code>null</code>.
0449:             */
0450:            public SAXParser getParser() {
0451:                // Return the parser we already created (if any)
0452:                if (parser != null) {
0453:                    return (parser);
0454:                }
0455:                // Create and return a new parser
0456:                synchronized (this ) {
0457:                    try {
0458:                        if (factory == null) {
0459:                            factory = SAXParserFactory.newInstance();
0460:                        }
0461:                        factory.setNamespaceAware(true);
0462:                        factory.setValidating(validating);
0463:                        parser = factory.newSAXParser();
0464:                        return (parser);
0465:                    } catch (Exception e) {
0466:                        log.error("XMLParser.getParser: ", e);
0467:                        return (null);
0468:                    }
0469:                }
0470:            }
0471:
0472:            /**
0473:             * By setting the reader in the constructor, you can bypass JAXP and
0474:             * be able to use digester in Weblogic 6.0.
0475:             *
0476:             * @deprecated Use getXMLReader() instead, which can throw a
0477:             *  SAXException if the reader cannot be instantiated
0478:             */
0479:            public XMLReader getReader() {
0480:                try {
0481:                    return (getXMLReader());
0482:                } catch (SAXException e) {
0483:                    log.error("Cannot get XMLReader", e);
0484:                    return (null);
0485:                }
0486:            }
0487:
0488:            /**
0489:             * Return the XMLReader to be used for parsing the input document.
0490:             *
0491:             * @exception SAXException if no XMLReader can be instantiated
0492:             */
0493:            public synchronized XMLReader getXMLReader() throws SAXException {
0494:                if (reader == null) {
0495:                    reader = getParser().getXMLReader();
0496:                    if (this .defaultNamespaceURI != null) {
0497:                        reader = new DefaultNamespaceFilter(
0498:                                this .defaultNamespaceURI, reader);
0499:                    }
0500:                }
0501:                //set up the parse
0502:                reader.setContentHandler(this );
0503:                reader.setDTDHandler(this );
0504:                //reader.setEntityResolver(this);
0505:                reader.setErrorHandler(this );
0506:
0507:                return reader;
0508:            }
0509:
0510:            /**
0511:             * Return the validating parser flag.
0512:             */
0513:            public boolean getValidating() {
0514:                return (this .validating);
0515:            }
0516:
0517:            /**
0518:             * Set the validating parser flag.  This must be called before
0519:             * <code>parse()</code> is called the first time.
0520:             *
0521:             * @param validating The new validating parser flag.
0522:             */
0523:            public void setValidating(boolean validating) {
0524:                this .validating = validating;
0525:            }
0526:
0527:            /**
0528:             * Returns the script that has just been created if this class is used
0529:             * as a SAX ContentHandler and passed into some XML processor or parser.
0530:             *
0531:             * @return the ScriptBlock created if SAX events are piped into this class,
0532:             * which must include a startDocument() and endDocument()
0533:             */
0534:            public ScriptBlock getScript() {
0535:                return script;
0536:            }
0537:
0538:            // ContentHandler interface
0539:            //-------------------------------------------------------------------------
0540:            /**
0541:             * Process notification of the beginning of the document being reached.
0542:             *
0543:             * @exception SAXException if a parsing error is to be reported
0544:             */
0545:            public void startDocument() throws SAXException {
0546:                script = new ScriptBlock();
0547:                textBuffer = new StringBuffer();
0548:                tagScript = null;
0549:                scriptStack.clear();
0550:                tagScriptStack.clear();
0551:            }
0552:
0553:            /**
0554:             * Process notification of the end of the document being reached.
0555:             *
0556:             * @exception SAXException if a parsing error is to be reported
0557:             */
0558:            public void endDocument() throws SAXException {
0559:                textBuffer = null;
0560:            }
0561:
0562:            /**
0563:             * Process notification of the start of an XML element being reached.
0564:             *
0565:             * @param namespaceURI The Namespace URI, or the empty string if the
0566:             *   element has no Namespace URI or if Namespace processing is not
0567:             *   being performed.
0568:             * @param localName The local name (without prefix), or the empty
0569:             *   string if Namespace processing is not being performed.
0570:             * @param qName The qualified name (with prefix), or the empty
0571:             *   string if qualified names are not available.\
0572:             * @param list The attributes attached to the element. If there are
0573:             *   no attributes, it shall be an empty Attributes object.
0574:             * @exception SAXException if a parsing error is to be reported
0575:             */
0576:            public void startElement(String namespaceURI, String localName,
0577:                    String qName, Attributes list) throws SAXException {
0578:
0579:                try {
0580:                    // add check to ensure namespace URI is "" for no namespace
0581:                    if (namespaceURI == null) {
0582:                        namespaceURI = "";
0583:                    }
0584:
0585:                    // if this is a tag then create a script to run it
0586:                    // otherwise pass the text to the current body
0587:                    TagScript newTagScript = createTag(namespaceURI, localName,
0588:                            list);
0589:                    if (newTagScript == null) {
0590:                        newTagScript = createStaticTag(namespaceURI, localName,
0591:                                qName, list);
0592:                    }
0593:                    tagScript = newTagScript;
0594:                    tagScriptStack.add(tagScript);
0595:                    if (tagScript != null) {
0596:                        // set the line number details
0597:                        if (locator != null) {
0598:                            tagScript.setLocator(locator);
0599:                        }
0600:                        // sets the file name element names
0601:                        tagScript.setFileName(fileName);
0602:                        tagScript.setElementName(qName);
0603:                        tagScript.setLocalName(localName);
0604:
0605:                        if (textBuffer.length() > 0) {
0606:                            addTextScript(textBuffer.toString());
0607:                            textBuffer.setLength(0);
0608:                        }
0609:                        script.addScript(tagScript);
0610:                        // start a new body
0611:                        scriptStack.push(script);
0612:                        script = new ScriptBlock();
0613:                        tagScript.setTagBody(script);
0614:                    } else {
0615:                        // XXXX: might wanna handle empty elements later...
0616:                        textBuffer.append("<");
0617:                        textBuffer.append(qName);
0618:                        int size = list.getLength();
0619:                        for (int i = 0; i < size; i++) {
0620:                            textBuffer.append(" ");
0621:                            textBuffer.append(list.getQName(i));
0622:                            textBuffer.append("=");
0623:                            textBuffer.append("\"");
0624:                            textBuffer.append(list.getValue(i));
0625:                            textBuffer.append("\"");
0626:                        }
0627:                        textBuffer.append(">");
0628:                    }
0629:                } catch (SAXException e) {
0630:                    throw e;
0631:                } catch (Exception e) {
0632:                    log.error("Caught exception: " + e, e);
0633:                    throw new SAXException("Runtime Exception: " + e, e);
0634:                }
0635:            }
0636:
0637:            /**
0638:             * Process notification of character data received from the body of
0639:             * an XML element.
0640:             *
0641:             * @param buffer The characters from the XML document
0642:             * @param start Starting offset into the buffer
0643:             * @param length Number of characters from the buffer
0644:             *
0645:             * @exception SAXException if a parsing error is to be reported
0646:             */
0647:            public void characters(char buffer[], int start, int length)
0648:                    throws SAXException {
0649:                textBuffer.append(buffer, start, length);
0650:            }
0651:
0652:            /**
0653:             * Process notification of the end of an XML element being reached.
0654:             *
0655:             * @param namespaceURI The Namespace URI, or the empty string if the
0656:             *   element has no Namespace URI or if Namespace processing is not
0657:             *   being performed.
0658:             * @param localName The local name (without prefix), or the empty
0659:             *   string if Namespace processing is not being performed.
0660:             * @param qName The qualified XML 1.0 name (with prefix), or the
0661:             *   empty string if qualified names are not available.
0662:             * @exception SAXException if a parsing error is to be reported
0663:             */
0664:            public void endElement(String namespaceURI, String localName,
0665:                    String qName) throws SAXException {
0666:                try {
0667:                    tagScript = (TagScript) tagScriptStack
0668:                            .remove(tagScriptStack.size() - 1);
0669:                    if (tagScript != null) {
0670:                        if (textBuffer.length() > 0) {
0671:                            addTextScript(textBuffer.toString());
0672:                            textBuffer.setLength(0);
0673:                        }
0674:                        script = (ScriptBlock) scriptStack.pop();
0675:                    } else {
0676:                        textBuffer.append("</");
0677:                        textBuffer.append(qName);
0678:                        textBuffer.append(">");
0679:                    }
0680:
0681:                    // now lets set the parent tag variable
0682:                    if (tagScriptStack.isEmpty()) {
0683:                        tagScript = null;
0684:                    } else {
0685:                        tagScript = (TagScript) tagScriptStack
0686:                                .get(tagScriptStack.size() - 1);
0687:                    }
0688:                } catch (Exception e) {
0689:                    log.error("Caught exception: " + e, e);
0690:                    throw new SAXException("Runtime Exception: " + e, e);
0691:                }
0692:            }
0693:
0694:            /**
0695:             * Process notification that a namespace prefix is coming in to scope.
0696:             *
0697:             * @param prefix Prefix that is being declared
0698:             * @param namespaceURI Corresponding namespace URI being mapped to
0699:             *
0700:             * @exception SAXException if a parsing error is to be reported
0701:             */
0702:            public void startPrefixMapping(String prefix, String namespaceURI)
0703:                    throws SAXException {
0704:                // Register this prefix mapping
0705:                ArrayStack stack = (ArrayStack) namespaces.get(prefix);
0706:                if (stack == null) {
0707:                    stack = new ArrayStack();
0708:                    namespaces.put(prefix, stack);
0709:                }
0710:                stack.push(namespaceURI);
0711:
0712:                if (elementNamespaces == null) {
0713:                    elementNamespaces = new HashMap();
0714:                }
0715:                elementNamespaces.put(prefix, namespaceURI);
0716:            }
0717:
0718:            /**
0719:             * Process notification that a namespace prefix is going out of scope.
0720:             *
0721:             * @param prefix Prefix that is going out of scope
0722:             *
0723:             * @exception SAXException if a parsing error is to be reported
0724:             */
0725:            public void endPrefixMapping(String prefix) throws SAXException {
0726:                // Deregister this prefix mapping
0727:                ArrayStack stack = (ArrayStack) namespaces.get(prefix);
0728:                if (stack == null) {
0729:                    return;
0730:                }
0731:                try {
0732:                    stack.pop();
0733:                    if (stack.empty()) {
0734:                        namespaces.remove(prefix);
0735:                    }
0736:                } catch (EmptyStackException e) {
0737:                    throw createSAXException("endPrefixMapping popped too many times");
0738:                }
0739:            }
0740:
0741:            /**
0742:             * Process notification of ignorable whitespace received from the body of
0743:             * an XML element.
0744:             *
0745:             * @param buffer The characters from the XML document
0746:             * @param start Starting offset into the buffer
0747:             * @param len Number of characters from the buffer
0748:             *
0749:             * @exception SAXException if a parsing error is to be reported
0750:             */
0751:            public void ignorableWhitespace(char buffer[], int start, int len)
0752:                    throws SAXException {
0753:                ; // No processing required
0754:            }
0755:
0756:            /**
0757:             * Process notification of a processing instruction that was encountered.
0758:             *
0759:             * @param target The processing instruction target
0760:             * @param data The processing instruction data (if any)
0761:             *
0762:             * @exception SAXException if a parsing error is to be reported
0763:             */
0764:            public void processingInstruction(String target, String data)
0765:                    throws SAXException {
0766:                ; // No processing is required
0767:            }
0768:
0769:            /**
0770:             * Set the document locator associated with our parser.
0771:             *
0772:             * @param locator The new locator
0773:             */
0774:            public void setDocumentLocator(Locator locator) {
0775:                this .locator = locator;
0776:            }
0777:
0778:            /**
0779:             * Process notification of a skipped entity.
0780:             *
0781:             * @param name Name of the skipped entity
0782:             *
0783:             * @exception SAXException if a parsing error is to be reported
0784:             */
0785:            public void skippedEntity(String name) throws SAXException {
0786:                ; // No processing required
0787:            }
0788:
0789:            // DTDHandler interface
0790:            //-------------------------------------------------------------------------
0791:
0792:            /**
0793:             * Receive notification of a notation declaration event.
0794:             *
0795:             * @param name The notation name
0796:             * @param publicId The public identifier (if any)
0797:             * @param systemId The system identifier (if any)
0798:             */
0799:            public void notationDecl(String name, String publicId,
0800:                    String systemId) {
0801:            }
0802:
0803:            /**
0804:             * Receive notification of an unparsed entity declaration event.
0805:             *
0806:             * @param name The unparsed entity name
0807:             * @param publicId The public identifier (if any)
0808:             * @param systemId The system identifier (if any)
0809:             * @param notation The name of the associated notation
0810:             */
0811:            public void unparsedEntityDecl(String name, String publicId,
0812:                    String systemId, String notation) {
0813:            }
0814:
0815:            // ErrorHandler interface
0816:            //-------------------------------------------------------------------------
0817:
0818:            /**
0819:             * Forward notification of a parsing error to the application supplied
0820:             * error handler, if any, otherwise throw a SAXException with the error.
0821:             *
0822:             * @param exception The error information
0823:             *
0824:             * @exception SAXException if a parsing exception occurs
0825:             */
0826:            public void error(SAXParseException exception) throws SAXException {
0827:                log.error("Parse Error at line " + exception.getLineNumber()
0828:                        + " column " + exception.getColumnNumber() + ": "
0829:                        + exception.getMessage(), exception);
0830:                if (errorHandler != null) {
0831:                    errorHandler.error(exception);
0832:                } else {
0833:                    throw exception;
0834:                }
0835:            }
0836:
0837:            /**
0838:             * Forward notification of a fatal parsing error to the application
0839:             * supplied error handler, if any, otherwise throw a SAXException with the error.
0840:             *
0841:             * @param exception The fatal error information
0842:             *
0843:             * @exception SAXException if a parsing exception occurs
0844:             */
0845:            public void fatalError(SAXParseException exception)
0846:                    throws SAXException {
0847:                log.error("Parse Fatal Error at line "
0848:                        + exception.getLineNumber() + " column "
0849:                        + exception.getColumnNumber() + ": "
0850:                        + exception.getMessage(), exception);
0851:                if (errorHandler != null) {
0852:                    errorHandler.fatalError(exception);
0853:                } else {
0854:                    throw exception;
0855:                }
0856:            }
0857:
0858:            /**
0859:             * Forward notification of a parse warning to the application supplied
0860:             * error handler (if any).  Unlike XMLParser.error(SAXParseException) and
0861:             * XMLParser.fatalError(SAXParseException), this implementation will
0862:             * NOT throw a SAXException by default if no error handler is supplied.
0863:             *
0864:             * @param exception The warning information
0865:             *
0866:             * @exception SAXException if a parsing exception occurs
0867:             */
0868:            public void warning(SAXParseException exception)
0869:                    throws SAXException {
0870:                log.error("Parse Warning at line " + exception.getLineNumber()
0871:                        + " column " + exception.getColumnNumber() + ": "
0872:                        + exception.getMessage(), exception);
0873:                if (errorHandler != null) {
0874:                    errorHandler.warning(exception);
0875:                }
0876:            }
0877:
0878:            // Implementation methods
0879:            //-------------------------------------------------------------------------
0880:            /**
0881:             * If this object has not been configured then register the default
0882:             * namespaces
0883:             */
0884:            private void ensureConfigured() {
0885:                if (!configured) {
0886:                    configure();
0887:                    configured = true;
0888:                }
0889:            }
0890:
0891:            /**
0892:             * This method is called only once before parsing occurs
0893:             * which allows tag libraries to be registered and so forth
0894:             */
0895:            protected void configure() {
0896:                // load the properties file of libraries available
0897:                Properties properties = getJellyProperties();
0898:                for (Iterator iter = properties.entrySet().iterator(); iter
0899:                        .hasNext();) {
0900:                    Map.Entry entry = (Map.Entry) iter.next();
0901:                    String uri = (String) entry.getKey();
0902:                    String className = (String) entry.getValue();
0903:                    String libraryURI = "jelly:" + uri;
0904:
0905:                    // don't overload any Mock Tags already
0906:                    if (!context.isTagLibraryRegistered(libraryURI)) {
0907:                        context.registerTagLibrary(libraryURI, className);
0908:                    }
0909:                }
0910:            }
0911:
0912:            /**
0913:             * A helper method which loads the static Jelly properties once on startup
0914:             */
0915:            protected synchronized Properties getJellyProperties() {
0916:                if (jellyProperties == null) {
0917:                    jellyProperties = new Properties();
0918:
0919:                    InputStream in = null;
0920:                    URL url = getClassLoader().getResource(
0921:                            "org/apache/commons/jelly/jelly.properties");
0922:                    if (url != null) {
0923:                        log.debug("Loading Jelly default tag libraries from: "
0924:                                + url);
0925:                        try {
0926:                            in = url.openStream();
0927:                            jellyProperties.load(in);
0928:                        } catch (IOException e) {
0929:                            log.error("Could not load jelly properties from: "
0930:                                    + url + ". Reason: " + e, e);
0931:                        } finally {
0932:                            try {
0933:                                in.close();
0934:                            } catch (Exception e) {
0935:                                if (log.isDebugEnabled())
0936:                                    log.debug("error closing jelly.properties",
0937:                                            e);
0938:                            }
0939:                        }
0940:                    }
0941:                }
0942:                return jellyProperties;
0943:            }
0944:
0945:            /**
0946:             * Factory method to create new Tag script for the given namespaceURI and name or
0947:             * return null if this is not a custom Tag.
0948:             */
0949:            protected TagScript createTag(String namespaceURI,
0950:                    String localName, Attributes list) throws SAXException {
0951:                try {
0952:                    // use the URI to load a taglib
0953:                    TagLibrary taglib = context.getTagLibrary(namespaceURI);
0954:                    if (taglib == null) {
0955:                        if (namespaceURI != null
0956:                                && namespaceURI.startsWith("jelly:")) {
0957:                            String uri = namespaceURI.substring(6);
0958:                            // try to find the class on the claspath
0959:                            try {
0960:                                Class taglibClass = getClassLoader().loadClass(
0961:                                        uri);
0962:                                taglib = (TagLibrary) taglibClass.newInstance();
0963:                                context
0964:                                        .registerTagLibrary(namespaceURI,
0965:                                                taglib);
0966:                            } catch (ClassNotFoundException e) {
0967:                                throw createSAXException(
0968:                                        "Could not load class: "
0969:                                                + uri
0970:                                                + " so taglib instantiation failed",
0971:                                        e);
0972:                            } catch (IllegalAccessException e) {
0973:                                throw createSAXException(
0974:                                        "Constructor for class is not accessible: "
0975:                                                + uri
0976:                                                + " so taglib instantiation failed",
0977:                                        e);
0978:                            } catch (InstantiationException e) {
0979:                                throw createSAXException(
0980:                                        "Class could not be instantiated: "
0981:                                                + uri
0982:                                                + " so taglib instantiation failed",
0983:                                        e);
0984:                            } catch (ClassCastException e) {
0985:                                throw createSAXException(
0986:                                        "Class is not a TagLibrary: "
0987:                                                + uri
0988:                                                + " so taglib instantiation failed",
0989:                                        e);
0990:                            }
0991:                        }
0992:                    }
0993:                    if (taglib != null) {
0994:                        TagScript script = taglib.createTagScript(localName,
0995:                                list);
0996:                        if (script != null) {
0997:                            configureTagScript(script);
0998:
0999:                            // clone the attributes to keep them around after this parse
1000:                            script.setSaxAttributes(new AttributesImpl(list));
1001:
1002:                            // now iterate through through the expressions
1003:                            int size = list.getLength();
1004:                            for (int i = 0; i < size; i++) {
1005:                                String attributeName = list.getLocalName(i);
1006:                                String attributeValue = list.getValue(i);
1007:                                Expression expression = taglib
1008:                                        .createExpression(
1009:                                                getExpressionFactory(), script,
1010:                                                attributeName, attributeValue);
1011:                                if (expression == null) {
1012:                                    expression = createConstantExpression(
1013:                                            localName, attributeName,
1014:                                            attributeValue);
1015:                                }
1016:                                script.addAttribute(attributeName, expression);
1017:                            }
1018:                        }
1019:                        return script;
1020:                    }
1021:                    return null;
1022:                } catch (Exception e) {
1023:                    log.warn("Could not create taglib or URI: " + namespaceURI
1024:                            + " tag name: " + localName, e);
1025:                    throw createSAXException(e);
1026:                }
1027:            }
1028:
1029:            /**
1030:             * Factory method to create a static Tag that represents some static content.
1031:             */
1032:            protected TagScript createStaticTag(final String namespaceURI,
1033:                    final String localName, final String qName, Attributes list)
1034:                    throws SAXException {
1035:                try {
1036:                    StaticTag tag = new StaticTag(namespaceURI, localName,
1037:                            qName);
1038:                    StaticTagScript script = new StaticTagScript(
1039:                            new TagFactory() {
1040:                                public Tag createTag(String name,
1041:                                        Attributes attributes) {
1042:                                    return new StaticTag(namespaceURI,
1043:                                            localName, qName);
1044:                                }
1045:                            });
1046:                    configureTagScript(script);
1047:
1048:                    // now iterate through through the expressions
1049:                    int size = list.getLength();
1050:                    for (int i = 0; i < size; i++) {
1051:                        String attributeValue = list.getValue(i);
1052:                        Expression expression = CompositeExpression.parse(
1053:                                attributeValue, getExpressionFactory());
1054:                        String attrQName = list.getQName(i);
1055:                        script.addAttribute(attrQName, expression);
1056:                    }
1057:                    return script;
1058:                } catch (Exception e) {
1059:                    log.warn("Could not create static tag for URI: "
1060:                            + namespaceURI + " tag name: " + localName, e);
1061:                    throw createSAXException(e);
1062:                }
1063:            }
1064:
1065:            /**
1066:             * Configure a newly created TagScript instance before any Expressions are created
1067:             *
1068:             * @param aTagScript
1069:             */
1070:            protected void configureTagScript(TagScript aTagScript) {
1071:                // set parent relationship...
1072:                aTagScript.setParent(this .tagScript);
1073:
1074:                // set the namespace Map
1075:                if (elementNamespaces != null) {
1076:                    aTagScript.setTagNamespacesMap(elementNamespaces);
1077:                    elementNamespaces = null;
1078:                }
1079:            }
1080:
1081:            /**
1082:             * Adds the text to the current script block parsing any embedded
1083:             * expressions inot ExpressionScript objects.
1084:             */
1085:            protected void addTextScript(String text) throws JellyException {
1086:                Expression expression = CompositeExpression.parse(text,
1087:                        getExpressionFactory());
1088:
1089:                addExpressionScript(script, expression);
1090:            }
1091:
1092:            /**
1093:             * Adds the given Expression object to the current Script.
1094:             */
1095:            protected void addExpressionScript(ScriptBlock script,
1096:                    Expression expression) {
1097:                if (expression instanceof  ConstantExpression) {
1098:                    ConstantExpression constantExpression = (ConstantExpression) expression;
1099:                    Object value = constantExpression.getValue();
1100:                    if (value != null) {
1101:                        script.addScript(new TextScript(value.toString()));
1102:                    }
1103:                } else if (expression instanceof  CompositeExpression) {
1104:                    CompositeTextScriptBlock newBlock = new CompositeTextScriptBlock();
1105:                    script.addScript(newBlock);
1106:
1107:                    CompositeExpression compositeExpression = (CompositeExpression) expression;
1108:                    Iterator iter = compositeExpression.getExpressions()
1109:                            .iterator();
1110:                    while (iter.hasNext()) {
1111:                        addExpressionScript(newBlock, (Expression) iter.next());
1112:                    }
1113:                } else {
1114:                    script.addScript(new ExpressionScript(expression));
1115:                }
1116:            }
1117:
1118:            protected Expression createConstantExpression(String tagName,
1119:                    String attributeName, String attributeValue) {
1120:                return new ConstantExpression(attributeValue);
1121:            }
1122:
1123:            protected ExpressionFactory createExpressionFactory() {
1124:                return new JexlExpressionFactory();
1125:            }
1126:
1127:            /**
1128:             * @return the current context URI as a String or null if there is no
1129:             * current context defined on the JellyContext
1130:             */
1131:            protected String getCurrentURI() {
1132:                URL url = this .getContext().getCurrentURL();
1133:                return (url != null) ? url.toString() : null;
1134:            }
1135:
1136:            /**
1137:             * Create a SAX exception which also understands about the location in
1138:             * the file where the exception occurs
1139:             *
1140:             * @return the new exception
1141:             */
1142:            protected SAXException createSAXException(String message,
1143:                    Exception e) {
1144:                log.warn("Underlying exception: " + e);
1145:                e.printStackTrace();
1146:                if (locator != null) {
1147:                    String error = "Error at (" + locator.getLineNumber()
1148:                            + ", " + locator.getColumnNumber() + "): "
1149:                            + message;
1150:                    if (e != null) {
1151:                        return new SAXParseException(error, locator, e);
1152:                    } else {
1153:                        return new SAXParseException(error, locator);
1154:                    }
1155:                }
1156:                log.error("No Locator!");
1157:                if (e != null) {
1158:                    return new SAXException(message, e);
1159:                } else {
1160:                    return new SAXException(message);
1161:                }
1162:            }
1163:
1164:            /**
1165:             * Create a SAX exception which also understands about the location in
1166:             * the digester file where the exception occurs
1167:             *
1168:             * @return the new exception
1169:             */
1170:            protected SAXException createSAXException(Exception e) {
1171:                return createSAXException(e.getMessage(), e);
1172:            }
1173:
1174:            /**
1175:             * Create a SAX exception which also understands about the location in
1176:             * the digester file where the exception occurs
1177:             *
1178:             * @return the new exception
1179:             */
1180:            protected SAXException createSAXException(String message) {
1181:                return createSAXException(message, null);
1182:            }
1183:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.