--- java/org/apache/jasper/JspC.java (revision 712265) +++ java/org/apache/jasper/JspC.java (working copy) @@ -139,7 +139,7 @@ protected static int die; protected String classPath = null; protected URLClassLoader loader = null; - protected boolean trimSpaces = false; + protected TrimSpacesOption trimSpaces = TrimSpacesOption.FALSE; protected boolean genStringAsCharArray = false; protected boolean xpoweredBy; protected boolean mappedFile = false; @@ -297,7 +297,13 @@ } else if (tok.equals(SWITCH_XPOWERED_BY)) { xpoweredBy = true; } else if (tok.equals(SWITCH_TRIM_SPACES)) { - setTrimSpaces(true); + tok = nextArg(); + if (TrimSpacesOption.SINGLE.toString().equalsIgnoreCase(tok)) { + setTrimSpaces(TrimSpacesOption.SINGLE); + } else { + setTrimSpaces(TrimSpacesOption.TRUE); + argPos--; + } } else if (tok.equals(SWITCH_CACHE)) { tok = nextArg(); if ("false".equals(tok)) { @@ -362,14 +368,18 @@ return true; } - public boolean getTrimSpaces() { + public TrimSpacesOption getTrimSpaces() { return trimSpaces; } - public void setTrimSpaces(boolean ts) { + public void setTrimSpaces(TrimSpacesOption ts) { this.trimSpaces = ts; } + public void setTrimSpaces(String ts) { + this.trimSpaces = TrimSpacesOption.fromString(ts); + } + public boolean isPoolingEnabled() { return poolingEnabled; } --- java/org/apache/jasper/EmbeddedServletOptions.java (revision 712265) +++ java/org/apache/jasper/EmbeddedServletOptions.java (working copy) @@ -61,9 +61,10 @@ private boolean keepGenerated = true; /** - * Should white spaces between directives or actions be trimmed? + * Should white spaces between directives or actions be trimmed and if so, + * to nothing (per Section JSP.3.3.8) or to a single space? */ - private boolean trimSpaces = false; + private TrimSpacesOption trimSpaces = TrimSpacesOption.FALSE; /** * Determines whether tag handler pooling is enabled. @@ -198,9 +199,10 @@ } /** - * Should white spaces between directives or actions be trimmed? + * Should white spaces between directives or actions be trimmed and if so, + * to nothing (per Section JSP.3.3.8) or to a single space? */ - public boolean getTrimSpaces() { + public TrimSpacesOption getTrimSpaces() { return trimSpaces; } @@ -423,11 +425,8 @@ String trimsp = config.getInitParameter("trimSpaces"); if (trimsp != null) { - if (trimsp.equalsIgnoreCase("true")) { - trimSpaces = true; - } else if (trimsp.equalsIgnoreCase("false")) { - trimSpaces = false; - } else { + trimSpaces = TrimSpacesOption.fromString(trimsp); + if (!trimSpaces.toString().equalsIgnoreCase(trimsp)) { if (log.isWarnEnabled()) { log.warn(Localizer.getMessage("jsp.warning.trimspaces")); } --- java/org/apache/jasper/compiler/TextOptimizer.java (revision 712265) +++ java/org/apache/jasper/compiler/TextOptimizer.java (working copy) @@ -34,6 +34,7 @@ private Node.TemplateText firstTextNode = null; private StringBuffer textBuffer; private final String emptyText = new String(""); + private final String singleText = new String(" "); public TextCatVisitor(Compiler compiler) { options = compiler.getCompilationContext().getOptions(); @@ -72,9 +73,13 @@ } public void visit(Node.TemplateText n) throws JasperException { - if ((options.getTrimSpaces() || pageInfo.isTrimDirectiveWhitespaces()) + if ((!Options.TrimSpacesOption.FALSE.equals(options.getTrimSpaces()) + || pageInfo.isTrimDirectiveWhitespaces()) && n.isAllSpace()) { - n.setText(emptyText); + switch (options.getTrimSpaces()) { + case SINGLE: n.setText(singleText); break; + default: n.setText(emptyText); + } return; } --- java/org/apache/jasper/resources/LocalStrings.properties (revision 712265) +++ java/org/apache/jasper/resources/LocalStrings.properties (working copy) @@ -236,28 +236,29 @@ or any number of\n\ \ A file to be parsed as a JSP page\n\ where options include:\n\ -\ -help Print this help message\n\ -\ -v Verbose mode\n\ -\ -d Output Directory (default -Djava.io.tmpdir)\n\ -\ -l Outputs the name of the JSP page upon failure\n\ -\ -s Outputs the name of the JSP page upon success\n\ -\ -p Name of target package (default org.apache.jsp)\n\ -\ -c Name of target class name (only applies to first JSP page)\n\ -\ -mapped Generates separate write() calls for each HTML line in the JSP\n\ -\ -die[#] Generates an error return code (#) on fatal errors (default 1)\n\ -\ -uribase The uri directory compilations should be relative to\n\ -\ (default "/")\n\ -\ -uriroot Same as -webapp\n\ -\ -compile Compiles generated servlets\n\ -\ -webinc Creates a partial servlet mappings in the file\n\ -\ -webxml Creates a complete web.xml in the file\n\ -\ -ieplugin Java Plugin classid for Internet Explorer\n\ -\ -classpath Overrides java.class.path system property\n\ -\ -xpoweredBy Add X-Powered-By response header\n\ -\ -trimSpaces Trim spaces in template text between actions, directives\n\ -\ -javaEncoding Set the encoding charset for Java classes (default UTF-8)\n\ -\ -source Set the -source argument to the compiler (default 1.4)\n\ -\ -target Set the -target argument to the compiler (default 1.4)\n\ +\ -help Print this help message\n\ +\ -v Verbose mode\n\ +\ -d Output Directory (default -Djava.io.tmpdir)\n\ +\ -l Outputs the name of the JSP page upon failure\n\ +\ -s Outputs the name of the JSP page upon success\n\ +\ -p Name of target package (default org.apache.jsp)\n\ +\ -c Name of target class name (only applies to first JSP page)\n\ +\ -mapped Generates separate write() calls for each HTML line in the JSP\n\ +\ -die[#] Generates an error return code (#) on fatal errors (default 1)\n\ +\ -uribase The uri directory compilations should be relative to\n\ +\ (default "/")\n\ +\ -uriroot Same as -webapp\n\ +\ -compile Compiles generated servlets\n\ +\ -webinc Creates a partial servlet mappings in the file\n\ +\ -webxml Creates a complete web.xml in the file\n\ +\ -ieplugin Java Plugin classid for Internet Explorer\n\ +\ -classpath Overrides java.class.path system property\n\ +\ -xpoweredBy Add X-Powered-By response header\n\ +\ -trimSpaces [single] Trim spaces in template text between actions, directives\n\ +\ (if "single", whitespace trimmed to single space)\n\ +\ -javaEncoding Set the encoding charset for Java classes (default UTF-8)\n\ +\ -source Set the -source argument to the compiler (default 1.4)\n\ +\ -target Set the -target argument to the compiler (default 1.4)\n\ jspc.webxml.header=\n\ \n\ --- java/org/apache/jasper/resources/LocalStrings_es.properties (revision 712265) +++ java/org/apache/jasper/resources/LocalStrings_es.properties (working copy) @@ -254,7 +254,8 @@ \ -ieplugin Java Plugin classid para Internet Explorer\n\ \ -classpath Pasa por alto la propiedad de sistema java.class.path\n\ \ -xpoweredBy A\u00F1ade cabecera de respuesta X-Powered-By\n\ - \ -trimSpaces Trim spaces in template text between actions, directives\n\ + \ -trimSpaces [single] Trim spaces in template text between actions, directives\n\ + \ (if "single", whitespace trimmed to single space)\n\ \ -javaEncoding Set the encoding charset for Java classes (default UTF-8)\n\ \ -source Set the -source argument to the compiler (default 1.4)\n\ \ -target Set the -target argument to the compiler (default 1.4)\n --- java/org/apache/jasper/resources/LocalStrings_fr.properties (revision 712265) +++ java/org/apache/jasper/resources/LocalStrings_fr.properties (working copy) @@ -196,7 +196,8 @@ \ -webxml Création d''un fichier web.xml complet pour l''option -webapp.\n\ \ -ieplugin Le classid du Plugin Java Plugin pour Internet Explorer\n\ \ -sax2 Le nom de classe du Driver SAX 2.0 à utiliser\n\ -\ -trimSpaces Trim spaces in template text between actions, directives\n\ +\ -trimSpaces [single] Trim spaces in template text between actions, directives\n\ +\ (if "single", whitespace trimmed to single space)\n\ \ -javaEncoding Set the encoding charset for Java classes (default UTF-8)\n\ \ -source Set the -source argument to the compiler (default 1.4)\n\ \ -target Set the -target argument to the compiler (default 1.4)\n\ --- java/org/apache/jasper/resources/LocalStrings_ja.properties (revision 712265) +++ java/org/apache/jasper/resources/LocalStrings_ja.properties (working copy) @@ -238,8 +238,9 @@ \ -ieplugin Internet Explorer\u306eJava Plugin\u306eclassid\n\ \ -classpath java.class.path\u30b7\u30b9\u30c6\u30e0\u30d7\u30ed\u30d1\u30c6\u30a3\u306e\u4e0a\u66f8\u304d\n\ \ -xpoweredBy X-Powered-By\u30ec\u30b9\u30dd\u30f3\u30b9\u30d8\u30c3\u30c0\u306e\u8ffd\u52a0\n\ -\ -trimSpaces \u30a2\u30af\u30b7\u30e7\u30f3\u3084\u6307\u793a\u5b50\u306e\u9593\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u30c6\u30ad\u30b9\u30c8\u4e2d\u306e\u30b9\u30da\u30fc\u30b9\u3092\u524a\u9664\n\ -\ -trimSpaces Trim spaces in template text between actions, directives\n\ +\ -trimSpaces [single] \u30a2\u30af\u30b7\u30e7\u30f3\u3084\u6307\u793a\u5b50\u306e\u9593\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u30c6\u30ad\u30b9\u30c8\u4e2d\u306e\u30b9\u30da\u30fc\u30b9\u3092\u524a\u9664\n\ +\ -trimSpaces [single] Trim spaces in template text between actions, directives\n\ +\ (if "single", whitespace trimmed to single space)\n\ \ -javaEncoding Set the encoding charset for Java classes (default UTF-8)\n\ \ -source Set the -source argument to the compiler (default 1.4)\n\ \ -target Set the -target argument to the compiler (default 1.4)\n\ --- java/org/apache/jasper/Options.java (revision 712265) +++ java/org/apache/jasper/Options.java (working copy) @@ -96,11 +96,53 @@ public boolean isSmapDumped(); /** - * Should white spaces between directives or actions be trimmed? + * Possible values for trimSpaces */ - public boolean getTrimSpaces(); + public enum TrimSpacesOption { + FALSE ("false"), + TRUE ("true"), + SINGLE ("single"); + private String value; + + TrimSpacesOption(String value) { + this.value = value; + } + + /** + * Get the enum value from the option string + */ + public static TrimSpacesOption fromString(String value) { + if (value == null) { + return FALSE; + } + + value = value.toLowerCase().trim(); + + if ("true".equals(value)) { + return TRUE; + } else if ("single".equals(value)) { + return SINGLE; + } else { + return FALSE; + } + } + + /** + * Return the option string value + */ + public String toString() { + return this.value; + } + } + /** + * Should white spaces between directives or actions be trimmed and if so, + * to nothing (per Section JSP.3.3.8) or to a single space? + */ + public TrimSpacesOption getTrimSpaces(); + + /** * Class ID for use in the plugin tag when the browser is IE. */ public String getIeClassId();