1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
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
103
104 public void doTag(XMLOutput output) throws JellyTagException {
105 stylesheet = createStylesheet(output);
106
107
108 invokeBody(output);
109 stylesheet.setModeName(getMode());
110
111 if (var != null) {
112 context.setVariable(var, stylesheet);
113 }
114 else {
115
116
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
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
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 }