All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.jasper.compiler.JspDocumentParser Maven / Gradle / Ivy

There is a newer version: 5.5.23
Show newest version
/*
 * Copyright 1999,2004 The Apache Software Foundation.
 * 
 * Licensed 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.*;
import java.util.Hashtable;
import javax.servlet.jsp.tagext.*;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import org.xml.sax.*;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.AttributesImpl;
import org.apache.jasper.JasperException;
import org.apache.jasper.JspCompilationContext;

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

public class JspDocumentParser extends DefaultHandler
            implements LexicalHandler, TagConstants {

    private static final String XMLNS = "xmlns:";
    private static final String XMLNS_JSP = "xmlns:jsp";
    private static final String JSP_VERSION = "version";
    private static final String XMLNS_XSI = "xmlns:xsi";
    private static final String XSI_SCHEMA_LOCATION = "xsi:schemaLocation";
    private static final String URN_JSPTLD = "urn:jsptld:";
    private static final String LEXICAL_HANDLER_PROPERTY
        = "http://xml.org/sax/properties/lexical-handler";

    private ParserController parserController;

    // XXX
    private JspCompilationContext ctxt;
    
    // XML document source
    private InputSource inputSource;

    // XXX
    private String path;

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

    // Document locator
    private Locator locator;

    // XXX
    private Hashtable taglibs;

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

    private ErrorDispatcher err;

    /*
     * Constructor
     */
    public JspDocumentParser(ParserController pc,
                             String path,
                             InputStreamReader reader) {
        this.parserController = pc;
        this.ctxt = pc.getJspCompilationContext();
        this.taglibs = pc.getCompiler().getPageInfo().getTagLibraries();
        this.err = pc.getCompiler().getErrorDispatcher();
        this.path = path;
        this.inputSource = new InputSource(reader);
    }

    /*
     * Parses a JSP document by responding to SAX events.
     *
     * @throws JasperException XXX
     */
    public static Node.Nodes parse(ParserController pc,
                                   String path,
                                   InputStreamReader reader,
                                   Node parent) throws JasperException {
        JspDocumentParser handler = new JspDocumentParser(pc, path, reader);
        handler.current = parent;
        Node.Nodes pageNodes = null;

        try {
            // Use the default (non-validating) parser
            SAXParserFactory factory = SAXParserFactory.newInstance();

            // Configure the parser
            SAXParser saxParser = factory.newSAXParser();
            XMLReader xmlReader = saxParser.getXMLReader();
            xmlReader.setProperty(LEXICAL_HANDLER_PROPERTY, handler);
            xmlReader.setErrorHandler(handler);

            // Parse the input
            saxParser.parse(handler.inputSource, handler);

            if (parent == null) {
                // Add the jsp:root element to the parse result
                pageNodes = new Node.Nodes((Node.JspRoot) handler.current);
            } else {
                pageNodes = parent.getBody();
            }
        } catch (IOException ioe) {
            handler.err.jspError("jsp.error.data.file.read", path, ioe);
        } catch (Exception e) {
            handler.err.jspError(e);
        }

        return pageNodes;
    }

    /*
     * Receives notification of the start of an element.
     */
    public void startElement(String uri,
                             String localName,
                             String qName,
                             Attributes attrs) throws SAXException {

        Mark start = new Mark(path, locator.getLineNumber(),
                              locator.getColumnNumber());
        Attributes attrsCopy = new AttributesImpl(attrs);

        Node node = null;        
        if (qName.equals(JSP_ROOT_TAG)) {
            node = new Node.JspRoot(attrsCopy, start, current);
            try {
                addCustomTagLibraries(attrsCopy);
            } catch (JasperException je) {
                throw new SAXException(je);
            }
        } else if (qName.equals(JSP_PAGE_DIRECTIVE_TAG)) {
            node = new Node.PageDirective(attrsCopy, start, current);
            String imports = attrs.getValue("import");
            // There can only be one 'import' attribute per page directive
            if (imports != null) {
                ((Node.PageDirective) node).addImport(imports);
            }
        } else if (qName.equals(JSP_INCLUDE_DIRECTIVE_TAG)) {
            node = new Node.IncludeDirective(attrsCopy, start, current);
            String file = attrsCopy.getValue("file");
            try {
                parserController.parse(file, node);
            } catch (FileNotFoundException fnfe) {
                throw new SAXParseException(
                    err.getString("jsp.error.file.not.found", file),
                    locator, fnfe);
            } catch (Exception e) {
                throw new SAXException(e);
            }
        } else if (qName.equals(JSP_DECLARATION_TAG)) {
            node = new Node.Declaration(start, current);
        } else if (qName.equals(JSP_SCRIPTLET_TAG)) {
            node = new Node.Scriptlet(start, current);
        } else if (qName.equals(JSP_EXPRESSION_TAG)) {
            node = new Node.Expression(start, current);
        } else if (qName.equals(JSP_USE_BEAN_TAG)) {
            node = new Node.UseBean(attrsCopy, start, current);
        } else if (qName.equals(JSP_SET_PROPERTY_TAG)) {
            node = new Node.SetProperty(attrsCopy, start, current);
        } else if (qName.equals(JSP_GET_PROPERTY_TAG)) {
            node = new Node.GetProperty(attrsCopy, start, current);
        } else if (qName.equals(JSP_INCLUDE_TAG)) {
            node = new Node.IncludeAction(attrsCopy, start, current);
        } else if (qName.equals(JSP_FORWARD_TAG)) {
            node = new Node.ForwardAction(attrsCopy, start, current);
        } else if (qName.equals(JSP_PARAM_TAG)) {
            node = new Node.ParamAction(attrsCopy, start, current);
        } else if (qName.equals(JSP_PARAMS_TAG)) {
            node = new Node.ParamsAction(start, current);
        } else if (qName.equals(JSP_PLUGIN_TAG)) {
            node = new Node.PlugIn(attrsCopy, start, current);
        } else if (qName.equals(JSP_TEXT_TAG)) {
            node = new Node.JspText(start, current);
        } else if (qName.equals(JSP_FALLBACK_TAG)) {
            node = new Node.FallBackAction(start, current);
        } else {
            node = getCustomTag(qName, attrsCopy, start, current);
            if (node == null) {
                node = new Node.UninterpretedTag(attrsCopy, start, qName,
                                                 current);
            }
        }

        current = node;
    }

    /*
     * Receives notification of character data inside an element.
     *
     * @param buf The characters
     * @param offset The start position in the character array
     * @param len The number of characters to use from the character array
     *
     * @throws SAXException
     */
    public void characters(char[] buf,
                           int offset,
                           int len) throws SAXException {
        /*
         * All textual nodes that have only white space are to be dropped from
         * the document, except for nodes in a jsp:text element, which are 
         * kept verbatim (JSP 5.2.1).
         */
        boolean isAllSpace = true;
        if (!(current instanceof Node.JspText)) {
            for (int i=offset; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy