View Javadoc

1   /*
2    * Copyright 2002,2004 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.jelly.tags.jsl;
17  
18  import org.apache.commons.jelly.JellyTagException;
19  import org.apache.commons.jelly.XMLOutput;
20  import org.apache.commons.jelly.xpath.XPathSource;
21  import org.apache.commons.jelly.xpath.XPathTagSupport;
22  import org.apache.commons.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  import org.dom4j.rule.Rule;
25  import org.dom4j.rule.Stylesheet;
26  import org.jaxen.JaxenException;
27  import org.jaxen.XPath;
28  
29  
30  /***
31   * This tag implements a JSL stylesheet which is similar to an
32   * XSLT stylesheet but can use Jelly tags inside it
33   *
34   * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
35   * @version $Revision: 155420 $
36   */
37  public class StylesheetTag extends XPathTagSupport implements XPathSource {
38  
39      /*** The Log to which logging calls will be made. */
40      private Log log = LogFactory.getLog(StylesheetTag.class);
41  
42  
43      /*** Holds the stylesheet which will be applied to the source context. */
44      private Stylesheet stylesheet;
45  
46      /*** Holds value of property mode. */
47      private String mode;
48  
49      /*** The variable which the stylesheet will be output as */
50      private String var;
51  
52      /*** The XPath expression to evaluate. */
53      private XPath select;
54  
55      /*** The XPath source used by TemplateTag and ApplyTemplatesTag to pass XPath contexts */
56      private Object xpathSource;
57  
58      public StylesheetTag() {
59      }
60  
61  
62      /***
63       * @return the XMLOutput from the stylesheet if available
64       */
65      public XMLOutput getStylesheetOutput() {
66          if (stylesheet instanceof JellyStylesheet) {
67              JellyStylesheet jellyStyle = (JellyStylesheet) stylesheet;
68              return jellyStyle.getOutput();
69          }
70          return null;
71      }
72  
73      /***
74       * Sets the XMLOutput to use by the current stylesheet
75       */
76      public void setStylesheetOutput(XMLOutput output) {
77          if (stylesheet instanceof JellyStylesheet) {
78              JellyStylesheet jellyStyle = (JellyStylesheet) stylesheet;
79              jellyStyle.setOutput(output);
80          }
81      }
82  
83      /***
84       * Adds a new template rule to this stylesheet
85       */
86      public void addTemplate( Rule rule ) {
87          getStylesheet().addRule( rule );
88      }
89  
90      // XPathSource interface
91      //-------------------------------------------------------------------------
92  
93      /***
94       * @return the current XPath iteration value
95       *  so that any other XPath aware child tags to use
96       */
97      public Object getXPathSource() {
98          return xpathSource;
99      }
100 
101 
102     // Tag interface
103     //-------------------------------------------------------------------------
104     public void doTag(XMLOutput output) throws JellyTagException {
105         stylesheet = createStylesheet(output);
106 
107         // run the body to add the rules
108         invokeBody(output);
109         stylesheet.setModeName(getMode());
110 
111         if (var != null) {
112             context.setVariable(var, stylesheet);
113         }
114         else {
115 
116             //dom4j seems to only throw generic Exceptions
117             try {
118                 Object source = getSource();
119 
120                 if (log.isDebugEnabled()) {
121                     log.debug("About to evaluate stylesheet on source: " + source);
122                 }
123 
124                 stylesheet.run(source);
125             }
126             catch (Exception e) {
127                 throw new JellyTagException(e);
128             }
129 
130         }
131     }
132 
133 
134     // Properties
135     //-------------------------------------------------------------------------
136 
137     /***
138      * Getter for property mode.
139      * @return Value of property mode.
140      */
141     public String getMode() {
142         return mode;
143     }
144 
145     /***
146      * Sets the mode.
147      * @param mode New value of property mode.
148      */
149     public void setMode(String mode) {
150         this.mode = mode;
151     }
152 
153     public Stylesheet getStylesheet() {
154         return stylesheet;
155     }
156 
157     /*** Sets the variable name to define for this expression
158      */
159     public void setVar(String var) {
160         this.var = var;
161     }
162 
163     /*** Sets the XPath expression to evaluate. */
164     public void setSelect(XPath select) {
165         this.select = select;
166     }
167 
168     // Implementation methods
169     //-------------------------------------------------------------------------
170 
171     /*** @return the source on which the stylesheet should run
172      */
173     protected Object getSource() throws JaxenException {
174         Object source = getXPathContext();
175         if ( select != null ) {
176             return select.evaluate(source);
177         }
178         return source;
179     }
180 
181 
182     /***
183      * Factory method to create a new stylesheet
184      */
185     protected Stylesheet createStylesheet(final XMLOutput output) {
186         JellyStylesheet answer = new JellyStylesheet();
187         answer.setOutput(output);
188         return answer;
189     }
190 
191     /***
192      * Sets the xpathSource.
193      * @param xpathSource The xpathSource to set
194      */
195     void setXPathSource(Object xpathSource) {
196         this.xpathSource = xpathSource;
197     }
198 
199 }