
org.apache.jasper.compiler.JspDocumentParser Maven / Gradle / Ivy
/*
* 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 - 2025 Weber Informatics LLC | Privacy Policy