sylvain 01/10/22 06:14:06 Modified: . changes.xml src/org/apache/cocoon/components/language/markup/sitemap/java sitemap.xsl src/org/apache/cocoon/sitemap XSLTFactoryLoader.java webapp sitemap.xmap Log: - sitemap substitution on matcher patterns is possible even for PreparableMatchers. In that case, the matcher behaves like a regular matcher - if a '{' is part of the pattern, sitemap substitution can be escaped with a '\' before '{' Revision Changes Path 1.44 +3 -1 xml-cocoon2/changes.xml Index: changes.xml =================================================================== RCS file: /home/cvs/xml-cocoon2/changes.xml,v retrieving revision 1.43 retrieving revision 1.44 diff -u -r1.43 -r1.44 --- changes.xml 2001/10/22 10:17:45 1.43 +++ changes.xml 2001/10/22 13:14:06 1.44 @@ -4,7 +4,7 @@ <!-- History of Cocoon changes - $Id: changes.xml,v 1.43 2001/10/22 10:17:45 sylvain Exp $ + $Id: changes.xml,v 1.44 2001/10/22 13:14:06 sylvain Exp $ --> <changes title="History of Changes"> @@ -30,6 +30,8 @@ Deprecation of CodeFactory in preparation of the tree traversal implementation of the sitemap. All factory-based matchers have been rewritten using the new PreparableMatcher interface, and all factory-based selectors have been rewritten as regular implementations of Selector. + For patterns whose syntax uses '{' like regexp, sitemap substitution can be avoided by escaping the + brace character (example : "pat\{2}ern" will match "pattern"). </action> <action dev="SW" type="fix"> Reduce exception nesting in case of sitemap setup errors, and display all nested exceptions 1.46 +26 -19 xml-cocoon2/src/org/apache/cocoon/components/language/markup/sitemap/java/sitemap.xsl Index: sitemap.xsl =================================================================== RCS file: /home/cvs/xml-cocoon2/src/org/apache/cocoon/components/language/markup/sitemap/java/sitemap.xsl,v retrieving revision 1.45 retrieving revision 1.46 diff -u -r1.45 -r1.46 --- sitemap.xsl 2001/10/22 10:17:45 1.45 +++ sitemap.xsl 2001/10/22 13:14:06 1.46 @@ -125,7 +125,7 @@ * * @author <a href="mailto:[EMAIL PROTECTED]">Giacomo Pati</a> * @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a> - * @version CVS $Id: sitemap.xsl,v 1.45 2001/10/22 10:17:45 sylvain Exp $ + * @version CVS $Id: sitemap.xsl,v 1.46 2001/10/22 13:14:06 sylvain Exp $ */ public class <xsl:value-of select="@file-name"/> extends AbstractSitemap { static final String LOCATION = "<xsl:value-of select="translate(@file-path, '/', '.')"/>.<xsl:value-of select="@file-name"/>"; @@ -238,13 +238,13 @@ /** * Method that handles non-factory matchers. */ - private Map matches(String hint, Object patternValue, List listOfMaps, Parameters params, Map objectModel) throws Exception { + private Map matches(String hint, Object preparedPattern, String pattern, List listOfMaps, Parameters params, Map objectModel) throws Exception { Component matcher = (Component)this.matchers.select(hint); try { - if (matcher instanceof PreparableMatcher) { - return ((PreparableMatcher)matcher).preparedMatch(patternValue, objectModel, params); + if (preparedPattern == null) { + return ((Matcher)matcher).match(substitute(listOfMaps, pattern), objectModel, params); } else { - return ((Matcher)matcher).match(substitute(listOfMaps, (String)patternValue), objectModel, params); + return ((PreparableMatcher)matcher).preparedMatch(preparedPattern, objectModel, params); } } finally { this.matchers.release(matcher); @@ -373,11 +373,11 @@ Component matcher = this.matchers.select(type); try { if (matcher instanceof PreparableMatcher) { - // Prepare pattern + // Prepare pattern ('{' have been unescaped) return ((PreparableMatcher)matcher).preparePattern(pattern); } else { - // Return pattern unchanged - return pattern; + // Return null : regular Matcher will be used. + return null; } } finally { this.matchers.release(matcher); @@ -400,14 +400,21 @@ <xsl:variable name="src" select="/map:sitemap/map:components/map:matchers/map:matcher[@name=string($matcher-type)]/@src"/> <xsl:if test="not(XSLTFactoryLoader:isFactory($factory-loader, string($src)))"> - <xsl:variable name="matcher-name"> - <xsl:call-template name="generate-name"> - <xsl:with-param name="prefix">matcher_</xsl:with-param> - <xsl:with-param name="suffix"><xsl:value-of select="$matcher-type"/>_<xsl:value-of select="generate-id(.)"/></xsl:with-param> - </xsl:call-template> - </xsl:variable> - // Prepare the pattern for "<xsl:value-of select="@pattern"/>" - this.<xsl:value-of select="$matcher-name"/>_expr = this.preparePattern("<xsl:value-of select="$matcher-type"/>", "<xsl:value-of select="XSLTFactoryLoader:escape($factory-loader, @pattern)"/>"); + <xsl:choose> + <xsl:when test="XSLTFactoryLoader:hasSubstitutions(@pattern)"> + // Pattern "<xsl:value-of select="@pattern"/>" has substitutions and is not prepared. + </xsl:when> + <xsl:otherwise> + <xsl:variable name="matcher-name"> + <xsl:call-template name="generate-name"> + <xsl:with-param name="prefix">matcher_</xsl:with-param> + <xsl:with-param name="suffix"><xsl:value-of select="$matcher-type"/>_<xsl:value-of select="generate-id(.)"/></xsl:with-param> + </xsl:call-template> + </xsl:variable> + // Prepare the pattern for "<xsl:value-of select="@pattern"/>" + this.<xsl:value-of select="$matcher-name"/>_expr = this.preparePattern("<xsl:value-of select="$matcher-type"/>", "<xsl:value-of select="XSLTFactoryLoader:escapeBraces($factory-loader, @pattern)"/>"); + </xsl:otherwise> + </xsl:choose> </xsl:if> </xsl:for-each> @@ -754,7 +761,7 @@ <xsl:value-of select="translate($matcher-type, '- ', '__')"/>Match(<xsl:value-of select="$matcher-name2"/>_expr, objectModel, <xsl:value-of select="$component-param"/>) </xsl:when> <xsl:otherwise> - matches("<xsl:value-of select="$matcher-type"/>", <xsl:value-of select="$matcher-name2"/>_expr, listOfMaps, <xsl:value-of select="$component-param"/>, objectModel) + matches("<xsl:value-of select="$matcher-type"/>", <xsl:value-of select="$matcher-name2"/>_expr, "<xsl:value-of select="XSLTFactoryLoader:escape($pattern-value)"/>", listOfMaps, <xsl:value-of select="$component-param"/>, objectModel) </xsl:otherwise> </xsl:choose> </xsl:variable> @@ -762,7 +769,7 @@ <!-- this is the actual code produced --> // handling "<xsl:value-of select="@pattern"/>" if ((map = <xsl:value-of select="$matcher-name"/>) != null) { - getLogger().debug("Matched <xsl:value-of select="$matcher-type"/><xsl:text> </xsl:text><xsl:value-of select="$matcher-name2"/><xsl:text> </xsl:text>pattern:<xsl:value-of select="XSLTFactoryLoader:escape($factory-loader, @pattern)"/>"); + getLogger().debug("Matched <xsl:value-of select="$matcher-type"/><xsl:text> </xsl:text><xsl:value-of select="$matcher-name2"/><xsl:text> </xsl:text>pattern:<xsl:value-of select="XSLTFactoryLoader:escape($factory-loader, $pattern-value)"/>"); listOfMaps.add (map); <xsl:apply-templates/> listOfMaps.remove (listOfMaps.size()-1); @@ -841,7 +848,7 @@ </xsl:when> <xsl:otherwise> - <xsl:text>matches("</xsl:text><xsl:value-of select="$matcher-type"/>", <xsl:value-of select="$matcher-name2"/>_expr, listOfMaps, <xsl:value-of select="$component-param"/><xsl:text>, objectModel)</xsl:text> + <xsl:text>matches("</xsl:text><xsl:value-of select="$matcher-type"/>", <xsl:value-of select="$matcher-name2"/>_expr, "<xsl:value-of select="XSLTFactoryLoader:escape($pattern-value)"/>", listOfMaps, <xsl:value-of select="$component-param"/><xsl:text>, objectModel)</xsl:text> </xsl:otherwise> </xsl:choose> </xsl:variable> 1.10 +41 -2 xml-cocoon2/src/org/apache/cocoon/sitemap/XSLTFactoryLoader.java Index: XSLTFactoryLoader.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/org/apache/cocoon/sitemap/XSLTFactoryLoader.java,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- XSLTFactoryLoader.java 2001/10/22 10:17:47 1.9 +++ XSLTFactoryLoader.java 2001/10/22 13:14:06 1.10 @@ -26,7 +26,7 @@ * * @author <a href="mailto:[EMAIL PROTECTED]">Giacomo Pati</a> * @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a> - * @version CVS $Revision: 1.9 $ $Date: 2001/10/22 10:17:47 $ + * @version CVS $Revision: 1.10 $ $Date: 2001/10/22 13:14:06 $ */ public class XSLTFactoryLoader { protected static Logger log; @@ -121,7 +121,8 @@ } /** - * Escapes '"' and '\' characters in a String so that it can be inserted in java source + * Escapes '"' and '\' characters in a String (add a '\' before them) so that it can + * be inserted in java source. */ public String escape(String string) { if (string.indexOf('\\') == -1 && string.indexOf('"') == -1) { @@ -138,5 +139,43 @@ buf.append(ch); } return buf.toString(); + } + + /** + * Escapes like {@link escape(String)} after having removed any '\' preceding a '{'. + * This is used to insert a pattern with escaped subsitution syntax in Java source. + */ + public String escapeBraces(String string) { + if (string.indexOf("\\{") == -1) + { + return escape(string); + } + + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < string.length(); i++) { + char ch = string.charAt(i); + if (ch != '\\' || i >= (string.length() - 1) || string.charAt(i+1) != '{') { + buf.append(ch); + } + } + return escape(buf.toString()); + } + + public boolean hasSubstitutions(String pattern) { + // Does it start by a substitution ? + if (pattern.charAt(0) == '{') { + return true; + } + + // Search for an unescaped '{' + int i = 1; + while ((i = pattern.indexOf('{', i)) != -1) { + if (pattern.charAt(i-1) != '\\') { + return true; + } + i++; // Pass '{' + } + + return false; } } 1.59 +3 -2 xml-cocoon2/webapp/sitemap.xmap Index: sitemap.xmap =================================================================== RCS file: /home/cvs/xml-cocoon2/webapp/sitemap.xmap,v retrieving revision 1.58 retrieving revision 1.59 diff -u -r1.58 -r1.59 --- sitemap.xmap 2001/10/22 10:17:47 1.58 +++ sitemap.xmap 2001/10/22 13:14:06 1.59 @@ -198,8 +198,9 @@ <!-- Utility for viewing source xml or html--> <map:pipeline> - <!-- sample use of regexp equivalent to "**.source" using wildcard --> - <map:match pattern="(.*)\.source" type="regexp"> + <!-- sample use of regexp equivalent to "**.source" using wildcard + this also shows the '\{' notation to escape sitemap values substitution --> + <map:match pattern="(.*)\.s\{1}ource" type="regexp"> <map:generate src="cocoon:/{1}" /> <map:transform src="stylesheets/simple-xml2html.xsl"/> <map:serialize/>
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]