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  
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      // Tag interface
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      // XPathSource interface
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      // Properties
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     // Implementation methods
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                 // store the context for use by applyTemplates tag
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 }