* for include directives that refer to relative paths.
*/
private Stack baseDirStack = new Stack();
-
+
private boolean isEncodingSpecifiedInProlog;
private boolean isBomPresent;
*/
public ParserController(JspCompilationContext ctxt, Compiler compiler) {
this.ctxt = ctxt;
- this.compiler = compiler;
- this.err = compiler.getErrorDispatcher();
+ this.compiler = compiler;
+ this.err = compiler.getErrorDispatcher();
}
public JspCompilationContext getJspCompilationContext () {
- return ctxt;
+ return ctxt;
}
public Compiler getCompiler () {
- return compiler;
+ return compiler;
}
/**
* @param inFileName The path to the JSP page or tag file to be parsed.
*/
public Node.Nodes parse(String inFileName)
- throws FileNotFoundException, JasperException, IOException {
- // If we're parsing a packaged tag file or a resource included by it
- // (using an include directive), ctxt.getTagFileJar() returns the
- // JAR file from which to read the tag file or included resource,
- // respectively.
+ throws FileNotFoundException, JasperException, IOException {
+ // If we're parsing a packaged tag file or a resource included by it
+ // (using an include directive), ctxt.getTagFileJar() returns the
+ // JAR file from which to read the tag file or included resource,
+ // respectively.
isTagFile = ctxt.isTagFile();
directiveOnly = false;
return doParse(inFileName, null, ctxt.getTagFileJarUrl());
* or null of the included resource is to be read from the filesystem
*/
public Node.Nodes parse(String inFileName, Node parent,
- URL jarFileUrl)
- throws FileNotFoundException, JasperException, IOException {
+ URL jarFileUrl)
+ throws FileNotFoundException, JasperException, IOException {
// For files that are statically included, isTagfile and directiveOnly
// remain unchanged.
return doParse(inFileName, parent, jarFileUrl);
* @param inFileName The name of the tag file to be parsed.
*/
public Node.Nodes parseTagFileDirectives(String inFileName)
- throws FileNotFoundException, JasperException, IOException {
+ throws FileNotFoundException, JasperException, IOException {
boolean isTagFileSave = isTagFile;
boolean directiveOnlySave = directiveOnly;
isTagFile = true;
* or null if the JSP page or tag file is to be read from the filesystem
*/
private Node.Nodes doParse(String inFileName,
- Node parent,
- URL jarFileUrl)
- throws FileNotFoundException, JasperException, IOException {
-
- Node.Nodes parsedPage = null;
- isEncodingSpecifiedInProlog = false;
- isBomPresent = false;
- isDefaultPageEncoding = false;
-
- JarFile jarFile = getJarFile(jarFileUrl);
- String absFileName = resolveFileName(inFileName);
- String jspConfigPageEnc = getJspConfigPageEncoding(absFileName);
-
- // Figure out what type of JSP document and encoding type we are
- // dealing with
- determineSyntaxAndEncoding(absFileName, jarFile, jspConfigPageEnc);
-
- if (parent != null) {
- // Included resource, add to dependent list
- compiler.getPageInfo().addDependant(absFileName);
- }
-
- if ((isXml && isEncodingSpecifiedInProlog) || isBomPresent) {
- /*
- * Make sure the encoding explicitly specified in the XML
- * prolog (if any) matches that in the JSP config element
- * (if any), treating "UTF-16", "UTF-16BE", and "UTF-16LE" as
- * identical.
- */
- if (jspConfigPageEnc != null && !jspConfigPageEnc.equals(sourceEnc)
- && (!jspConfigPageEnc.startsWith("UTF-16")
- || !sourceEnc.startsWith("UTF-16"))) {
- err.jspError("jsp.error.prolog_config_encoding_mismatch",
- sourceEnc, jspConfigPageEnc);
- }
- }
-
- // Dispatch to the appropriate parser
- if (isXml) {
- // JSP document (XML syntax)
+ Node parent,
+ URL jarFileUrl)
+ throws FileNotFoundException, JasperException, IOException {
+
+ Node.Nodes parsedPage = null;
+ isEncodingSpecifiedInProlog = false;
+ isBomPresent = false;
+ isDefaultPageEncoding = false;
+
+ JarFile jarFile = getJarFile(jarFileUrl);
+ String absFileName = resolveFileName(inFileName);
+ String jspConfigPageEnc = getJspConfigPageEncoding(absFileName);
+
+ // Figure out what type of JSP document and encoding type we are
+ // dealing with
+ determineSyntaxAndEncoding(absFileName, jarFile, jspConfigPageEnc);
+
+ if (parent != null) {
+ // Included resource, add to dependent list
+ compiler.getPageInfo().addDependant(absFileName);
+ }
+
+ if ((isXml && isEncodingSpecifiedInProlog) || isBomPresent) {
+ /*
+ * Make sure the encoding explicitly specified in the XML
+ * prolog (if any) matches that in the JSP config element
+ * (if any), treating "UTF-16", "UTF-16BE", and "UTF-16LE" as
+ * identical.
+ */
+ if (jspConfigPageEnc != null && !jspConfigPageEnc.equals(sourceEnc)
+ && (!jspConfigPageEnc.startsWith("UTF-16")
+ || !sourceEnc.startsWith("UTF-16"))) {
+ err.jspError("jsp.error.prolog_config_encoding_mismatch",
+ sourceEnc, jspConfigPageEnc);
+ }
+ }
+
+ // Dispatch to the appropriate parser
+ if (isXml) {
+ // JSP document (XML syntax)
// InputStream for jspx page is created and properly closed in
// JspDocumentParser.
parsedPage = JspDocumentParser.parse(this, absFileName,
- jarFile, parent,
- isTagFile, directiveOnly,
- sourceEnc,
- jspConfigPageEnc,
- isEncodingSpecifiedInProlog,
- isBomPresent);
- } else {
- // Standard syntax
- InputStreamReader inStreamReader = null;
- try {
- inStreamReader = JspUtil.getReader(absFileName, sourceEnc,
- jarFile, ctxt, err);
- JspReader jspReader = new JspReader(ctxt, absFileName,
- sourceEnc, inStreamReader,
- err);
+ jarFile, parent,
+ isTagFile, directiveOnly,
+ sourceEnc,
+ jspConfigPageEnc,
+ isEncodingSpecifiedInProlog,
+ isBomPresent);
+ } else {
+ // Standard syntax
+ InputStreamReader inStreamReader = null;
+ try {
+ inStreamReader = JspUtil.getReader(absFileName, sourceEnc,
+ jarFile, ctxt, err);
+ JspReader jspReader = new JspReader(ctxt, absFileName,
+ sourceEnc, inStreamReader,
+ err);
parsedPage = Parser.parse(this, jspReader, parent, isTagFile,
- directiveOnly, jarFileUrl,
- sourceEnc, jspConfigPageEnc,
- isDefaultPageEncoding, isBomPresent);
+ directiveOnly, jarFileUrl,
+ sourceEnc, jspConfigPageEnc,
+ isDefaultPageEncoding, isBomPresent);
} finally {
- if (inStreamReader != null) {
- try {
- inStreamReader.close();
- } catch (Exception any) {
- }
- }
- }
- }
-
- if (jarFile != null) {
- try {
- jarFile.close();
- } catch (Throwable t) {}
- }
-
- baseDirStack.pop();
-
- return parsedPage;
+ if (inStreamReader != null) {
+ try {
+ inStreamReader.close();
+ } catch (Exception any) {
+ }
+ }
+ }
+ }
+
+ if (jarFile != null) {
+ try {
+ jarFile.close();
+ } catch (Throwable t) {}
+ }
+
+ baseDirStack.pop();
+
+ return parsedPage;
}
/*
* jsp-property-group with matching URL pattern
*/
private String getJspConfigPageEncoding(String absFileName)
- throws JasperException {
+ throws JasperException {
- JspConfig jspConfig = ctxt.getOptions().getJspConfig();
- JspConfig.JspProperty jspProperty
- = jspConfig.findJspProperty(absFileName);
- return jspProperty.getPageEncoding();
+ JspConfig jspConfig = ctxt.getOptions().getJspConfig();
+ JspConfig.JspProperty jspProperty
+ = jspConfig.findJspProperty(absFileName);
+ return jspProperty.getPageEncoding();
}
/**
* instance variables, respectively.
*/
private void determineSyntaxAndEncoding(String absFileName,
- JarFile jarFile,
- String jspConfigPageEnc)
- throws JasperException, IOException {
+ JarFile jarFile,
+ String jspConfigPageEnc)
+ throws JasperException, IOException {
- isXml = false;
+ isXml = false;
- /*
- * 'true' if the syntax (XML or standard) of the file is given
- * from external information: either via a JSP configuration element,
- * the ".jspx" suffix, or the enclosing file (for included resources)
- */
- boolean isExternal = false;
+ /*
+ * 'true' if the syntax (XML or standard) of the file is given
+ * from external information: either via a JSP configuration element,
+ * the ".jspx" suffix, or the enclosing file (for included resources)
+ */
+ boolean isExternal = false;
- /*
- * Indicates whether we need to revert from temporary usage of
- * "ISO-8859-1" back to "UTF-8"
- */
- boolean revert = false;
+ /*
+ * Indicates whether we need to revert from temporary usage of
+ * "ISO-8859-1" back to "UTF-8"
+ */
+ boolean revert = false;
JspConfig jspConfig = ctxt.getOptions().getJspConfig();
JspConfig.JspProperty jspProperty = jspConfig.findJspProperty(
- absFileName);
+ absFileName);
if (jspProperty.isXml() != null) {
// If <is-xml> is specified in a <jsp-property-group>, it is used.
isXml = JspUtil.booleanValue(jspProperty.isXml());
- isExternal = true;
- } else if (absFileName.endsWith(".jspx")
- || absFileName.endsWith(".tagx")) {
- isXml = true;
- isExternal = true;
- }
-
- if (isExternal && !isXml) {
- // JSP (standard) syntax. Use encoding specified in jsp-config
- // if provided.
- sourceEnc = jspConfigPageEnc;
- if (sourceEnc != null) {
- return;
- }
- // We don't know the encoding, so use BOM to determine it
- sourceEnc = "ISO-8859-1";
- } else {
- // XML syntax or unknown, (auto)detect encoding ...
- Object[] ret = XMLEncodingDetector.getEncoding(absFileName,
- jarFile, ctxt, err);
- sourceEnc = (String) ret[0];
- if (((Boolean) ret[1]).booleanValue()) {
- isEncodingSpecifiedInProlog = true;
- }
- if (((Boolean) ret[2]).booleanValue()) {
- isBomPresent = true;
- }
-
- if (!isXml && sourceEnc.equals("UTF-8")) {
- /*
- * We don't know if we're dealing with XML or standard syntax.
- * Therefore, we need to check to see if the page contains
- * a <jsp:root> element.
- *
- * We need to be careful, because the page may be encoded in
- * ISO-8859-1 (or something entirely different), and may
- * contain byte sequences that will cause a UTF-8 converter to
- * throw exceptions.
- *
- * It is safe to use a source encoding of ISO-8859-1 in this
- * case, as there are no invalid byte sequences in ISO-8859-1,
- * and the byte/character sequences we're looking for (i.e.,
- * <jsp:root>) are identical in either encoding (both UTF-8
- * and ISO-8859-1 are extensions of ASCII).
- */
- sourceEnc = "ISO-8859-1";
- revert = true;
- }
- }
-
- if (isXml) {
- // (This implies 'isExternal' is TRUE.)
- // We know we're dealing with a JSP document (via JSP config or
- // ".jspx" suffix), so we're done.
- return;
- }
-
- /*
- * At this point, 'isExternal' or 'isXml' is FALSE.
- * Search for jsp:root action, in order to determine if we're dealing
- * with XML or standard syntax (unless we already know what we're
- * dealing with, i.e., when 'isExternal' is TRUE and 'isXml' is FALSE).
- * No check for XML prolog, since nothing prevents a page from
- * outputting XML and still using JSP syntax (in this case, the
- * XML prolog is treated as template text).
- */
- JspReader jspReader = null;
- try {
- jspReader = new JspReader(ctxt, absFileName, sourceEnc, jarFile,
- err);
- } catch (FileNotFoundException ex) {
- throw new JasperException(ex);
- }
+ isExternal = true;
+ } else if (absFileName.endsWith(".jspx")
+ || absFileName.endsWith(".tagx")) {
+ isXml = true;
+ isExternal = true;
+ }
+
+ if (isExternal && !isXml) {
+ // JSP (standard) syntax. Use encoding specified in jsp-config
+ // if provided.
+ sourceEnc = jspConfigPageEnc;
+ if (sourceEnc != null) {
+ return;
+ }
+ // We don't know the encoding, so use BOM to determine it
+ sourceEnc = "ISO-8859-1";
+ } else {
+ // XML syntax or unknown, (auto)detect encoding ...
+ Object[] ret = XMLEncodingDetector.getEncoding(absFileName,
+ jarFile, ctxt, err);
+ sourceEnc = (String) ret[0];
+ if (((Boolean) ret[1]).booleanValue()) {
+ isEncodingSpecifiedInProlog = true;
+ }
+ if (((Boolean) ret[2]).booleanValue()) {
+ isBomPresent = true;
+ }
+
+ if (!isXml && sourceEnc.equals("UTF-8")) {
+ /*
+ * We don't know if we're dealing with XML or standard syntax.
+ * Therefore, we need to check to see if the page contains
+ * a <jsp:root> element.
+ *
+ * We need to be careful, because the page may be encoded in
+ * ISO-8859-1 (or something entirely different), and may
+ * contain byte sequences that will cause a UTF-8 converter to
+ * throw exceptions.
+ *
+ * It is safe to use a source encoding of ISO-8859-1 in this
+ * case, as there are no invalid byte sequences in ISO-8859-1,
+ * and the byte/character sequences we're looking for (i.e.,
+ * <jsp:root>) are identical in either encoding (both UTF-8
+ * and ISO-8859-1 are extensions of ASCII).
+ */
+ sourceEnc = "ISO-8859-1";
+ revert = true;
+ }
+ }
+
+ if (isXml) {
+ // (This implies 'isExternal' is TRUE.)
+ // We know we're dealing with a JSP document (via JSP config or
+ // ".jspx" suffix), so we're done.
+ return;
+ }
+
+ /*
+ * At this point, 'isExternal' or 'isXml' is FALSE.
+ * Search for jsp:root action, in order to determine if we're dealing
+ * with XML or standard syntax (unless we already know what we're
+ * dealing with, i.e., when 'isExternal' is TRUE and 'isXml' is FALSE).
+ * No check for XML prolog, since nothing prevents a page from
+ * outputting XML and still using JSP syntax (in this case, the
+ * XML prolog is treated as template text).
+ */
+ JspReader jspReader = null;
+ try {
+ jspReader = new JspReader(ctxt, absFileName, sourceEnc, jarFile,
+ err);
+ } catch (FileNotFoundException ex) {
+ throw new JasperException(ex);
+ }
jspReader.setSingleFile(true);
Mark startMark = jspReader.mark();
- if (!isExternal) {
- jspReader.reset(startMark);
- if (hasJspRoot(jspReader)) {
- if (revert) sourceEnc = "UTF-8";
- isXml = true;
- return;
- } else {
- if (revert && isBomPresent) sourceEnc = "UTF-8";
- isXml = false;
- }
- }
-
- /*
- * At this point, we know we're dealing with JSP syntax.
- * If an XML prolog is provided, it's treated as template text.
- * Determine the page encoding from the page directive, unless it's
- * specified via JSP config.
- */
- if (sourceEnc == null) {
- sourceEnc = jspConfigPageEnc;
- if (sourceEnc == null) {
- sourceEnc = getPageEncodingForJspSyntax(jspReader, startMark);
+ if (!isExternal) {
+ jspReader.reset(startMark);
+ if (hasJspRoot(jspReader)) {
+ if (revert) {
+ sourceEnc = "UTF-8";
+ }
+ isXml = true;
+ return;
+ } else {
+ if (revert && isBomPresent) {
+ sourceEnc = "UTF-8";
+ }
+ isXml = false;
+ }
+ }
+
+ /*
+ * At this point, we know we're dealing with JSP syntax.
+ * If an XML prolog is provided, it's treated as template text.
+ * Determine the page encoding from the page directive, unless it's
+ * specified via JSP config.
+ */
+ if (!isBomPresent) {
+ sourceEnc = jspConfigPageEnc;
if (sourceEnc == null) {
- // Default to "ISO-8859-1" per JSP spec
- sourceEnc = "ISO-8859-1";
- isDefaultPageEncoding = true;
+ sourceEnc = getPageEncodingForJspSyntax(jspReader, startMark);
+ if (sourceEnc == null) {
+ // Default to "ISO-8859-1" per JSP spec
+ sourceEnc = "ISO-8859-1";
+ isDefaultPageEncoding = true;
+ }
}
}
+
}
- }
-
+
/*
* Determines page source encoding for page or tag file in JSP syntax,
* by reading (in this order) the value of the 'pageEncoding' page
* @return The page encoding, or null if not found
*/
private String getPageEncodingForJspSyntax(JspReader jspReader,
- Mark startMark)
- throws JasperException {
+ Mark startMark)
+ throws JasperException {
- String encoding = null;
+ String encoding = null;
String saveEncoding = null;
jspReader.reset(startMark);
- /*
- * Determine page encoding from directive of the form <%@ page %>,
- * <%@ tag %>, <jsp:directive.page > or <jsp:directive.tag >.
- */
+ /*
+ * Determine page encoding from directive of the form <%@ page %>,
+ * <%@ tag %>, <jsp:directive.page > or <jsp:directive.tag >.
+ */
while (true) {
if (jspReader.skipUntil("<") == null) {
break;
}
boolean isDirective = jspReader.matches("%@");
if (isDirective) {
- jspReader.skipSpaces();
+ jspReader.skipSpaces();
}
else {
isDirective = jspReader.matches("jsp:directive.");
continue;
}
- // compare for "tag ", so we don't match "taglib"
- if (jspReader.matches("tag ") || jspReader.matches("page")) {
+ // compare for "tag ", so we don't match "taglib"
+ if (jspReader.matches("tag ") || jspReader.matches("page")) {
- jspReader.skipSpaces();
+ jspReader.skipSpaces();
Attributes attrs = Parser.parseAttributes(this, jspReader);
- encoding = getPageEncodingFromDirective(attrs, "pageEncoding");
+ encoding = getPageEncodingFromDirective(attrs, "pageEncoding");
if (encoding != null) {
break;
}
- encoding = getPageEncodingFromDirective(attrs, "contentType");
+ encoding = getPageEncodingFromDirective(attrs, "contentType");
if (encoding != null) {
saveEncoding = encoding;
}
- }
- }
+ }
+ }
if (encoding == null) {
encoding = saveEncoding;
}
- return encoding;
+ return encoding;
}
/*
* @return The page encoding, or null
*/
private String getPageEncodingFromDirective(Attributes attrs,
- String attrName) {
- String value = attrs.getValue(attrName);
+ String attrName) {
+ String value = attrs.getValue(attrName);
if (attrName.equals("pageEncoding")) {
return value;
}
String contentType = value;
String encoding = null;
if (contentType != null) {
- int loc = contentType.indexOf(CHARSET);
- if (loc != -1) {
- encoding = contentType.substring(loc + CHARSET.length());
- }
- }
+ int loc = contentType.indexOf(CHARSET);
+ if (loc != -1) {
+ encoding = contentType.substring(loc + CHARSET.length());
+ }
+ }
- return encoding;
+ return encoding;
}
/*
private String resolveFileName(String inFileName) {
String fileName = inFileName.replace('\\', '/');
boolean isAbsolute = fileName.startsWith("/");
- fileName = isAbsolute ? fileName
- : (String) baseDirStack.peek() + fileName;
- String baseDir =
- fileName.substring(0, fileName.lastIndexOf("/") + 1);
- baseDirStack.push(baseDir);
- return fileName;
+ fileName = isAbsolute ? fileName
+ : (String) baseDirStack.peek() + fileName;
+ String baseDir =
+ fileName.substring(0, fileName.lastIndexOf("/") + 1);
+ baseDirStack.push(baseDir);
+ return fileName;
}
/*
*/
private boolean hasJspRoot(JspReader reader) throws JasperException {
- // <prefix>:root must be the first element
- Mark start = null;
- while ((start = reader.skipUntil("<")) != null) {
- int c = reader.nextChar();
- if (c != '!' && c != '?') break;
- }
- if (start == null) {
- return false;
- }
- Mark stop = reader.skipUntil(":root");
- if (stop == null) {
- return false;
- }
- // call substring to get rid of leading '<'
- String prefix = reader.getText(start, stop).substring(1);
-
- start = stop;
- stop = reader.skipUntil(">");
- if (stop == null) {
- return false;
- }
-
- // Determine namespace associated with <root> element's prefix
- String root = reader.getText(start, stop);
- String xmlnsDecl = "xmlns:" + prefix;
- int index = root.indexOf(xmlnsDecl);
- if (index == -1) {
- return false;
- }
- index += xmlnsDecl.length();
- while (index < root.length()
- && Character.isWhitespace(root.charAt(index))) {
- index++;
- }
- if (index < root.length() && root.charAt(index) == '=') {
- index++;
- while (index < root.length()
- && Character.isWhitespace(root.charAt(index))) {
- index++;
- }
- if (index < root.length() && root.charAt(index++) == '"'
- && root.regionMatches(index, JSP_URI, 0,
- JSP_URI.length())) {
- return true;
- }
- }
-
- return false;
+ // <prefix>:root must be the first element
+ Mark start = null;
+ while ((start = reader.skipUntil("<")) != null) {
+ int c = reader.nextChar();
+ if (c != '!' && c != '?') break;
+ }
+ if (start == null) {
+ return false;
+ }
+ Mark stop = reader.skipUntil(":root");
+ if (stop == null) {
+ return false;
+ }
+ // call substring to get rid of leading '<'
+ String prefix = reader.getText(start, stop).substring(1);
+
+ start = stop;
+ stop = reader.skipUntil(">");
+ if (stop == null) {
+ return false;
+ }
+
+ // Determine namespace associated with <root> element's prefix
+ String root = reader.getText(start, stop);
+ String xmlnsDecl = "xmlns:" + prefix;
+ int index = root.indexOf(xmlnsDecl);
+ if (index == -1) {
+ return false;
+ }
+ index += xmlnsDecl.length();
+ while (index < root.length()
+ && Character.isWhitespace(root.charAt(index))) {
+ index++;
+ }
+ if (index < root.length() && root.charAt(index) == '=') {
+ index++;
+ while (index < root.length()
+ && Character.isWhitespace(root.charAt(index))) {
+ index++;
+ }
+ if (index < root.length() && root.charAt(index++) == '"'
+ && root.regionMatches(index, JSP_URI, 0,
+ JSP_URI.length())) {
+ return true;
+ }
+ }
+
+ return false;
}
private JarFile getJarFile(URL jarFileUrl) throws IOException {
- JarFile jarFile = null;
+ JarFile jarFile = null;
- if (jarFileUrl != null) {
- JarURLConnection conn = (JarURLConnection) jarFileUrl.openConnection();
- conn.setUseCaches(false);
- conn.connect();
- jarFile = conn.getJarFile();
- }
+ if (jarFileUrl != null) {
+ JarURLConnection conn = (JarURLConnection) jarFileUrl.openConnection();
+ conn.setUseCaches(false);
+ conn.connect();
+ jarFile = conn.getJarFile();
+ }
- return jarFile;
+ return jarFile;
}
}