001: package net.sf.saxon.style;
002:
003: import net.sf.saxon.expr.Expression;
004: import net.sf.saxon.expr.ExpressionTool;
005: import net.sf.saxon.instruct.Choose;
006: import net.sf.saxon.instruct.Executable;
007: import net.sf.saxon.om.AttributeCollection;
008: import net.sf.saxon.om.Axis;
009: import net.sf.saxon.trans.XPathException;
010: import net.sf.saxon.type.ItemType;
011: import net.sf.saxon.value.Value;
012:
013: /**
014: * Handler for xsl:if elements in stylesheet. <br>
015: * The xsl:if element has a mandatory attribute test, a boolean expression.
016: * The content is output if the test condition is true.
017: */
018:
019: public class XSLIf extends StyleElement {
020:
021: private Expression test;
022:
023: /**
024: * Determine whether this node is an instruction.
025: * @return true - it is an instruction
026: */
027:
028: public boolean isInstruction() {
029: return true;
030: }
031:
032: /**
033: * Determine the type of item returned by this instruction (only relevant if
034: * it is an instruction).
035: * @return the item type returned
036: */
037:
038: protected ItemType getReturnedItemType() {
039: return getCommonChildItemType();
040: }
041:
042: /**
043: * Determine whether this type of element is allowed to contain a template-body
044: * @return true: yes, it may contain a template-body
045: */
046:
047: public boolean mayContainSequenceConstructor() {
048: return true;
049: }
050:
051: public void prepareAttributes() throws XPathException {
052:
053: String testAtt = null;
054:
055: AttributeCollection atts = getAttributeList();
056:
057: for (int a = 0; a < atts.getLength(); a++) {
058: int nc = atts.getNameCode(a);
059: String f = getNamePool().getClarkName(nc);
060: if (f == StandardNames.TEST) {
061: testAtt = atts.getValue(a);
062: } else {
063: checkUnknownAttribute(nc);
064: }
065: }
066:
067: if (testAtt == null) {
068: reportAbsence("test");
069: } else {
070: test = makeExpression(testAtt);
071: }
072: }
073:
074: public void validate() throws XPathException {
075: checkWithinTemplate();
076: test = typeCheck("test", test);
077: }
078:
079: /**
080: * Mark tail-recursive calls on stylesheet functions. For most instructions, this does nothing.
081: */
082:
083: public void markTailCalls() {
084: StyleElement last = getLastChildInstruction();
085: if (last != null) {
086: last.markTailCalls();
087: }
088: }
089:
090: public Expression compile(Executable exec) throws XPathException {
091: if (test instanceof Value) {
092: // condition known statically, so we only need compile the code if true.
093: // This can happen with expressions such as test="function-available('abc')".
094: try {
095: if (test.effectiveBooleanValue(null)) {
096: return compileSequenceConstructor(exec,
097: iterateAxis(Axis.CHILD), true);
098: // Block block = new Block();
099: // block.setLocationId(allocateLocationId(getSystemId(), getLineNumber()));
100: // compileChildren(exec, block, true);
101: // return block.simplify(getStaticContext());
102: } else {
103: return null;
104: }
105: } catch (XPathException err) {
106: // fall through to non-optimizing case
107: }
108: }
109:
110: Expression action = compileSequenceConstructor(exec,
111: iterateAxis(Axis.CHILD), true);
112: if (action == null) {
113: return null;
114: }
115: Expression[] conditions = { test };
116: Expression[] actions = { action };
117:
118: Choose inst = new Choose(conditions, actions);
119: ExpressionTool.makeParentReferences(inst);
120: return inst;
121: }
122:
123: }
124: //
125: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
126: // you may not use this file except in compliance with the License. You may obtain a copy of the
127: // License at http://www.mozilla.org/MPL/
128: //
129: // Software distributed under the License is distributed on an "AS IS" basis,
130: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
131: // See the License for the specific language governing rights and limitations under the License.
132: //
133: // The Original Code is: all this file.
134: //
135: // The Initial Developer of the Original Code is Michael H. Kay.
136: //
137: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
138: //
139: // Contributor(s): none.
140: //
|