Source Code Cross Referenced for JspDocumentParser.java in  » Sevlet-Container » apache-tomcat-6.0.14 » org » apache » jasper » compiler » 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 » Sevlet Container » apache tomcat 6.0.14 » org.apache.jasper.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         * 
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         * 
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:        package org.apache.jasper.compiler;
0018:
0019:        import java.io.CharArrayWriter;
0020:        import java.io.FileNotFoundException;
0021:        import java.io.IOException;
0022:        import java.io.InputStream;
0023:
0024:        import java.util.Iterator;
0025:        import java.util.List;
0026:        import java.util.jar.JarFile;
0027:
0028:        import javax.servlet.jsp.tagext.TagFileInfo;
0029:        import javax.servlet.jsp.tagext.TagInfo;
0030:        import javax.servlet.jsp.tagext.TagLibraryInfo;
0031:        import javax.xml.parsers.SAXParser;
0032:        import javax.xml.parsers.SAXParserFactory;
0033:
0034:        import org.apache.jasper.JasperException;
0035:        import org.apache.jasper.JspCompilationContext;
0036:        import org.xml.sax.Attributes;
0037:        import org.xml.sax.InputSource;
0038:        import org.xml.sax.Locator;
0039:        import org.xml.sax.SAXException;
0040:        import org.xml.sax.SAXParseException;
0041:        import org.xml.sax.XMLReader;
0042:        import org.xml.sax.ext.LexicalHandler;
0043:        import org.xml.sax.helpers.AttributesImpl;
0044:        import org.xml.sax.helpers.DefaultHandler;
0045:
0046:        /**
0047:         * Class implementing a parser for a JSP document, that is, a JSP page in XML
0048:         * syntax.
0049:         *
0050:         * @author Jan Luehe
0051:         * @author Kin-man Chung
0052:         */
0053:
0054:        class JspDocumentParser extends DefaultHandler implements 
0055:                LexicalHandler, TagConstants {
0056:
0057:            private static final String JSP_VERSION = "version";
0058:            private static final String LEXICAL_HANDLER_PROPERTY = "http://xml.org/sax/properties/lexical-handler";
0059:            private static final String JSP_URI = "http://java.sun.com/JSP/Page";
0060:
0061:            private static final EnableDTDValidationException ENABLE_DTD_VALIDATION_EXCEPTION = new EnableDTDValidationException(
0062:                    "jsp.error.enable_dtd_validation", null);
0063:
0064:            private ParserController parserController;
0065:            private JspCompilationContext ctxt;
0066:            private PageInfo pageInfo;
0067:            private String path;
0068:            private StringBuffer charBuffer;
0069:
0070:            // Node representing the XML element currently being parsed
0071:            private Node current;
0072:
0073:            /*
0074:             * Outermost (in the nesting hierarchy) node whose body is declared to be
0075:             * scriptless. If a node's body is declared to be scriptless, all its
0076:             * nested nodes must be scriptless, too.
0077:             */
0078:            private Node scriptlessBodyNode;
0079:
0080:            private Locator locator;
0081:
0082:            //Mark representing the start of the current element.  Note
0083:            //that locator.getLineNumber() and locator.getColumnNumber()
0084:            //return the line and column numbers for the character
0085:            //immediately _following_ the current element.  The underlying
0086:            //XMl parser eats white space that is not part of character
0087:            //data, so for Nodes that are not created from character data,
0088:            //this is the best we can do.  But when we parse character data,
0089:            //we get an accurate starting location by starting with startMark
0090:            //as set by the previous element, and updating it as we advance
0091:            //through the characters.
0092:            private Mark startMark;
0093:
0094:            // Flag indicating whether we are inside DTD declarations
0095:            private boolean inDTD;
0096:
0097:            private boolean isValidating;
0098:
0099:            private ErrorDispatcher err;
0100:            private boolean isTagFile;
0101:            private boolean directivesOnly;
0102:            private boolean isTop;
0103:
0104:            // Nesting level of Tag dependent bodies
0105:            private int tagDependentNesting = 0;
0106:            // Flag set to delay incrmenting tagDependentNesting until jsp:body
0107:            // is first encountered
0108:            private boolean tagDependentPending = false;
0109:
0110:            /*
0111:             * Constructor
0112:             */
0113:            public JspDocumentParser(ParserController pc, String path,
0114:                    boolean isTagFile, boolean directivesOnly) {
0115:                this .parserController = pc;
0116:                this .ctxt = pc.getJspCompilationContext();
0117:                this .pageInfo = pc.getCompiler().getPageInfo();
0118:                this .err = pc.getCompiler().getErrorDispatcher();
0119:                this .path = path;
0120:                this .isTagFile = isTagFile;
0121:                this .directivesOnly = directivesOnly;
0122:                this .isTop = true;
0123:            }
0124:
0125:            /*
0126:             * Parses a JSP document by responding to SAX events.
0127:             *
0128:             * @throws JasperException
0129:             */
0130:            public static Node.Nodes parse(ParserController pc, String path,
0131:                    JarFile jarFile, Node parent, boolean isTagFile,
0132:                    boolean directivesOnly, String pageEnc,
0133:                    String jspConfigPageEnc,
0134:                    boolean isEncodingSpecifiedInProlog, boolean isBomPresent)
0135:                    throws JasperException {
0136:
0137:                JspDocumentParser jspDocParser = new JspDocumentParser(pc,
0138:                        path, isTagFile, directivesOnly);
0139:                Node.Nodes pageNodes = null;
0140:
0141:                try {
0142:
0143:                    // Create dummy root and initialize it with given page encodings
0144:                    Node.Root dummyRoot = new Node.Root(null, parent, true);
0145:                    dummyRoot.setPageEncoding(pageEnc);
0146:                    dummyRoot.setJspConfigPageEncoding(jspConfigPageEnc);
0147:                    dummyRoot
0148:                            .setIsEncodingSpecifiedInProlog(isEncodingSpecifiedInProlog);
0149:                    dummyRoot.setIsBomPresent(isBomPresent);
0150:                    jspDocParser.current = dummyRoot;
0151:                    if (parent == null) {
0152:                        jspDocParser.addInclude(dummyRoot,
0153:                                jspDocParser.pageInfo.getIncludePrelude());
0154:                    } else {
0155:                        jspDocParser.isTop = false;
0156:                    }
0157:
0158:                    // Parse the input
0159:                    SAXParser saxParser = getSAXParser(false, jspDocParser);
0160:                    InputStream inStream = null;
0161:                    try {
0162:                        inStream = JspUtil.getInputStream(path, jarFile,
0163:                                jspDocParser.ctxt, jspDocParser.err);
0164:                        saxParser
0165:                                .parse(new InputSource(inStream), jspDocParser);
0166:                    } catch (EnableDTDValidationException e) {
0167:                        saxParser = getSAXParser(true, jspDocParser);
0168:                        jspDocParser.isValidating = true;
0169:                        if (inStream != null) {
0170:                            try {
0171:                                inStream.close();
0172:                            } catch (Exception any) {
0173:                            }
0174:                        }
0175:                        inStream = JspUtil.getInputStream(path, jarFile,
0176:                                jspDocParser.ctxt, jspDocParser.err);
0177:                        saxParser
0178:                                .parse(new InputSource(inStream), jspDocParser);
0179:                    } finally {
0180:                        if (inStream != null) {
0181:                            try {
0182:                                inStream.close();
0183:                            } catch (Exception any) {
0184:                            }
0185:                        }
0186:                    }
0187:
0188:                    if (parent == null) {
0189:                        jspDocParser.addInclude(dummyRoot,
0190:                                jspDocParser.pageInfo.getIncludeCoda());
0191:                    }
0192:
0193:                    // Create Node.Nodes from dummy root
0194:                    pageNodes = new Node.Nodes(dummyRoot);
0195:
0196:                } catch (IOException ioe) {
0197:                    jspDocParser.err.jspError("jsp.error.data.file.read", path,
0198:                            ioe);
0199:                } catch (SAXParseException e) {
0200:                    jspDocParser.err.jspError(new Mark(jspDocParser.ctxt, path,
0201:                            e.getLineNumber(), e.getColumnNumber()), e
0202:                            .getMessage());
0203:                } catch (Exception e) {
0204:                    jspDocParser.err.jspError(e);
0205:                }
0206:
0207:                return pageNodes;
0208:            }
0209:
0210:            /*
0211:             * Processes the given list of included files.
0212:             *
0213:             * This is used to implement the include-prelude and include-coda
0214:             * subelements of the jsp-config element in web.xml
0215:             */
0216:            private void addInclude(Node parent, List files)
0217:                    throws SAXException {
0218:                if (files != null) {
0219:                    Iterator iter = files.iterator();
0220:                    while (iter.hasNext()) {
0221:                        String file = (String) iter.next();
0222:                        AttributesImpl attrs = new AttributesImpl();
0223:                        attrs.addAttribute("", "file", "file", "CDATA", file);
0224:
0225:                        // Create a dummy Include directive node
0226:                        Node includeDir = new Node.IncludeDirective(attrs,
0227:                                null, // XXX
0228:                                parent);
0229:                        processIncludeDirective(file, includeDir);
0230:                    }
0231:                }
0232:            }
0233:
0234:            /*
0235:             * Receives notification of the start of an element.
0236:             *
0237:             * This method assigns the given tag attributes to one of 3 buckets:
0238:             * 
0239:             * - "xmlns" attributes that represent (standard or custom) tag libraries.
0240:             * - "xmlns" attributes that do not represent tag libraries.
0241:             * - all remaining attributes.
0242:             *
0243:             * For each "xmlns" attribute that represents a custom tag library, the
0244:             * corresponding TagLibraryInfo object is added to the set of custom
0245:             * tag libraries.
0246:             */
0247:            public void startElement(String uri, String localName,
0248:                    String qName, Attributes attrs) throws SAXException {
0249:
0250:                AttributesImpl taglibAttrs = null;
0251:                AttributesImpl nonTaglibAttrs = null;
0252:                AttributesImpl nonTaglibXmlnsAttrs = null;
0253:
0254:                processChars();
0255:
0256:                checkPrefixes(uri, qName, attrs);
0257:
0258:                if (directivesOnly
0259:                        && !(JSP_URI.equals(uri) && localName
0260:                                .startsWith(DIRECTIVE_ACTION))) {
0261:                    return;
0262:                }
0263:
0264:                // jsp:text must not have any subelements
0265:                if (JSP_URI.equals(uri)
0266:                        && TEXT_ACTION.equals(current.getLocalName())) {
0267:                    throw new SAXParseException(Localizer
0268:                            .getMessage("jsp.error.text.has_subelement"),
0269:                            locator);
0270:                }
0271:
0272:                startMark = new Mark(ctxt, path, locator.getLineNumber(),
0273:                        locator.getColumnNumber());
0274:
0275:                if (attrs != null) {
0276:                    /*
0277:                     * Notice that due to a bug in the underlying SAX parser, the
0278:                     * attributes must be enumerated in descending order. 
0279:                     */
0280:                    boolean isTaglib = false;
0281:                    for (int i = attrs.getLength() - 1; i >= 0; i--) {
0282:                        isTaglib = false;
0283:                        String attrQName = attrs.getQName(i);
0284:                        if (!attrQName.startsWith("xmlns")) {
0285:                            if (nonTaglibAttrs == null) {
0286:                                nonTaglibAttrs = new AttributesImpl();
0287:                            }
0288:                            nonTaglibAttrs.addAttribute(attrs.getURI(i), attrs
0289:                                    .getLocalName(i), attrs.getQName(i), attrs
0290:                                    .getType(i), attrs.getValue(i));
0291:                        } else {
0292:                            if (attrQName.startsWith("xmlns:jsp")) {
0293:                                isTaglib = true;
0294:                            } else {
0295:                                String attrUri = attrs.getValue(i);
0296:                                // TaglibInfo for this uri already established in
0297:                                // startPrefixMapping
0298:                                isTaglib = pageInfo.hasTaglib(attrUri);
0299:                            }
0300:                            if (isTaglib) {
0301:                                if (taglibAttrs == null) {
0302:                                    taglibAttrs = new AttributesImpl();
0303:                                }
0304:                                taglibAttrs.addAttribute(attrs.getURI(i), attrs
0305:                                        .getLocalName(i), attrs.getQName(i),
0306:                                        attrs.getType(i), attrs.getValue(i));
0307:                            } else {
0308:                                if (nonTaglibXmlnsAttrs == null) {
0309:                                    nonTaglibXmlnsAttrs = new AttributesImpl();
0310:                                }
0311:                                nonTaglibXmlnsAttrs.addAttribute(attrs
0312:                                        .getURI(i), attrs.getLocalName(i),
0313:                                        attrs.getQName(i), attrs.getType(i),
0314:                                        attrs.getValue(i));
0315:                            }
0316:                        }
0317:                    }
0318:                }
0319:
0320:                Node node = null;
0321:
0322:                if (tagDependentPending && JSP_URI.equals(uri)
0323:                        && localName.equals(BODY_ACTION)) {
0324:                    tagDependentPending = false;
0325:                    tagDependentNesting++;
0326:                    current = parseStandardAction(qName, localName,
0327:                            nonTaglibAttrs, nonTaglibXmlnsAttrs, taglibAttrs,
0328:                            startMark, current);
0329:                    return;
0330:                }
0331:
0332:                if (tagDependentPending && JSP_URI.equals(uri)
0333:                        && localName.equals(ATTRIBUTE_ACTION)) {
0334:                    current = parseStandardAction(qName, localName,
0335:                            nonTaglibAttrs, nonTaglibXmlnsAttrs, taglibAttrs,
0336:                            startMark, current);
0337:                    return;
0338:                }
0339:
0340:                if (tagDependentPending) {
0341:                    tagDependentPending = false;
0342:                    tagDependentNesting++;
0343:                }
0344:
0345:                if (tagDependentNesting > 0) {
0346:                    node = new Node.UninterpretedTag(qName, localName,
0347:                            nonTaglibAttrs, nonTaglibXmlnsAttrs, taglibAttrs,
0348:                            startMark, current);
0349:                } else if (JSP_URI.equals(uri)) {
0350:                    node = parseStandardAction(qName, localName,
0351:                            nonTaglibAttrs, nonTaglibXmlnsAttrs, taglibAttrs,
0352:                            startMark, current);
0353:                } else {
0354:                    node = parseCustomAction(qName, localName, uri,
0355:                            nonTaglibAttrs, nonTaglibXmlnsAttrs, taglibAttrs,
0356:                            startMark, current);
0357:                    if (node == null) {
0358:                        node = new Node.UninterpretedTag(qName, localName,
0359:                                nonTaglibAttrs, nonTaglibXmlnsAttrs,
0360:                                taglibAttrs, startMark, current);
0361:                    } else {
0362:                        // custom action
0363:                        String bodyType = getBodyType((Node.CustomTag) node);
0364:
0365:                        if (scriptlessBodyNode == null
0366:                                && bodyType
0367:                                        .equalsIgnoreCase(TagInfo.BODY_CONTENT_SCRIPTLESS)) {
0368:                            scriptlessBodyNode = node;
0369:                        } else if (TagInfo.BODY_CONTENT_TAG_DEPENDENT
0370:                                .equalsIgnoreCase(bodyType)) {
0371:                            tagDependentPending = true;
0372:                        }
0373:                    }
0374:                }
0375:
0376:                current = node;
0377:            }
0378:
0379:            /*
0380:             * Receives notification of character data inside an element.
0381:             *
0382:             * The SAX does not call this method with all of the template text, but may
0383:             * invoke this method with chunks of it.  This is a problem when we try
0384:             * to determine if the text contains only whitespaces, or when we are
0385:             * looking for an EL expression string.  Therefore it is necessary to
0386:             * buffer and concatenate the chunks and process the concatenated text 
0387:             * later (at beginTag and endTag)
0388:             *
0389:             * @param buf The characters
0390:             * @param offset The start position in the character array
0391:             * @param len The number of characters to use from the character array
0392:             *
0393:             * @throws SAXException
0394:             */
0395:            public void characters(char[] buf, int offset, int len) {
0396:
0397:                if (charBuffer == null) {
0398:                    charBuffer = new StringBuffer();
0399:                }
0400:                charBuffer.append(buf, offset, len);
0401:            }
0402:
0403:            private void processChars() throws SAXException {
0404:
0405:                if (charBuffer == null || directivesOnly) {
0406:                    return;
0407:                }
0408:
0409:                /*
0410:                 * JSP.6.1.1: All textual nodes that have only white space are to be
0411:                 * dropped from the document, except for nodes in a jsp:text element,
0412:                 * and any leading and trailing white-space-only textual nodes in a
0413:                 * jsp:attribute whose 'trim' attribute is set to FALSE, which are to
0414:                 * be kept verbatim.
0415:                 * JSP.6.2.3 defines white space characters.
0416:                 */
0417:                boolean isAllSpace = true;
0418:                if (!(current instanceof  Node.JspText)
0419:                        && !(current instanceof  Node.NamedAttribute)) {
0420:                    for (int i = 0; i < charBuffer.length(); i++) {
0421:                        if (!(charBuffer.charAt(i) == ' '
0422:                                || charBuffer.charAt(i) == '\n'
0423:                                || charBuffer.charAt(i) == '\r' || charBuffer
0424:                                .charAt(i) == '\t')) {
0425:                            isAllSpace = false;
0426:                            break;
0427:                        }
0428:                    }
0429:                }
0430:
0431:                if (!isAllSpace && tagDependentPending) {
0432:                    tagDependentPending = false;
0433:                    tagDependentNesting++;
0434:                }
0435:
0436:                if (tagDependentNesting > 0) {
0437:                    if (charBuffer.length() > 0) {
0438:                        new Node.TemplateText(charBuffer.toString(), startMark,
0439:                                current);
0440:                    }
0441:                    startMark = new Mark(ctxt, path, locator.getLineNumber(),
0442:                            locator.getColumnNumber());
0443:                    charBuffer = null;
0444:                    return;
0445:                }
0446:
0447:                if ((current instanceof  Node.JspText)
0448:                        || (current instanceof  Node.NamedAttribute)
0449:                        || !isAllSpace) {
0450:
0451:                    int line = startMark.getLineNumber();
0452:                    int column = startMark.getColumnNumber();
0453:
0454:                    CharArrayWriter ttext = new CharArrayWriter();
0455:                    int lastCh = 0, elType = 0;
0456:                    for (int i = 0; i < charBuffer.length(); i++) {
0457:
0458:                        int ch = charBuffer.charAt(i);
0459:                        if (ch == '\n') {
0460:                            column = 1;
0461:                            line++;
0462:                        } else {
0463:                            column++;
0464:                        }
0465:                        if ((lastCh == '$' || lastCh == '#') && ch == '{') {
0466:                            elType = lastCh;
0467:                            if (ttext.size() > 0) {
0468:                                new Node.TemplateText(ttext.toString(),
0469:                                        startMark, current);
0470:                                ttext = new CharArrayWriter();
0471:                                //We subtract two from the column number to
0472:                                //account for the '[$,#]{' that we've already parsed
0473:                                startMark = new Mark(ctxt, path, line,
0474:                                        column - 2);
0475:                            }
0476:                            // following "${" || "#{" to first unquoted "}"
0477:                            i++;
0478:                            boolean singleQ = false;
0479:                            boolean doubleQ = false;
0480:                            lastCh = 0;
0481:                            for (;; i++) {
0482:                                if (i >= charBuffer.length()) {
0483:                                    throw new SAXParseException(Localizer
0484:                                            .getMessage(
0485:                                                    "jsp.error.unterminated",
0486:                                                    (char) elType + "{"),
0487:                                            locator);
0488:
0489:                                }
0490:                                ch = charBuffer.charAt(i);
0491:                                if (ch == '\n') {
0492:                                    column = 1;
0493:                                    line++;
0494:                                } else {
0495:                                    column++;
0496:                                }
0497:                                if (lastCh == '\\' && (singleQ || doubleQ)) {
0498:                                    ttext.write(ch);
0499:                                    lastCh = 0;
0500:                                    continue;
0501:                                }
0502:                                if (ch == '}') {
0503:                                    new Node.ELExpression((char) elType, ttext
0504:                                            .toString(), startMark, current);
0505:                                    ttext = new CharArrayWriter();
0506:                                    startMark = new Mark(ctxt, path, line,
0507:                                            column);
0508:                                    break;
0509:                                }
0510:                                if (ch == '"')
0511:                                    doubleQ = !doubleQ;
0512:                                else if (ch == '\'')
0513:                                    singleQ = !singleQ;
0514:
0515:                                ttext.write(ch);
0516:                                lastCh = ch;
0517:                            }
0518:                        } else if (lastCh == '\\' && (ch == '$' || ch == '#')) {
0519:                            ttext.write(ch);
0520:                            ch = 0; // Not start of EL anymore
0521:                        } else {
0522:                            if (lastCh == '$' || lastCh == '#'
0523:                                    || lastCh == '\\') {
0524:                                ttext.write(lastCh);
0525:                            }
0526:                            if (ch != '$' && ch != '#' && ch != '\\') {
0527:                                ttext.write(ch);
0528:                            }
0529:                        }
0530:                        lastCh = ch;
0531:                    }
0532:                    if (lastCh == '$' || lastCh == '#' || lastCh == '\\') {
0533:                        ttext.write(lastCh);
0534:                    }
0535:                    if (ttext.size() > 0) {
0536:                        new Node.TemplateText(ttext.toString(), startMark,
0537:                                current);
0538:                    }
0539:                }
0540:                startMark = new Mark(ctxt, path, locator.getLineNumber(),
0541:                        locator.getColumnNumber());
0542:
0543:                charBuffer = null;
0544:            }
0545:
0546:            /*
0547:             * Receives notification of the end of an element.
0548:             */
0549:            public void endElement(String uri, String localName, String qName)
0550:                    throws SAXException {
0551:
0552:                processChars();
0553:
0554:                if (directivesOnly
0555:                        && !(JSP_URI.equals(uri) && localName
0556:                                .startsWith(DIRECTIVE_ACTION))) {
0557:                    return;
0558:                }
0559:
0560:                if (current instanceof  Node.NamedAttribute) {
0561:                    boolean isTrim = ((Node.NamedAttribute) current).isTrim();
0562:                    Node.Nodes subElems = ((Node.NamedAttribute) current)
0563:                            .getBody();
0564:                    for (int i = 0; subElems != null && i < subElems.size(); i++) {
0565:                        Node subElem = subElems.getNode(i);
0566:                        if (!(subElem instanceof  Node.TemplateText)) {
0567:                            continue;
0568:                        }
0569:                        // Ignore any whitespace (including spaces, carriage returns,
0570:                        // line feeds, and tabs, that appear at the beginning and at
0571:                        // the end of the body of the <jsp:attribute> action, if the
0572:                        // action's 'trim' attribute is set to TRUE (default).
0573:                        // In addition, any textual nodes in the <jsp:attribute> that
0574:                        // have only white space are dropped from the document, with
0575:                        // the exception of leading and trailing white-space-only
0576:                        // textual nodes in a <jsp:attribute> whose 'trim' attribute
0577:                        // is set to FALSE, which must be kept verbatim.
0578:                        if (i == 0) {
0579:                            if (isTrim) {
0580:                                ((Node.TemplateText) subElem).ltrim();
0581:                            }
0582:                        } else if (i == subElems.size() - 1) {
0583:                            if (isTrim) {
0584:                                ((Node.TemplateText) subElem).rtrim();
0585:                            }
0586:                        } else {
0587:                            if (((Node.TemplateText) subElem).isAllSpace()) {
0588:                                subElems.remove(subElem);
0589:                            }
0590:                        }
0591:                    }
0592:                } else if (current instanceof  Node.ScriptingElement) {
0593:                    checkScriptingBody((Node.ScriptingElement) current);
0594:                }
0595:
0596:                if (isTagDependent(current)) {
0597:                    tagDependentNesting--;
0598:                }
0599:
0600:                if (scriptlessBodyNode != null
0601:                        && current.equals(scriptlessBodyNode)) {
0602:                    scriptlessBodyNode = null;
0603:                }
0604:
0605:                if (current.getParent() != null) {
0606:                    current = current.getParent();
0607:                }
0608:            }
0609:
0610:            /*
0611:             * Receives the document locator.
0612:             *
0613:             * @param locator the document locator
0614:             */
0615:            public void setDocumentLocator(Locator locator) {
0616:                this .locator = locator;
0617:            }
0618:
0619:            /*
0620:             * See org.xml.sax.ext.LexicalHandler.
0621:             */
0622:            public void comment(char[] buf, int offset, int len)
0623:                    throws SAXException {
0624:
0625:                processChars(); // Flush char buffer and remove white spaces
0626:
0627:                // ignore comments in the DTD
0628:                if (!inDTD) {
0629:                    startMark = new Mark(ctxt, path, locator.getLineNumber(),
0630:                            locator.getColumnNumber());
0631:                    new Node.Comment(new String(buf, offset, len), startMark,
0632:                            current);
0633:                }
0634:            }
0635:
0636:            /*
0637:             * See org.xml.sax.ext.LexicalHandler.
0638:             */
0639:            public void startCDATA() throws SAXException {
0640:
0641:                processChars(); // Flush char buffer and remove white spaces
0642:                startMark = new Mark(ctxt, path, locator.getLineNumber(),
0643:                        locator.getColumnNumber());
0644:            }
0645:
0646:            /*
0647:             * See org.xml.sax.ext.LexicalHandler.
0648:             */
0649:            public void endCDATA() throws SAXException {
0650:                processChars(); // Flush char buffer and remove white spaces
0651:            }
0652:
0653:            /*
0654:             * See org.xml.sax.ext.LexicalHandler.
0655:             */
0656:            public void startEntity(String name) throws SAXException {
0657:                // do nothing
0658:            }
0659:
0660:            /*
0661:             * See org.xml.sax.ext.LexicalHandler.
0662:             */
0663:            public void endEntity(String name) throws SAXException {
0664:                // do nothing
0665:            }
0666:
0667:            /*
0668:             * See org.xml.sax.ext.LexicalHandler.
0669:             */
0670:            public void startDTD(String name, String publicId, String systemId)
0671:                    throws SAXException {
0672:                if (!isValidating) {
0673:                    fatalError(ENABLE_DTD_VALIDATION_EXCEPTION);
0674:                }
0675:
0676:                inDTD = true;
0677:            }
0678:
0679:            /*
0680:             * See org.xml.sax.ext.LexicalHandler.
0681:             */
0682:            public void endDTD() throws SAXException {
0683:                inDTD = false;
0684:            }
0685:
0686:            /*
0687:             * Receives notification of a non-recoverable error.
0688:             */
0689:            public void fatalError(SAXParseException e) throws SAXException {
0690:                throw e;
0691:            }
0692:
0693:            /*
0694:             * Receives notification of a recoverable error.
0695:             */
0696:            public void error(SAXParseException e) throws SAXException {
0697:                throw e;
0698:            }
0699:
0700:            /*
0701:             * Receives notification of the start of a Namespace mapping. 
0702:             */
0703:            public void startPrefixMapping(String prefix, String uri)
0704:                    throws SAXException {
0705:                TagLibraryInfo taglibInfo;
0706:
0707:                if (directivesOnly && !(JSP_URI.equals(uri))) {
0708:                    return;
0709:                }
0710:
0711:                try {
0712:                    taglibInfo = getTaglibInfo(prefix, uri);
0713:                } catch (JasperException je) {
0714:                    throw new SAXParseException(
0715:                            Localizer
0716:                                    .getMessage("jsp.error.could.not.add.taglibraries"),
0717:                            locator, je);
0718:                }
0719:
0720:                if (taglibInfo != null) {
0721:                    if (pageInfo.getTaglib(uri) == null) {
0722:                        pageInfo.addTaglib(uri, taglibInfo);
0723:                    }
0724:                    pageInfo.pushPrefixMapping(prefix, uri);
0725:                } else {
0726:                    pageInfo.pushPrefixMapping(prefix, null);
0727:                }
0728:            }
0729:
0730:            /*
0731:             * Receives notification of the end of a Namespace mapping. 
0732:             */
0733:            public void endPrefixMapping(String prefix) throws SAXException {
0734:
0735:                if (directivesOnly) {
0736:                    String uri = pageInfo.getURI(prefix);
0737:                    if (!JSP_URI.equals(uri)) {
0738:                        return;
0739:                    }
0740:                }
0741:
0742:                pageInfo.popPrefixMapping(prefix);
0743:            }
0744:
0745:            //*********************************************************************
0746:            // Private utility methods
0747:
0748:            private Node parseStandardAction(String qName, String localName,
0749:                    Attributes nonTaglibAttrs, Attributes nonTaglibXmlnsAttrs,
0750:                    Attributes taglibAttrs, Mark start, Node parent)
0751:                    throws SAXException {
0752:
0753:                Node node = null;
0754:
0755:                if (localName.equals(ROOT_ACTION)) {
0756:                    if (!(current instanceof  Node.Root)) {
0757:                        throw new SAXParseException(Localizer
0758:                                .getMessage("jsp.error.nested_jsproot"),
0759:                                locator);
0760:                    }
0761:                    node = new Node.JspRoot(qName, nonTaglibAttrs,
0762:                            nonTaglibXmlnsAttrs, taglibAttrs, start, current);
0763:                    if (isTop) {
0764:                        pageInfo.setHasJspRoot(true);
0765:                    }
0766:                } else if (localName.equals(PAGE_DIRECTIVE_ACTION)) {
0767:                    if (isTagFile) {
0768:                        throw new SAXParseException(Localizer.getMessage(
0769:                                "jsp.error.action.istagfile", localName),
0770:                                locator);
0771:                    }
0772:                    node = new Node.PageDirective(qName, nonTaglibAttrs,
0773:                            nonTaglibXmlnsAttrs, taglibAttrs, start, current);
0774:                    String imports = nonTaglibAttrs.getValue("import");
0775:                    // There can only be one 'import' attribute per page directive
0776:                    if (imports != null) {
0777:                        ((Node.PageDirective) node).addImport(imports);
0778:                    }
0779:                } else if (localName.equals(INCLUDE_DIRECTIVE_ACTION)) {
0780:                    node = new Node.IncludeDirective(qName, nonTaglibAttrs,
0781:                            nonTaglibXmlnsAttrs, taglibAttrs, start, current);
0782:                    processIncludeDirective(nonTaglibAttrs.getValue("file"),
0783:                            node);
0784:                } else if (localName.equals(DECLARATION_ACTION)) {
0785:                    if (scriptlessBodyNode != null) {
0786:                        // We're nested inside a node whose body is
0787:                        // declared to be scriptless
0788:                        throw new SAXParseException(Localizer.getMessage(
0789:                                "jsp.error.no.scriptlets", localName), locator);
0790:                    }
0791:                    node = new Node.Declaration(qName, nonTaglibXmlnsAttrs,
0792:                            taglibAttrs, start, current);
0793:                } else if (localName.equals(SCRIPTLET_ACTION)) {
0794:                    if (scriptlessBodyNode != null) {
0795:                        // We're nested inside a node whose body is
0796:                        // declared to be scriptless
0797:                        throw new SAXParseException(Localizer.getMessage(
0798:                                "jsp.error.no.scriptlets", localName), locator);
0799:                    }
0800:                    node = new Node.Scriptlet(qName, nonTaglibXmlnsAttrs,
0801:                            taglibAttrs, start, current);
0802:                } else if (localName.equals(EXPRESSION_ACTION)) {
0803:                    if (scriptlessBodyNode != null) {
0804:                        // We're nested inside a node whose body is
0805:                        // declared to be scriptless
0806:                        throw new SAXParseException(Localizer.getMessage(
0807:                                "jsp.error.no.scriptlets", localName), locator);
0808:                    }
0809:                    node = new Node.Expression(qName, nonTaglibXmlnsAttrs,
0810:                            taglibAttrs, start, current);
0811:                } else if (localName.equals(USE_BEAN_ACTION)) {
0812:                    node = new Node.UseBean(qName, nonTaglibAttrs,
0813:                            nonTaglibXmlnsAttrs, taglibAttrs, start, current);
0814:                } else if (localName.equals(SET_PROPERTY_ACTION)) {
0815:                    node = new Node.SetProperty(qName, nonTaglibAttrs,
0816:                            nonTaglibXmlnsAttrs, taglibAttrs, start, current);
0817:                } else if (localName.equals(GET_PROPERTY_ACTION)) {
0818:                    node = new Node.GetProperty(qName, nonTaglibAttrs,
0819:                            nonTaglibXmlnsAttrs, taglibAttrs, start, current);
0820:                } else if (localName.equals(INCLUDE_ACTION)) {
0821:                    node = new Node.IncludeAction(qName, nonTaglibAttrs,
0822:                            nonTaglibXmlnsAttrs, taglibAttrs, start, current);
0823:                } else if (localName.equals(FORWARD_ACTION)) {
0824:                    node = new Node.ForwardAction(qName, nonTaglibAttrs,
0825:                            nonTaglibXmlnsAttrs, taglibAttrs, start, current);
0826:                } else if (localName.equals(PARAM_ACTION)) {
0827:                    node = new Node.ParamAction(qName, nonTaglibAttrs,
0828:                            nonTaglibXmlnsAttrs, taglibAttrs, start, current);
0829:                } else if (localName.equals(PARAMS_ACTION)) {
0830:                    node = new Node.ParamsAction(qName, nonTaglibXmlnsAttrs,
0831:                            taglibAttrs, start, current);
0832:                } else if (localName.equals(PLUGIN_ACTION)) {
0833:                    node = new Node.PlugIn(qName, nonTaglibAttrs,
0834:                            nonTaglibXmlnsAttrs, taglibAttrs, start, current);
0835:                } else if (localName.equals(TEXT_ACTION)) {
0836:                    node = new Node.JspText(qName, nonTaglibXmlnsAttrs,
0837:                            taglibAttrs, start, current);
0838:                } else if (localName.equals(BODY_ACTION)) {
0839:                    node = new Node.JspBody(qName, nonTaglibXmlnsAttrs,
0840:                            taglibAttrs, start, current);
0841:                } else if (localName.equals(ATTRIBUTE_ACTION)) {
0842:                    node = new Node.NamedAttribute(qName, nonTaglibAttrs,
0843:                            nonTaglibXmlnsAttrs, taglibAttrs, start, current);
0844:                } else if (localName.equals(OUTPUT_ACTION)) {
0845:                    node = new Node.JspOutput(qName, nonTaglibAttrs,
0846:                            nonTaglibXmlnsAttrs, taglibAttrs, start, current);
0847:                } else if (localName.equals(TAG_DIRECTIVE_ACTION)) {
0848:                    if (!isTagFile) {
0849:                        throw new SAXParseException(Localizer.getMessage(
0850:                                "jsp.error.action.isnottagfile", localName),
0851:                                locator);
0852:                    }
0853:                    node = new Node.TagDirective(qName, nonTaglibAttrs,
0854:                            nonTaglibXmlnsAttrs, taglibAttrs, start, current);
0855:                    String imports = nonTaglibAttrs.getValue("import");
0856:                    // There can only be one 'import' attribute per tag directive
0857:                    if (imports != null) {
0858:                        ((Node.TagDirective) node).addImport(imports);
0859:                    }
0860:                } else if (localName.equals(ATTRIBUTE_DIRECTIVE_ACTION)) {
0861:                    if (!isTagFile) {
0862:                        throw new SAXParseException(Localizer.getMessage(
0863:                                "jsp.error.action.isnottagfile", localName),
0864:                                locator);
0865:                    }
0866:                    node = new Node.AttributeDirective(qName, nonTaglibAttrs,
0867:                            nonTaglibXmlnsAttrs, taglibAttrs, start, current);
0868:                } else if (localName.equals(VARIABLE_DIRECTIVE_ACTION)) {
0869:                    if (!isTagFile) {
0870:                        throw new SAXParseException(Localizer.getMessage(
0871:                                "jsp.error.action.isnottagfile", localName),
0872:                                locator);
0873:                    }
0874:                    node = new Node.VariableDirective(qName, nonTaglibAttrs,
0875:                            nonTaglibXmlnsAttrs, taglibAttrs, start, current);
0876:                } else if (localName.equals(INVOKE_ACTION)) {
0877:                    if (!isTagFile) {
0878:                        throw new SAXParseException(Localizer.getMessage(
0879:                                "jsp.error.action.isnottagfile", localName),
0880:                                locator);
0881:                    }
0882:                    node = new Node.InvokeAction(qName, nonTaglibAttrs,
0883:                            nonTaglibXmlnsAttrs, taglibAttrs, start, current);
0884:                } else if (localName.equals(DOBODY_ACTION)) {
0885:                    if (!isTagFile) {
0886:                        throw new SAXParseException(Localizer.getMessage(
0887:                                "jsp.error.action.isnottagfile", localName),
0888:                                locator);
0889:                    }
0890:                    node = new Node.DoBodyAction(qName, nonTaglibAttrs,
0891:                            nonTaglibXmlnsAttrs, taglibAttrs, start, current);
0892:                } else if (localName.equals(ELEMENT_ACTION)) {
0893:                    node = new Node.JspElement(qName, nonTaglibAttrs,
0894:                            nonTaglibXmlnsAttrs, taglibAttrs, start, current);
0895:                } else if (localName.equals(FALLBACK_ACTION)) {
0896:                    node = new Node.FallBackAction(qName, nonTaglibXmlnsAttrs,
0897:                            taglibAttrs, start, current);
0898:                } else {
0899:                    throw new SAXParseException(Localizer.getMessage(
0900:                            "jsp.error.xml.badStandardAction", localName),
0901:                            locator);
0902:                }
0903:
0904:                return node;
0905:            }
0906:
0907:            /*
0908:             * Checks if the XML element with the given tag name is a custom action,
0909:             * and returns the corresponding Node object.
0910:             */
0911:            private Node parseCustomAction(String qName, String localName,
0912:                    String uri, Attributes nonTaglibAttrs,
0913:                    Attributes nonTaglibXmlnsAttrs, Attributes taglibAttrs,
0914:                    Mark start, Node parent) throws SAXException {
0915:
0916:                // Check if this is a user-defined (custom) tag
0917:                TagLibraryInfo tagLibInfo = pageInfo.getTaglib(uri);
0918:                if (tagLibInfo == null) {
0919:                    return null;
0920:                }
0921:
0922:                TagInfo tagInfo = tagLibInfo.getTag(localName);
0923:                TagFileInfo tagFileInfo = tagLibInfo.getTagFile(localName);
0924:                if (tagInfo == null && tagFileInfo == null) {
0925:                    throw new SAXException(Localizer.getMessage(
0926:                            "jsp.error.xml.bad_tag", localName, uri));
0927:                }
0928:                Class tagHandlerClass = null;
0929:                if (tagInfo != null) {
0930:                    String handlerClassName = tagInfo.getTagClassName();
0931:                    try {
0932:                        tagHandlerClass = ctxt.getClassLoader().loadClass(
0933:                                handlerClassName);
0934:                    } catch (Exception e) {
0935:                        throw new SAXException(Localizer.getMessage(
0936:                                "jsp.error.loadclass.taghandler",
0937:                                handlerClassName, qName), e);
0938:                    }
0939:                }
0940:
0941:                String prefix = "";
0942:                int colon = qName.indexOf(':');
0943:                if (colon != -1) {
0944:                    prefix = qName.substring(0, colon);
0945:                }
0946:
0947:                Node.CustomTag ret = null;
0948:                if (tagInfo != null) {
0949:                    ret = new Node.CustomTag(qName, prefix, localName, uri,
0950:                            nonTaglibAttrs, nonTaglibXmlnsAttrs, taglibAttrs,
0951:                            start, parent, tagInfo, tagHandlerClass);
0952:                } else {
0953:                    ret = new Node.CustomTag(qName, prefix, localName, uri,
0954:                            nonTaglibAttrs, nonTaglibXmlnsAttrs, taglibAttrs,
0955:                            start, parent, tagFileInfo);
0956:                }
0957:
0958:                return ret;
0959:            }
0960:
0961:            /*
0962:             * Creates the tag library associated with the given uri namespace, and
0963:             * returns it.
0964:             *
0965:             * @param prefix The prefix of the xmlns attribute
0966:             * @param uri The uri namespace (value of the xmlns attribute)
0967:             *
0968:             * @return The tag library associated with the given uri namespace
0969:             */
0970:            private TagLibraryInfo getTaglibInfo(String prefix, String uri)
0971:                    throws JasperException {
0972:
0973:                TagLibraryInfo result = null;
0974:
0975:                if (uri.startsWith(URN_JSPTAGDIR)) {
0976:                    // uri (of the form "urn:jsptagdir:path") references tag file dir
0977:                    String tagdir = uri.substring(URN_JSPTAGDIR.length());
0978:                    result = new ImplicitTagLibraryInfo(ctxt, parserController,
0979:                            pageInfo, prefix, tagdir, err);
0980:                } else {
0981:                    // uri references TLD file
0982:                    boolean isPlainUri = false;
0983:                    if (uri.startsWith(URN_JSPTLD)) {
0984:                        // uri is of the form "urn:jsptld:path"
0985:                        uri = uri.substring(URN_JSPTLD.length());
0986:                    } else {
0987:                        isPlainUri = true;
0988:                    }
0989:
0990:                    String[] location = ctxt.getTldLocation(uri);
0991:                    if (location != null || !isPlainUri) {
0992:                        if (ctxt.getOptions().isCaching()) {
0993:                            result = (TagLibraryInfoImpl) ctxt.getOptions()
0994:                                    .getCache().get(uri);
0995:                        }
0996:                        if (result == null) {
0997:                            /*
0998:                             * If the uri value is a plain uri, a translation error must
0999:                             * not be generated if the uri is not found in the taglib map.
1000:                             * Instead, any actions in the namespace defined by the uri
1001:                             * value must be treated as uninterpreted.
1002:                             */
1003:                            result = new TagLibraryInfoImpl(ctxt,
1004:                                    parserController, pageInfo, prefix, uri,
1005:                                    location, err);
1006:                            if (ctxt.getOptions().isCaching()) {
1007:                                ctxt.getOptions().getCache().put(uri, result);
1008:                            }
1009:                        }
1010:                    }
1011:                }
1012:
1013:                return result;
1014:            }
1015:
1016:            /*
1017:             * Ensures that the given body only contains nodes that are instances of
1018:             * TemplateText.
1019:             *
1020:             * This check is performed only for the body of a scripting (that is:
1021:             * declaration, scriptlet, or expression) element, after the end tag of a
1022:             * scripting element has been reached.
1023:             */
1024:            private void checkScriptingBody(Node.ScriptingElement scriptingElem)
1025:                    throws SAXException {
1026:                Node.Nodes body = scriptingElem.getBody();
1027:                if (body != null) {
1028:                    int size = body.size();
1029:                    for (int i = 0; i < size; i++) {
1030:                        Node n = body.getNode(i);
1031:                        if (!(n instanceof  Node.TemplateText)) {
1032:                            String elemType = SCRIPTLET_ACTION;
1033:                            if (scriptingElem instanceof  Node.Declaration)
1034:                                elemType = DECLARATION_ACTION;
1035:                            if (scriptingElem instanceof  Node.Expression)
1036:                                elemType = EXPRESSION_ACTION;
1037:                            String msg = Localizer
1038:                                    .getMessage(
1039:                                            "jsp.error.parse.xml.scripting.invalid.body",
1040:                                            elemType);
1041:                            throw new SAXException(msg);
1042:                        }
1043:                    }
1044:                }
1045:            }
1046:
1047:            /*
1048:             * Parses the given file included via an include directive.
1049:             *
1050:             * @param fname The path to the included resource, as specified by the
1051:             * 'file' attribute of the include directive
1052:             * @param parent The Node representing the include directive
1053:             */
1054:            private void processIncludeDirective(String fname, Node parent)
1055:                    throws SAXException {
1056:
1057:                if (fname == null) {
1058:                    return;
1059:                }
1060:
1061:                try {
1062:                    parserController.parse(fname, parent, null);
1063:                } catch (FileNotFoundException fnfe) {
1064:                    throw new SAXParseException(Localizer.getMessage(
1065:                            "jsp.error.file.not.found", fname), locator, fnfe);
1066:                } catch (Exception e) {
1067:                    throw new SAXException(e);
1068:                }
1069:            }
1070:
1071:            /*
1072:             * Checks an element's given URI, qname, and attributes to see if any
1073:             * of them hijack the 'jsp' prefix, that is, bind it to a namespace other
1074:             * than http://java.sun.com/JSP/Page.
1075:             *
1076:             * @param uri The element's URI
1077:             * @param qName The element's qname
1078:             * @param attrs The element's attributes
1079:             */
1080:            private void checkPrefixes(String uri, String qName,
1081:                    Attributes attrs) {
1082:
1083:                checkPrefix(uri, qName);
1084:
1085:                int len = attrs.getLength();
1086:                for (int i = 0; i < len; i++) {
1087:                    checkPrefix(attrs.getURI(i), attrs.getQName(i));
1088:                }
1089:            }
1090:
1091:            /*
1092:             * Checks the given URI and qname to see if they hijack the 'jsp' prefix,
1093:             * which would be the case if qName contained the 'jsp' prefix and
1094:             * uri was different from http://java.sun.com/JSP/Page.
1095:             *
1096:             * @param uri The URI to check
1097:             * @param qName The qname to check
1098:             */
1099:            private void checkPrefix(String uri, String qName) {
1100:
1101:                int index = qName.indexOf(':');
1102:                if (index != -1) {
1103:                    String prefix = qName.substring(0, index);
1104:                    pageInfo.addPrefix(prefix);
1105:                    if ("jsp".equals(prefix) && !JSP_URI.equals(uri)) {
1106:                        pageInfo.setIsJspPrefixHijacked(true);
1107:                    }
1108:                }
1109:            }
1110:
1111:            /*
1112:             * Gets SAXParser.
1113:             *
1114:             * @param validating Indicates whether the requested SAXParser should
1115:             * be validating
1116:             * @param jspDocParser The JSP document parser
1117:             *
1118:             * @return The SAXParser
1119:             */
1120:            private static SAXParser getSAXParser(boolean validating,
1121:                    JspDocumentParser jspDocParser) throws Exception {
1122:
1123:                SAXParserFactory factory = SAXParserFactory.newInstance();
1124:                factory.setNamespaceAware(true);
1125:
1126:                // Preserve xmlns attributes
1127:                factory.setFeature(
1128:                        "http://xml.org/sax/features/namespace-prefixes", true);
1129:                factory.setValidating(validating);
1130:                //factory.setFeature(
1131:                //    "http://xml.org/sax/features/validation",
1132:                //    validating);
1133:
1134:                // Configure the parser
1135:                SAXParser saxParser = factory.newSAXParser();
1136:                XMLReader xmlReader = saxParser.getXMLReader();
1137:                xmlReader.setProperty(LEXICAL_HANDLER_PROPERTY, jspDocParser);
1138:                xmlReader.setErrorHandler(jspDocParser);
1139:
1140:                return saxParser;
1141:            }
1142:
1143:            /*
1144:             * Exception indicating that a DOCTYPE declaration is present, but
1145:             * validation is turned off.
1146:             */
1147:            private static class EnableDTDValidationException extends
1148:                    SAXParseException {
1149:
1150:                EnableDTDValidationException(String message, Locator loc) {
1151:                    super (message, loc);
1152:                }
1153:            }
1154:
1155:            private static String getBodyType(Node.CustomTag custom) {
1156:
1157:                if (custom.getTagInfo() != null) {
1158:                    return custom.getTagInfo().getBodyContent();
1159:                }
1160:
1161:                return custom.getTagFileInfo().getTagInfo().getBodyContent();
1162:            }
1163:
1164:            private boolean isTagDependent(Node n) {
1165:
1166:                if (n instanceof  Node.CustomTag) {
1167:                    String bodyType = getBodyType((Node.CustomTag) n);
1168:                    return TagInfo.BODY_CONTENT_TAG_DEPENDENT
1169:                            .equalsIgnoreCase(bodyType);
1170:                }
1171:                return false;
1172:            }
1173:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.