001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 /*
019 * $Id: ElemIf.java 468643 2006-10-28 06:56:03Z minchau $
020 */
021 package org.apache.xalan.templates;
022
023 import javax.xml.transform.TransformerException;
024
025 import org.apache.xalan.transformer.TransformerImpl;
026 import org.apache.xpath.XPath;
027 import org.apache.xpath.XPathContext;
028 import org.apache.xpath.objects.XObject;
029
030 /**
031 * Implement xsl:if.
032 * <pre>
033 * <!ELEMENT xsl:if %template;>
034 * <!ATTLIST xsl:if
035 * test %expr; #REQUIRED
036 * %space-att;
037 * >
038 * </pre>
039 * @see <a href="http://www.w3.org/TR/xslt#section-Conditional-Processing-with-xsl:if">XXX in XSLT Specification</a>
040 * @xsl.usage advanced
041 */
042 public class ElemIf extends ElemTemplateElement
043 {
044 static final long serialVersionUID = 2158774632427453022L;
045
046 /**
047 * The xsl:if element must have a test attribute, which specifies an expression.
048 * @serial
049 */
050 private XPath m_test = null;
051
052 /**
053 * Set the "test" attribute.
054 * The xsl:if element must have a test attribute, which specifies an expression.
055 *
056 * @param v test attribute to set
057 */
058 public void setTest(XPath v)
059 {
060 m_test = v;
061 }
062
063 /**
064 * Get the "test" attribute.
065 * The xsl:if element must have a test attribute, which specifies an expression.
066 *
067 * @return the "test" attribute for this element.
068 */
069 public XPath getTest()
070 {
071 return m_test;
072 }
073
074 /**
075 * This function is called after everything else has been
076 * recomposed, and allows the template to set remaining
077 * values that may be based on some other property that
078 * depends on recomposition.
079 *
080 * @param sroot The root stylesheet.
081 *
082 * @throws TransformerException
083 */
084 public void compose(StylesheetRoot sroot) throws TransformerException
085 {
086
087 super.compose(sroot);
088
089 java.util.Vector vnames = sroot.getComposeState().getVariableNames();
090
091 if (null != m_test)
092 m_test.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
093 }
094
095 /**
096 * Get an int constant identifying the type of element.
097 * @see org.apache.xalan.templates.Constants
098 *
099 * @return The token ID for this element
100 */
101 public int getXSLToken()
102 {
103 return Constants.ELEMNAME_IF;
104 }
105
106 /**
107 * Return the node name.
108 *
109 * @return the element's name
110 */
111 public String getNodeName()
112 {
113 return Constants.ELEMNAME_IF_STRING;
114 }
115
116 /**
117 * Conditionally execute a sub-template.
118 * The expression is evaluated and the resulting object is converted
119 * to a boolean as if by a call to the boolean function. If the result
120 * is true, then the content template is instantiated; otherwise, nothing
121 * is created.
122 *
123 * @param transformer non-null reference to the the current transform-time state.
124 *
125 * @throws TransformerException
126 */
127 public void execute(TransformerImpl transformer) throws TransformerException
128 {
129
130 XPathContext xctxt = transformer.getXPathContext();
131 int sourceNode = xctxt.getCurrentNode();
132
133 if (transformer.getDebug())
134 {
135 XObject test = m_test.execute(xctxt, sourceNode, this);
136
137 if (transformer.getDebug())
138 transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
139 "test", m_test, test);
140
141 // xsl:for-each now fires one trace event + one for every
142 // iteration; changing xsl:if to fire one regardless of true/false
143
144 if (transformer.getDebug())
145 transformer.getTraceManager().fireTraceEvent(this);
146
147 if (test.bool())
148 {
149 transformer.executeChildTemplates(this, true);
150 }
151
152 if (transformer.getDebug())
153 transformer.getTraceManager().fireTraceEndEvent(this);
154
155 // I don't think we want this. -sb
156 // if (transformer.getDebug())
157 // transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
158 // "endTest", m_test, test);
159 }
160 else if (m_test.bool(xctxt, sourceNode, this))
161 {
162 transformer.executeChildTemplates(this, true);
163 }
164
165 }
166
167 /**
168 * Call the children visitors.
169 * @param visitor The visitor whose appropriate method will be called.
170 */
171 protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
172 {
173 if(callAttrs)
174 m_test.getExpression().callVisitors(m_test, visitor);
175 super.callChildVisitors(visitor, callAttrs);
176 }
177
178 }