⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jspdocumentparser.java

📁 业界著名的tomcat服务器的最新6.0的源代码。
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.jasper.compiler;

import java.io.CharArrayWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import java.util.Iterator;
import java.util.List;
import java.util.jar.JarFile;

import javax.servlet.jsp.tagext.TagFileInfo;
import javax.servlet.jsp.tagext.TagInfo;
import javax.servlet.jsp.tagext.TagLibraryInfo;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.jasper.JasperException;
import org.apache.jasper.JspCompilationContext;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Class implementing a parser for a JSP document, that is, a JSP page in XML
 * syntax.
 *
 * @author Jan Luehe
 * @author Kin-man Chung
 */

class JspDocumentParser
    extends DefaultHandler
    implements LexicalHandler, TagConstants {

    private static final String JSP_VERSION = "version";
    private static final String LEXICAL_HANDLER_PROPERTY =
        "http://xml.org/sax/properties/lexical-handler";
    private static final String JSP_URI = "http://java.sun.com/JSP/Page";

    private static final EnableDTDValidationException ENABLE_DTD_VALIDATION_EXCEPTION =
        new EnableDTDValidationException(
            "jsp.error.enable_dtd_validation",
            null);

    private ParserController parserController;
    private JspCompilationContext ctxt;
    private PageInfo pageInfo;
    private String path;
    private StringBuffer charBuffer;

    // Node representing the XML element currently being parsed
    private Node current;

    /*
     * Outermost (in the nesting hierarchy) node whose body is declared to be
     * scriptless. If a node's body is declared to be scriptless, all its
     * nested nodes must be scriptless, too.
     */ 
    private Node scriptlessBodyNode;

    private Locator locator;

    //Mark representing the start of the current element.  Note
    //that locator.getLineNumber() and locator.getColumnNumber()
    //return the line and column numbers for the character
    //immediately _following_ the current element.  The underlying
    //XMl parser eats white space that is not part of character
    //data, so for Nodes that are not created from character data,
    //this is the best we can do.  But when we parse character data,
    //we get an accurate starting location by starting with startMark
    //as set by the previous element, and updating it as we advance
    //through the characters.
    private Mark startMark;

    // Flag indicating whether we are inside DTD declarations
    private boolean inDTD;

    private boolean isValidating;

    private ErrorDispatcher err;
    private boolean isTagFile;
    private boolean directivesOnly;
    private boolean isTop;

    // Nesting level of Tag dependent bodies
    private int tagDependentNesting = 0;
    // Flag set to delay incrmenting tagDependentNesting until jsp:body
    // is first encountered
    private boolean tagDependentPending = false;

    /*
     * Constructor
     */
    public JspDocumentParser(
        ParserController pc,
        String path,
        boolean isTagFile,
        boolean directivesOnly) {
        this.parserController = pc;
        this.ctxt = pc.getJspCompilationContext();
        this.pageInfo = pc.getCompiler().getPageInfo();
        this.err = pc.getCompiler().getErrorDispatcher();
        this.path = path;
        this.isTagFile = isTagFile;
        this.directivesOnly = directivesOnly;
        this.isTop = true;
    }

    /*
     * Parses a JSP document by responding to SAX events.
     *
     * @throws JasperException
     */
    public static Node.Nodes parse(
        ParserController pc,
        String path,
        JarFile jarFile,
        Node parent,
        boolean isTagFile,
        boolean directivesOnly,
        String pageEnc,
        String jspConfigPageEnc,
        boolean isEncodingSpecifiedInProlog,
        boolean isBomPresent)
        throws JasperException {

        JspDocumentParser jspDocParser =
            new JspDocumentParser(pc, path, isTagFile, directivesOnly);
        Node.Nodes pageNodes = null;

        try {

            // Create dummy root and initialize it with given page encodings
            Node.Root dummyRoot = new Node.Root(null, parent, true);
            dummyRoot.setPageEncoding(pageEnc);
            dummyRoot.setJspConfigPageEncoding(jspConfigPageEnc);
            dummyRoot.setIsEncodingSpecifiedInProlog(
                isEncodingSpecifiedInProlog);
            dummyRoot.setIsBomPresent(isBomPresent);
            jspDocParser.current = dummyRoot;
            if (parent == null) {
                jspDocParser.addInclude(
                    dummyRoot,
                    jspDocParser.pageInfo.getIncludePrelude());
            } else {
                jspDocParser.isTop = false;
            }

            // Parse the input
            SAXParser saxParser = getSAXParser(false, jspDocParser);
            InputStream inStream = null;
            try {
                inStream = JspUtil.getInputStream(path, jarFile,
                                                  jspDocParser.ctxt,
                                                  jspDocParser.err);
                saxParser.parse(new InputSource(inStream), jspDocParser);
            } catch (EnableDTDValidationException e) {
                saxParser = getSAXParser(true, jspDocParser);
                jspDocParser.isValidating = true;
                if (inStream != null) {
                    try {
                        inStream.close();
                    } catch (Exception any) {
                    }
                }
                inStream = JspUtil.getInputStream(path, jarFile,
                                                  jspDocParser.ctxt,
                                                  jspDocParser.err);
                saxParser.parse(new InputSource(inStream), jspDocParser);
            } finally {
                if (inStream != null) {
                    try {
                        inStream.close();
                    } catch (Exception any) {
                    }
                }
            }

            if (parent == null) {
                jspDocParser.addInclude(
                    dummyRoot,
                    jspDocParser.pageInfo.getIncludeCoda());
            }

            // Create Node.Nodes from dummy root
            pageNodes = new Node.Nodes(dummyRoot);

        } catch (IOException ioe) {
            jspDocParser.err.jspError("jsp.error.data.file.read", path, ioe);
        } catch (SAXParseException e) {
            jspDocParser.err.jspError
                (new Mark(jspDocParser.ctxt, path, e.getLineNumber(),
                          e.getColumnNumber()),
                 e.getMessage());
        } catch (Exception e) {
            jspDocParser.err.jspError(e);
        }

        return pageNodes;
    }

    /*
     * Processes the given list of included files.
     *
     * This is used to implement the include-prelude and include-coda
     * subelements of the jsp-config element in web.xml
     */
    private void addInclude(Node parent, List files) throws SAXException {
        if (files != null) {
            Iterator iter = files.iterator();
            while (iter.hasNext()) {
                String file = (String)iter.next();
                AttributesImpl attrs = new AttributesImpl();
                attrs.addAttribute("", "file", "file", "CDATA", file);

                // Create a dummy Include directive node
                    Node includeDir =
                        new Node.IncludeDirective(attrs, null, // XXX
    parent);
                processIncludeDirective(file, includeDir);
            }
        }
    }

    /*
     * Receives notification of the start of an element.
     *
     * This method assigns the given tag attributes to one of 3 buckets:
     * 
     * - "xmlns" attributes that represent (standard or custom) tag libraries.
     * - "xmlns" attributes that do not represent tag libraries.
     * - all remaining attributes.
     *
     * For each "xmlns" attribute that represents a custom tag library, the
     * corresponding TagLibraryInfo object is added to the set of custom
     * tag libraries.
     */
    public void startElement(
        String uri,
        String localName,
        String qName,
        Attributes attrs)
        throws SAXException {

        AttributesImpl taglibAttrs = null;
        AttributesImpl nonTaglibAttrs = null;
        AttributesImpl nonTaglibXmlnsAttrs = null;

        processChars();

        checkPrefixes(uri, qName, attrs);

        if (directivesOnly &&
            !(JSP_URI.equals(uri) && localName.startsWith(DIRECTIVE_ACTION))) {
            return;
        }

        // jsp:text must not have any subelements
        if (JSP_URI.equals(uri) && TEXT_ACTION.equals(current.getLocalName())) {
            throw new SAXParseException(
                Localizer.getMessage("jsp.error.text.has_subelement"),
                locator);
        }

        startMark = new Mark(ctxt, path, locator.getLineNumber(),
                             locator.getColumnNumber());

        if (attrs != null) {
            /*
             * Notice that due to a bug in the underlying SAX parser, the
             * attributes must be enumerated in descending order. 
             */
            boolean isTaglib = false;
            for (int i = attrs.getLength() - 1; i >= 0; i--) {
                isTaglib = false;
                String attrQName = attrs.getQName(i);
                if (!attrQName.startsWith("xmlns")) {
                    if (nonTaglibAttrs == null) {
                        nonTaglibAttrs = new AttributesImpl();
                    }
                    nonTaglibAttrs.addAttribute(
                        attrs.getURI(i),
                        attrs.getLocalName(i),
                        attrs.getQName(i),
                        attrs.getType(i),
                        attrs.getValue(i));
                } else {
                    if (attrQName.startsWith("xmlns:jsp")) {
                        isTaglib = true;
                    } else {
                        String attrUri = attrs.getValue(i);
                        // TaglibInfo for this uri already established in
                        // startPrefixMapping
                        isTaglib = pageInfo.hasTaglib(attrUri);
                    }
                    if (isTaglib) {
                        if (taglibAttrs == null) {
                            taglibAttrs = new AttributesImpl();
                        }
                        taglibAttrs.addAttribute(
                            attrs.getURI(i),
                            attrs.getLocalName(i),
                            attrs.getQName(i),
                            attrs.getType(i),
                            attrs.getValue(i));
                    } else {
                        if (nonTaglibXmlnsAttrs == null) {
                            nonTaglibXmlnsAttrs = new AttributesImpl();
                        }
                        nonTaglibXmlnsAttrs.addAttribute(
                            attrs.getURI(i),
                            attrs.getLocalName(i),
                            attrs.getQName(i),
                            attrs.getType(i),
                            attrs.getValue(i));
                    }
                }
            }
        }

        Node node = null;

        if (tagDependentPending && JSP_URI.equals(uri) &&
                     localName.equals(BODY_ACTION)) {
            tagDependentPending = false;
            tagDependentNesting++;
            current =
                parseStandardAction(
                    qName,
                    localName,
                    nonTaglibAttrs,
                    nonTaglibXmlnsAttrs,
                    taglibAttrs,
                    startMark,
                    current);
            return;
        }

        if (tagDependentPending && JSP_URI.equals(uri) &&

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -