jstrachan 2002/11/20 14:20:21
Modified: jelly/src/java/org/apache/commons/jelly/tags/jsl
StylesheetTag.java ApplyTemplatesTag.java
TemplateTag.java StyleTag.java
jelly/src/test/org/apache/commons/jelly/jsl suite.jelly
Added: jelly/src/java/org/apache/commons/jelly/tags/jsl
JellyStylesheet.java
Log:
Patch applied for the bug found by dIon. Also added a few more test cases to fully
test this feature to ensure it doesn't break again.
The bug essentially was that the <applyTemplates> is often invoked from a different
XMLOutput, which needs to be associated with the Stylesheet so that as new <template>s
fire they use the correct XMLOutput.
This is required as things like <j:set> use a different XMLOutput to buffer up its
body.
Revision Changes Path
1.8 +23 -15
jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/jsl/StylesheetTag.java
Index: StylesheetTag.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/jsl/StylesheetTag.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- StylesheetTag.java 23 Oct 2002 16:27:44 -0000 1.7
+++ StylesheetTag.java 20 Nov 2002 22:20:20 -0000 1.8
@@ -106,6 +106,26 @@
}
+ /**
+ * @return the XMLOutput from the stylesheet if available
+ */
+ public XMLOutput getStylesheetOutput() {
+ if (stylesheet instanceof JellyStylesheet) {
+ JellyStylesheet jellyStyle = (JellyStylesheet) stylesheet;
+ return jellyStyle.getOutput();
+ }
+ return null;
+ }
+
+ /**
+ * Sets the XMLOutput to use by the current stylesheet
*/
+ public void setStylesheetOutput(XMLOutput output) {
+ if (stylesheet instanceof JellyStylesheet) {
+ JellyStylesheet jellyStyle = (JellyStylesheet) stylesheet;
+ jellyStyle.setOutput(output);
+ }
+ }
+
/**
* Adds a new template rule to this stylesheet
*/
@@ -201,21 +221,9 @@
* Factory method to create a new stylesheet
*/
protected Stylesheet createStylesheet(final XMLOutput output) {
- // add default actions
- Stylesheet answer = new Stylesheet();
- answer.setValueOfAction(
- new Action() {
- public void run(Node node) throws Exception {
- String text = node.getStringValue();
- if ( text != null && text.length() > 0 ) {
- // #### should use an 'output' property
- // when this variable gets reused
- output.write( text );
- }
- }
- }
- );
- return answer;
+ JellyStylesheet answer = new JellyStylesheet();
+ answer.setOutput(output);
+ return answer;
}
/**
1.5 +7 -1
jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/jsl/ApplyTemplatesTag.java
Index: ApplyTemplatesTag.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/jsl/ApplyTemplatesTag.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- ApplyTemplatesTag.java 23 Oct 2002 16:27:44 -0000 1.4
+++ ApplyTemplatesTag.java 20 Nov 2002 22:20:20 -0000 1.5
@@ -101,7 +101,11 @@
"<applyTemplates> tag must be inside a <stylesheet> tag"
);
}
- Stylesheet stylesheet = tag.getStylesheet();
+ Stylesheet stylesheet = tag.getStylesheet();
+
+ XMLOutput oldOutput = tag.getStylesheetOutput();
+ tag.setStylesheetOutput(output);
+
Object source = tag.getXPathSource();
if ( select != null ) {
stylesheet.applyTemplates( source, select );
@@ -109,6 +113,8 @@
else {
stylesheet.applyTemplates( source );
}
+
+ tag.setStylesheetOutput(oldOutput);
// #### should support MODE!!!
1.8 +7 -1
jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/jsl/TemplateTag.java
Index: TemplateTag.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/jsl/TemplateTag.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- TemplateTag.java 19 Nov 2002 13:28:43 -0000 1.7
+++ TemplateTag.java 20 Nov 2002 22:20:20 -0000 1.8
@@ -196,7 +196,13 @@
if (log.isDebugEnabled()) {
log.debug( "Firing template body for match: " + match + " and
node: " + node );
}
- invokeBody(output);
+
+ XMLOutput actualOutput = tag.getStylesheetOutput();
+ if (actualOutput == null) {
+ actualOutput = output;
+ }
+
+ invokeBody(actualOutput);
}
};
}
1.3 +4 -0
jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/jsl/StyleTag.java
Index: StyleTag.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/jsl/StyleTag.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- StyleTag.java 23 Oct 2002 16:27:44 -0000 1.2
+++ StyleTag.java 20 Nov 2002 22:20:20 -0000 1.3
@@ -104,6 +104,10 @@
log.debug("About to evaluate stylesheet on source: " + source);
}
+ if (stylesheet instanceof JellyStylesheet) {
+ JellyStylesheet jellyStyle = (JellyStylesheet) stylesheet;
+ jellyStyle.setOutput(output);
+ }
stylesheet.run(source);
}
1.1
jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/jsl/JellyStylesheet.java
Index: JellyStylesheet.java
===================================================================
/*
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.jelly.tags.jsl;
import org.apache.commons.jelly.XMLOutput;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Node;
import org.dom4j.rule.Action;
import org.dom4j.rule.Stylesheet;
/**
* This class is a specialization of the Stylesheet from dom4j's rule engine
* that adds some Jelly specific features.
*
* @author <a href="mailto:[EMAIL PROTECTED]">James Strachan</a>
* @version $Revision: 1.8 $
*/
public class JellyStylesheet extends Stylesheet {
/** The Log to which logging calls will be made. */
private Log log = LogFactory.getLog(JellyStylesheet.class);
private XMLOutput output;
public JellyStylesheet() {
setValueOfAction(
new Action() {
public void run(Node node) throws Exception {
String text = node.getStringValue();
if ( text != null && text.length() > 0 ) {
getOutput().write( text );
}
}
}
);
}
// Properties
//-------------------------------------------------------------------------
/**
* Returns the output.
* @return XMLOutput
*/
public XMLOutput getOutput() {
return output;
}
/**
* Sets the output.
* @param output The output to set
*/
public void setOutput(XMLOutput output) {
this.output = output;
}
}
1.8 +54 -10
jakarta-commons-sandbox/jelly/src/test/org/apache/commons/jelly/jsl/suite.jelly
Index: suite.jelly
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/jelly/src/test/org/apache/commons/jelly/jsl/suite.jelly,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- suite.jelly 20 Nov 2002 06:05:19 -0000 1.7
+++ suite.jelly 20 Nov 2002 22:20:21 -0000 1.8
@@ -138,7 +138,7 @@
test case to test that the xml output for a stylesheet template is
'remembered' when using applyTemplates
-->
- <test:case name="testXMLContextKept" xmlns="dummy">
+ <test:case name="testXMLContextKept" xmlns:foo="dummy">
<x:parse var="testDoc">
<element1>
<element2>SomeText</element2>
@@ -153,18 +153,62 @@
<jsl:template match="element2"><x:expr select="."/></jsl:template>
</jsl:stylesheet>
- <!-- same stylesheet, no set -->
- <jsl:stylesheet var="contextStyleSheet2">
- <jsl:template match="element1">El1<jsl:applyTemplates /></jsl:template>
+ <log:info>
+ ...
+ <jsl:style stylesheet="${contextStyleSheet}" select="$testDoc"/>
+ ...
+ </log:info>
+
+ <m:echo>text is '${contextText}'</m:echo>
+
+ <test:assertEquals expected="El1SomeText" actual="${contextText}" />
+ </test:case>
+
+ <test:case name="testXMLContextKept2" xmlns:foo="dummy">
+ <x:parse var="testDoc">
+ <element1>
+ <element2>SomeText</element2>
+ </element1>
+ </x:parse>
+
+ <!-- stylesheet with embedded set and text() rule -->
+ <jsl:stylesheet var="contextStyleSheet">
+ <jsl:template match="element1">
+ <j:set var="contextText">El1<jsl:applyTemplates /></j:set>
+ </jsl:template>
<jsl:template match="element2"><x:expr select="."/></jsl:template>
+ <jsl:template match="text()"><x:expr select="."/></jsl:template>
</jsl:stylesheet>
- <!-- test stylesheet 1 -->
- <jsl:style stylesheet="${contextStyleSheet}" select="$testDoc"/>
- <!-- test stylesheet 2 -->
- <j:set var="contextText2"><jsl:style stylesheet="${contextStyleSheet2}"
select="$testDoc"/></j:set>
- <m:echo>text is '${contextText}', inline is '${contextText2}'</m:echo>
+ <log:info>
+ ...
+ <jsl:style stylesheet="${contextStyleSheet}" select="$testDoc"/>
+ ...
+ </log:info>
+
+ <m:echo>text is '${contextText}'</m:echo>
+
<test:assertEquals expected="El1SomeText" actual="${contextText}" />
- <test:assertEquals expected="El1SomeText" actual="${contextText2}" />
</test:case>
+
+ <test:case name="testXMLContextKept3" xmlns:foo="dummy">
+ <x:parse var="testDoc">
+ <element1>
+ <element2>SomeText</element2>
+ </element1>
+ </x:parse>
+
+ <!-- stylesheet with no embedded set -->
+ <jsl:stylesheet var="contextStyleSheet">
+ <jsl:template match="element1">El1<jsl:applyTemplates /></jsl:template>
+ <jsl:template match="element2"><x:expr select="."/></jsl:template>
+ </jsl:stylesheet>
+
+ <j:set var="contextText"><jsl:style stylesheet="${contextStyleSheet}"
select="$testDoc"/></j:set>
+
+ <m:echo>text is '${contextText}'</m:echo>
+
+ <test:assertEquals expected="El1SomeText" actual="${contextText}" />
+ </test:case>
+
</test:suite>
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>