luehe 2003/03/24 13:36:05 Modified: jasper2/src/share/org/apache/jasper/compiler Compiler.java JspDocumentParser.java Node.java PageDataImpl.java PageInfo.java Parser.java ParserController.java Validator.java Log: Implemented JSP 2.0 i18n-related spec change: Determine page encoding of included resources in the same fashion as page encoding of top-level page. This means that any included resources are now parsed using their own page encoding, instead of leveraging the page encoding of the top-level page. This also means that the <page-encoding> subelement of <jsp-property-group> no longer applies to an entire translation unit, but individual pages (whose URIs match the property group's URL pattern). Revision Changes Path 1.60 +0 -1 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Compiler.java Index: Compiler.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Compiler.java,v retrieving revision 1.59 retrieving revision 1.60 diff -u -r1.59 -r1.60 --- Compiler.java 19 Mar 2003 20:51:34 -0000 1.59 +++ Compiler.java 24 Mar 2003 21:36:05 -0000 1.60 @@ -213,7 +213,6 @@ pageInfo.setELIgnoredSpecified(true); } pageInfo.setIsXmlConfig(JspUtil.booleanValue(jspProperty.isXml())); - pageInfo.setConfigEncoding(jspProperty.getPageEncoding()); pageInfo.setELIgnored(JspUtil.booleanValue(jspProperty.isELIgnored())); pageInfo.setScriptingInvalid(JspUtil.booleanValue(jspProperty.isScriptingInvalid())); if (jspProperty.getIncludePrelude() != null) { 1.47 +42 -37 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/JspDocumentParser.java Index: JspDocumentParser.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/JspDocumentParser.java,v retrieving revision 1.46 retrieving revision 1.47 diff -u -r1.46 -r1.47 --- JspDocumentParser.java 1 Mar 2003 02:07:52 -0000 1.46 +++ JspDocumentParser.java 24 Mar 2003 21:36:05 -0000 1.47 @@ -144,34 +144,39 @@ InputStream inStream, Node parent, boolean isTagFile, - boolean directivesOnly) + boolean directivesOnly, + String pageEnc, + String jspConfigPageEnc) throws JasperException { - JspDocumentParser handler = new JspDocumentParser(pc, path, inStream, - isTagFile, - directivesOnly); + JspDocumentParser jspDocParser = new JspDocumentParser(pc, path, + inStream, + isTagFile, + directivesOnly); + // It's an error to have a prelude or a coda associated with // a JSP document - if (!handler.pageInfo.getIncludePrelude().isEmpty()) { - String file = (String) handler.pageInfo.getIncludePrelude().get(0); - handler.err.jspError("jsp.error.prelude.xml", path, file); - } - if (!handler.pageInfo.getIncludeCoda().isEmpty()) { - String file = (String) handler.pageInfo.getIncludeCoda().get(0); - handler.err.jspError("jsp.error.coda.xml", path, file); + if (!jspDocParser.pageInfo.getIncludePrelude().isEmpty()) { + String file = (String) jspDocParser.pageInfo.getIncludePrelude().get(0); + jspDocParser.err.jspError("jsp.error.prelude.xml", path, file); + } + if (!jspDocParser.pageInfo.getIncludeCoda().isEmpty()) { + String file = (String) jspDocParser.pageInfo.getIncludeCoda().get(0); + jspDocParser.err.jspError("jsp.error.coda.xml", path, file); } Node.Nodes pageNodes = null; - Node.Root jspRoot = null; try { - if (parent == null) { - // create dummy <jsp:root> element - jspRoot = new Node.Root(true); - handler.current = jspRoot; - } else { - handler.isTop = false; - handler.current = parent; + + // 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); + jspDocParser.current = dummyRoot; + + if (parent != null) { + jspDocParser.isTop = false; } // Use the default (non-validating) parser @@ -184,22 +189,19 @@ // Configure the parser SAXParser saxParser = factory.newSAXParser(); XMLReader xmlReader = saxParser.getXMLReader(); - xmlReader.setProperty(LEXICAL_HANDLER_PROPERTY, handler); - xmlReader.setErrorHandler(handler); + xmlReader.setProperty(LEXICAL_HANDLER_PROPERTY, jspDocParser); + xmlReader.setErrorHandler(jspDocParser); // Parse the input - saxParser.parse(handler.inputSource, handler); + saxParser.parse(jspDocParser.inputSource, jspDocParser); + + // Create Node.Nodes from dummy root + pageNodes = new Node.Nodes(dummyRoot); - if (parent == null) { - // Create Node.Nodes from dummy (top-level) <jsp:root> - pageNodes = new Node.Nodes(jspRoot); - } else { - pageNodes = parent.getBody(); - } } catch (IOException ioe) { - handler.err.jspError("jsp.error.data.file.read", path, ioe); + jspDocParser.err.jspError("jsp.error.data.file.read", path, ioe); } catch (Exception e) { - handler.err.jspError(e); + jspDocParser.err.jspError(e); } return pageNodes; @@ -812,10 +814,13 @@ } /* - * Parses the given file that is being specified in the given include - * directive. + * Parses the given file included via an include directive. + * + * @param fname The path to the included resource, as specified by the + * 'file' attribute of the include directive + * @param parent The Node representing the include directive */ - private void processIncludeDirective(String fname, Node includeDir) + private void processIncludeDirective(String fname, Node parent) throws SAXException { if (fname == null) { @@ -823,7 +828,7 @@ } try { - parserController.parse(fname, includeDir, null); + parserController.parse(fname, parent, null); } catch (FileNotFoundException fnfe) { throw new SAXParseException( Localizer.getMessage("jsp.error.file.not.found", fname), 1.67 +40 -29 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Node.java Index: Node.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Node.java,v retrieving revision 1.66 retrieving revision 1.67 diff -u -r1.66 -r1.67 --- Node.java 19 Mar 2003 20:51:34 -0000 1.66 +++ Node.java 24 Mar 2003 21:36:05 -0000 1.67 @@ -342,18 +342,12 @@ return isDummy; } - /** - * @return true if the current page is in xml syntax, false otherwise. - */ - public boolean isXmlSyntax() { - Node r = this; - while (!(r instanceof Node.Root)) { - r = r.getParent(); - if (r == null) - return false; + public Node.Root getRoot() { + Node n = this; + while (!(n instanceof Node.Root)) { + n = n.getParent(); } - - return r.isXmlSyntax(); + return (Node.Root) n; } /** @@ -395,14 +389,11 @@ private Root parentRoot; private boolean isXmlSyntax; - /* - * Constructor for dummy root. - */ - Root(boolean isXmlSyntax) { - this.isXmlSyntax = isXmlSyntax; - this.qName = JSP_ROOT_ACTION; - this.localName = ROOT_ACTION; - } + // Source encoding of the page containing this Root + private String pageEnc; + + // Page encoding specified in JSP config element + private String jspConfigPageEnc; /* * Constructor. @@ -428,8 +419,32 @@ return isXmlSyntax; } + /* + * Sets the encoding specified in the JSP config element whose URL + * pattern matches the page containing this Root. + */ + public void setJspConfigPageEncoding(String enc) { + jspConfigPageEnc = enc; + } + + /* + * Gets the encoding specified in the JSP config element whose URL + * pattern matches the page containing this Root. + */ + public String getJspConfigPageEncoding() { + return jspConfigPageEnc; + } + + public void setPageEncoding(String enc) { + pageEnc = enc; + } + + public String getPageEncoding() { + return pageEnc; + } + /** - * @return The enclosing root to this root. Usually represents the + * @return The enclosing root to this Root. Usually represents the * page that includes this one. */ public Root getParentRoot() { @@ -440,15 +455,11 @@ /** * Represents the root of a Jsp document (XML syntax) */ - public static class JspRoot extends Root { + public static class JspRoot extends Node { public JspRoot(String qName, Attributes attrs, Attributes xmlnsAttrs, Mark start, Node parent) { - super(start, parent, true); - this.qName = qName; - this.localName = ROOT_ACTION; - this.attrs = attrs; - this.xmlnsAttrs = xmlnsAttrs; + super(qName, ROOT_ACTION, attrs, xmlnsAttrs, start, parent); } public void accept(Visitor v) throws JasperException { 1.25 +6 -6 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/PageDataImpl.java Index: PageDataImpl.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/PageDataImpl.java,v retrieving revision 1.24 retrieving revision 1.25 diff -u -r1.24 -r1.25 --- PageDataImpl.java 26 Feb 2003 22:58:16 -0000 1.24 +++ PageDataImpl.java 24 Mar 2003 21:36:05 -0000 1.25 @@ -293,7 +293,7 @@ } public void visit(Node.ELExpression n) throws JasperException { - if (!n.isXmlSyntax()) { + if (!n.getRoot().isXmlSyntax()) { buf.append("<").append(JSP_TEXT_ACTION); buf.append(" jsp:id=\""); buf.append(jspId++).append("\">"); @@ -301,7 +301,7 @@ buf.append("${"); buf.append(n.getText()); buf.append("}"); - if (!n.isXmlSyntax()) { + if (!n.getRoot().isXmlSyntax()) { buf.append(JSP_TEXT_ACTION_END); } buf.append("\n"); @@ -388,7 +388,7 @@ * If the template text came from a JSP page written in JSP syntax, * create a jsp:text element for it (JSP 5.3.2). */ - appendText(n.getText(), !n.isXmlSyntax()); + appendText(n.getText(), !n.getRoot().isXmlSyntax()); } /* 1.26 +3 -31 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/PageInfo.java Index: PageInfo.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/PageInfo.java,v retrieving revision 1.25 retrieving revision 1.26 diff -u -r1.25 -r1.26 --- PageInfo.java 19 Mar 2003 20:51:35 -0000 1.25 +++ PageInfo.java 24 Mar 2003 21:36:05 -0000 1.26 @@ -88,10 +88,6 @@ private boolean threadSafe = true; private boolean isErrorPage = false; private String errorPage = null; - private String pageEncoding = null; - - // Encoding specified in JSP config element - private String configEncoding; /* * Indicates whether an encoding has been explicitly specified in the @@ -258,36 +254,12 @@ this.isErrorPage = isErrorPage; } - public void setPageEncoding(String pageEncoding) { - this.pageEncoding = pageEncoding; - } - - public String getPageEncoding() { - return pageEncoding; - } - public void setIsEncodingSpecifiedInProlog(boolean isSpecified) { this.isEncodingSpecifiedInProlog = isSpecified; } public boolean isEncodingSpecifiedInProlog() { return this.isEncodingSpecifiedInProlog; - } - - /* - * Sets the encoding specified in the JSP config element whose URL pattern - * matches this page. - */ - public void setConfigEncoding(String enc) { - this.configEncoding = enc; - } - - /* - * Gets the encoding specified in the JSP config element whose URL pattern - * matches this page. - */ - public String getConfigEncoding() { - return this.configEncoding; } public int getMaxTagNesting() { 1.69 +8 -4 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Parser.java Index: Parser.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Parser.java,v retrieving revision 1.68 retrieving revision 1.69 diff -u -r1.68 -r1.69 --- Parser.java 1 Mar 2003 02:07:52 -0000 1.68 +++ Parser.java 24 Mar 2003 21:36:05 -0000 1.69 @@ -144,13 +144,17 @@ Node parent, boolean isTagFile, boolean directivesOnly, - JarFile jarFile) + JarFile jarFile, + String pageEnc, + String jspConfigPageEnc) throws JasperException { Parser parser = new Parser(pc, reader, isTagFile, directivesOnly, jarFile); Node.Root root = new Node.Root(reader.mark(), parent, false); + root.setPageEncoding(pageEnc); + root.setJspConfigPageEncoding(jspConfigPageEnc); if (directivesOnly) { parser.parseTagFileDirectives(root); 1.35 +51 -43 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/ParserController.java Index: ParserController.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/ParserController.java,v retrieving revision 1.34 retrieving revision 1.35 diff -u -r1.34 -r1.35 --- ParserController.java 26 Feb 2003 22:58:16 -0000 1.34 +++ ParserController.java 24 Mar 2003 21:36:05 -0000 1.35 @@ -103,8 +103,8 @@ private static final String JSP_ROOT_TAG = "<jsp:root"; /* - * Tells if the file being processed is the "top" file - * in the translation unit. + * Tells if the file being processed is the "top" file in the translation + * unit. */ private boolean isTopFile = true; @@ -194,9 +194,12 @@ Node.Nodes parsedPage = null; String absFileName = resolveFileName(inFileName); + String jspConfigPageEnc = getJspConfigPageEncoding(absFileName); + // Figure out what type of JSP document and encoding type we are // dealing with - figureOutJspDocument(absFileName, jarFile); + determineSyntaxAndEncoding(absFileName, jarFile, + jspConfigPageEnc); if (isTopFile) { if (isXml && pageInfo.isEncodingSpecifiedInProlog()) { @@ -206,7 +209,6 @@ * (if any), treating "UTF-16", "UTF-16BE", and "UTF-16LE" as * identical. */ - String jspConfigPageEnc = pageInfo.getConfigEncoding(); if (jspConfigPageEnc != null && !jspConfigPageEnc.equals(sourceEnc) && (!jspConfigPageEnc.startsWith("UTF-16") @@ -215,7 +217,6 @@ sourceEnc, jspConfigPageEnc); } } - pageInfo.setPageEncoding(sourceEnc); isTopFile = false; } else { compiler.getPageInfo().addDependant(absFileName); @@ -226,21 +227,13 @@ // JSP document (XML syntax) InputStream inStream = null; try { - // XXX Files included using the include directive must be read - // using the character encoding of the including page. - // However, I am wondering how to implement this if an - // included JSP document contains its own XML prolog. Since - // we're handing the included JSP document off to the XML - // (e.g., SAX) parser, we have no control over how it's parsed: - // the parser will determine the encoding from the XML prolog - // on its own, and use it. We can't tell the parser to use - // a different encoding. inStream = JspUtil.getInputStream(absFileName, jarFile, ctxt, err); parsedPage = JspDocumentParser.parse(this, absFileName, inStream, parent, - isTagFile, - directivesOnly); + isTagFile, directivesOnly, + sourceEnc, + jspConfigPageEnc); } finally { if (inStream != null) { try { @@ -253,21 +246,14 @@ // Standard syntax InputStreamReader inStreamReader = null; try { - // Files included using the include directive must be read - // using the character encoding of the including page, which is - // the encoding returned by pageInfo.getPageEncoding(). - inStreamReader = JspUtil.getReader(absFileName, - pageInfo.getPageEncoding(), - jarFile, - ctxt, - err); - JspReader jspReader = new JspReader(ctxt, - absFileName, - pageInfo.getPageEncoding(), - inStreamReader, + inStreamReader = JspUtil.getReader(absFileName, sourceEnc, + jarFile, ctxt, err); + JspReader jspReader = new JspReader(ctxt, absFileName, + sourceEnc, inStreamReader, err); parsedPage = Parser.parse(this, jspReader, parent, isTagFile, - directivesOnly, jarFile); + directivesOnly, jarFile, sourceEnc, + jspConfigPageEnc); } finally { if (inStreamReader != null) { try { @@ -283,6 +269,25 @@ return parsedPage; } + /* + * Checks to see if the given URI is matched by a URL pattern specified in + * a jsp-property-group in web.xml, and if so, returns the value of the + * <page-encoding> element. + * + * @param absFileName The URI to match + * + * @return The value of the <page-encoding> attribute of the + * jsp-property-group with matching URL pattern + */ + private String getJspConfigPageEncoding(String absFileName) + throws JasperException { + + JspConfig jspConfig = ctxt.getOptions().getJspConfig(); + JspConfig.JspProperty jspProperty + = jspConfig.findJspProperty(absFileName); + return jspProperty.getPageEncoding(); + } + /** * Determines the properties of the given page or tag file. * The properties to be determined are: @@ -298,16 +303,19 @@ * If these properties are already specified in the jsp-config element * in web.xml, then they are used. */ - private void figureOutJspDocument(String fname, JarFile jarFile) + private void determineSyntaxAndEncoding(String absFileName, + JarFile jarFile, + String jspConfigPageEnc) throws JasperException, IOException { + isXml = false; + /* * 'true' if the syntax of the page (XML or standard) is identified by * external information: either via a JSP configuration element or * the ".jspx" suffix */ boolean isExternal = false; - isXml = false; /* * Indicates whether we need to revert from temporary usage of @@ -319,7 +327,8 @@ // If <is-xml> is specified in a <jsp-property-group>, it is used. isXml = pageInfo.isXmlConfig(); isExternal = true; - } else if (fname.endsWith(".jspx") || fname.endsWith(".tagx")) { + } else if (absFileName.endsWith(".jspx") + || absFileName.endsWith(".tagx")) { isXml = true; isExternal = true; } @@ -327,7 +336,7 @@ if (isExternal && !isXml) { // JSP (standard) syntax. Use encoding specified in jsp-config // if provided. - sourceEnc = pageInfo.getConfigEncoding(); + sourceEnc = jspConfigPageEnc; if (sourceEnc != null) { return; } @@ -335,8 +344,8 @@ sourceEnc = "ISO-8859-1"; } else { // XML syntax or unknown, (auto)detect encoding ... - Object[] ret = XMLEncodingDetector.getEncoding(fname, jarFile, - ctxt, err); + Object[] ret = XMLEncodingDetector.getEncoding(absFileName, + jarFile, ctxt, err); sourceEnc = (String) ret[0]; if (((Boolean) ret[1]).booleanValue()) { pageInfo.setIsEncodingSpecifiedInProlog(true); @@ -382,7 +391,8 @@ */ JspReader jspReader = null; try { - jspReader = new JspReader(ctxt, fname, sourceEnc, jarFile, err); + jspReader = new JspReader(ctxt, absFileName, sourceEnc, jarFile, + err); } catch (FileNotFoundException ex) { throw new JasperException(ex); } @@ -407,7 +417,7 @@ * Determine the page encoding from the page directive, unless it's * specified via JSP config. */ - sourceEnc = pageInfo.getConfigEncoding(); + sourceEnc = jspConfigPageEnc; if (sourceEnc == null) { sourceEnc = getSourceEncodingForJspSyntax(jspReader, startMark); } @@ -456,12 +466,10 @@ } /* - * Resolve the name of the file and update - * baseDirStack() to keep track ot the current - * base directory for each included file. - * The 'root' file is always an 'absolute' path, - * so no need to put an initial value in the - * baseDirStack. + * Resolve the name of the file and update baseDirStack() to keep track of + * the current base directory for each included file. + * The 'root' file is always an 'absolute' path, so no need to put an + * initial value in the baseDirStack. */ private String resolveFileName(String inFileName) { String fileName = inFileName.replace('\\', '/'); 1.94 +24 -21 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Validator.java Index: Validator.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Validator.java,v retrieving revision 1.93 retrieving revision 1.94 diff -u -r1.93 -r1.94 --- Validator.java 21 Mar 2003 03:18:38 -0000 1.93 +++ Validator.java 24 Mar 2003 21:36:05 -0000 1.94 @@ -255,7 +255,7 @@ * Report any encoding conflict, treating "UTF-16", * "UTF-16BE", and "UTF-16LE" as identical. */ - compareEncodings(value, n, pageInfo); + comparePageEncodings(value, n, pageInfo); } } @@ -301,7 +301,7 @@ if (pageEncodingSeen) err.jspError(n, "jsp.error.page.multiple.pageencoding"); pageEncodingSeen = true; - pageInfo.setPageEncoding(value); + n.getRoot().setPageEncoding(value); } } @@ -323,17 +323,19 @@ } /* - * Compares the encoding specified in the 'pageEncoding' attribute of - * the page directive with the encoding explicitly specified in the - * XML prolog (only for XML syntax) and the encoding specified in - * the JSP config element whose URL pattern matches the page, and - * throws an error in case of a mismatch. + * Compares the page encoding specified in the 'pageEncoding' + * attribute of the page directive with the encoding explicitly + * specified in the XML prolog (only for XML syntax) and the encoding + * specified in the JSP config element whose URL pattern matches the + * page, and throws an error in case of a mismatch. */ - private void compareEncodings(String pageDirEnc, Node n, - PageInfo pageInfo) + private void comparePageEncodings(String pageDirEnc, + Node.PageDirective n, + PageInfo pageInfo) throws JasperException { - String configEnc = pageInfo.getConfigEncoding(); + String configEnc = n.getRoot().getJspConfigPageEncoding(); + if (configEnc != null && !pageDirEnc.equals(configEnc) && (!pageDirEnc.startsWith("UTF-16") || !configEnc.startsWith("UTF-16"))) { @@ -341,8 +343,9 @@ configEnc, pageDirEnc); } - if (n.isXmlSyntax() && pageInfo.isEncodingSpecifiedInProlog()) { - String pageEnc = pageInfo.getPageEncoding(); + if (n.getRoot().isXmlSyntax() + && pageInfo.isEncodingSpecifiedInProlog()) { + String pageEnc = n.getRoot().getPageEncoding(); if (!pageDirEnc.equals(pageEnc) && (!pageDirEnc.startsWith("UTF-16") || !pageEnc.startsWith("UTF-16"))) { @@ -1053,7 +1056,7 @@ // valid attribute value in xml). if (value != null) { - if (n.isXmlSyntax() && value.startsWith("%=")) { + if (n.getRoot().isXmlSyntax() && value.startsWith("%=")) { result = new Node.JspAttribute( qName, uri, @@ -1063,7 +1066,7 @@ null, dynamic); } - else if(!n.isXmlSyntax() && value.startsWith("<%=")) { + else if(!n.getRoot().isXmlSyntax() && value.startsWith("<%=")) { result = new Node.JspAttribute( qName, uri, @@ -1125,8 +1128,8 @@ * EL expression. */ private boolean isExpression(Node n, String value) { - if ((n.isXmlSyntax() && value.startsWith("%=")) - || (!n.isXmlSyntax() && value.startsWith("<%=")) + if ((n.getRoot().isXmlSyntax() && value.startsWith("%=")) + || (!n.getRoot().isXmlSyntax() && value.startsWith("<%=")) || (value.indexOf("${") != -1 && !pageInfo.isELIgnored())) return true; else @@ -1208,7 +1211,7 @@ String function = func.getName(); String uri = null; - if (n.isXmlSyntax()) { + if (n.getRoot().isXmlSyntax()) { uri = findUri(prefix, n); } else if (prefix != null) { Hashtable prefixMapper = pageInfo.getPrefixMapper(); @@ -1314,7 +1317,7 @@ if (isXml) { charset = "UTF-8"; } else { - charset = pageInfo.getPageEncoding(); + charset = page.getRoot().getPageEncoding(); // The resulting charset might be null }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]