1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jelly.tags.jsl;
18
19 import org.apache.commons.jelly.JellyTagException;
20 import org.apache.commons.jelly.TagSupport;
21 import org.apache.commons.jelly.XMLOutput;
22 import org.apache.commons.jelly.xpath.XPathSource;
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.dom4j.Node;
26 import org.dom4j.rule.Action;
27 import org.dom4j.rule.Pattern;
28 import org.dom4j.rule.Rule;
29
30 /***
31 * This tag represents a declarative matching rule, similar to the template tag in XSLT.
32 *
33 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
34 * @version $Revision: 155420 $
35 */
36 public class TemplateTag extends TagSupport implements XPathSource {
37
38 /*** The Log to which logging calls will be made. */
39 private Log log = LogFactory.getLog(TemplateTag.class);
40
41
42 /*** Holds value of property name. */
43 private String name;
44
45 /*** Holds value of property mode. */
46 private String mode;
47
48 /*** Holds value of property priority. */
49 private double priority;
50
51 /*** The pattern to match */
52 private Pattern match;
53
54 /*** The source XPath context for any child tags */
55 private Object xpathSource;
56
57
58 public TemplateTag() {
59 }
60
61
62
63
64 public void doTag(XMLOutput output) throws JellyTagException {
65 StylesheetTag tag = (StylesheetTag) findAncestorWithClass( StylesheetTag.class );
66 if (tag == null) {
67 throw new JellyTagException( "This <template> tag must be used inside a <stylesheet> tag" );
68 }
69
70 if ( log.isDebugEnabled() ) {
71 log.debug( "adding template rule for match: " + match );
72 }
73
74 Rule rule = createRule(tag, output);
75 if ( rule != null && tag != null) {
76 rule.setMode( mode );
77 tag.addTemplate( rule );
78 }
79 }
80
81
82
83
84 /***
85 * @return the current XPath value on which relative paths are evaluated
86 */
87 public Object getXPathSource() {
88 return xpathSource;
89 }
90
91
92
93
94
95 public void setMatch(Pattern match) {
96 this.match = match;
97 }
98
99 /*** Getter for property priority.
100 * @return Value of property priority.
101 */
102 public double getPriority() {
103 return priority;
104 }
105
106 /*** Sets the priority.
107 * @param priority New value of property priority.
108 */
109 public void setPriority(double priority) {
110 this.priority = priority;
111 }
112
113 /*** Getter for property name.
114 * @return Value of property name.
115 */
116 public String getName() {
117 return name;
118 }
119
120 /*** Sets the name.
121 * @param name New value of property name.
122 */
123 public void setName(String name) {
124 this.name = name;
125 }
126
127
128 /*** Sets the mode.
129 * @param mode New value of property mode.
130 */
131 public void setMode(String mode) {
132 this.mode = mode;
133 }
134
135
136
137
138 protected Rule createRule(StylesheetTag tag, XMLOutput output) {
139 return new Rule( match, createAction(tag, output) );
140 }
141
142 protected Action createAction(final StylesheetTag tag, final XMLOutput output) {
143 return new Action() {
144 public void run(Node node) throws Exception {
145
146
147 tag.setXPathSource( node );
148
149 xpathSource = node;
150
151 if (log.isDebugEnabled()) {
152 log.debug( "Firing template body for match: " + match + " and node: " + node );
153 }
154
155 XMLOutput actualOutput = tag.getStylesheetOutput();
156 if (actualOutput == null) {
157 actualOutput = output;
158 }
159
160 invokeBody(actualOutput);
161 }
162 };
163 }
164 }