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 }