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]>

Reply via email to