1 package net.sf.saxon.style; 2 import net.sf.saxon.expr.Expression; 3 import net.sf.saxon.expr.ExpressionTool; 4 import net.sf.saxon.instruct.Choose; 5 import net.sf.saxon.instruct.Executable; 6 import net.sf.saxon.instruct.TraceWrapper; 7 import net.sf.saxon.om.AttributeCollection; 8 import net.sf.saxon.om.Axis; 9 import net.sf.saxon.om.AxisIterator; 10 import net.sf.saxon.om.NodeInfo; 11 import net.sf.saxon.trans.XPathException; 12 import net.sf.saxon.type.ItemType; 13 import net.sf.saxon.value.BooleanValue; 14 import net.sf.saxon.value.EmptySequence; 15 16 19 20 public class XSLChoose extends StyleElement { 21 22 private StyleElement otherwise; 23 private int numberOfWhens = 0; 24 25 29 30 public boolean isInstruction() { 31 return true; 32 } 33 34 39 40 protected ItemType getReturnedItemType() { 41 return getCommonChildItemType(); 42 } 43 44 public void prepareAttributes() throws XPathException { 45 AttributeCollection atts = getAttributeList(); 46 for (int a=0; a<atts.getLength(); a++) { 47 int nc = atts.getNameCode(a); 48 checkUnknownAttribute(nc); 49 } 50 } 51 52 public void validate() throws XPathException { 53 checkWithinTemplate(); 54 55 AxisIterator kids = iterateAxis(Axis.CHILD); 56 while(true) { 57 NodeInfo curr = (NodeInfo)kids.next(); 58 if (curr == null) { 59 break; 60 } 61 if (curr instanceof XSLWhen) { 62 if (otherwise!=null) { 63 compileError("xsl:otherwise must come last", "XTSE0010"); 64 } 65 numberOfWhens++; 66 } else if (curr instanceof XSLOtherwise) { 67 if (otherwise!=null) { 68 compileError("Only one xsl:otherwise allowed in an xsl:choose", "XTSE0010"); 69 } else { 70 otherwise = (StyleElement)curr; 71 } 72 } else { 73 compileError("Only xsl:when and xsl:otherwise are allowed here", "XTSE0010"); 74 } 75 } 76 77 if (numberOfWhens==0) { 78 compileError("xsl:choose must contain at least one xsl:when", "XTSE0010"); 79 } 80 } 81 82 85 86 public void markTailCalls() { 87 AxisIterator kids = iterateAxis(Axis.CHILD); 88 while(true) { 89 NodeInfo curr = (NodeInfo)kids.next(); 90 if (curr == null) { 91 return; 92 } 93 if (curr instanceof StyleElement) { 94 ((StyleElement)curr).markTailCalls(); 95 } 96 } 97 } 98 99 100 public Expression compile(Executable exec) throws XPathException { 101 102 int entries = numberOfWhens + (otherwise==null ? 0 : 1); 103 Expression[] conditions = new Expression[entries]; 104 Expression[] actions = new Expression[entries]; 105 106 int w = 0; 107 AxisIterator kids = iterateAxis(Axis.CHILD); 108 while(true) { 109 NodeInfo curr = (NodeInfo)kids.next(); 110 if (curr == null) { 111 break; 112 } 113 if (curr instanceof XSLWhen) { 114 conditions[w] = ((XSLWhen)curr).getCondition(); 115 Expression b = ((XSLWhen)curr).compileSequenceConstructor( 116 exec, curr.iterateAxis(Axis.CHILD), true); 117 if (b == null) { 118 b = EmptySequence.getInstance(); 119 } 120 try { 121 b = b.simplify(((XSLWhen)curr).getStaticContext()); 122 actions[w] = b; 123 } catch (XPathException e) { 124 compileError(e); 125 } 126 127 if (getConfiguration().getTraceListener() != null) { 128 TraceWrapper trace = makeTraceInstruction((XSLWhen)curr, actions[w]); 129 trace.setParentExpression((XSLWhen)curr); 130 actions[w] = trace; 131 } 132 133 if (conditions[w] instanceof BooleanValue) { 135 if (((BooleanValue)conditions[w]).getBooleanValue()) { 136 entries = w+1; 138 break; 139 } else { 140 w--; 142 entries--; 143 } 144 } 145 w++; 146 } else if (curr instanceof XSLOtherwise) { 147 conditions[w] = BooleanValue.TRUE; 148 Expression b = ((XSLOtherwise)curr).compileSequenceConstructor( 149 exec, curr.iterateAxis(Axis.CHILD), true); 150 if (b == null) { 151 b = EmptySequence.getInstance(); 152 } 153 try { 154 b = b.simplify(((XSLOtherwise)curr).getStaticContext()); 155 actions[w] = b; 156 } catch (XPathException e) { 157 compileError(e); 158 } 159 if (getConfiguration().getTraceListener() != null) { 160 TraceWrapper trace = makeTraceInstruction((XSLOtherwise)curr, actions[w]); 161 trace.setParentExpression((XSLOtherwise)curr); 162 actions[w] = trace; 163 } 164 w++; 165 } else { 166 new AssertionError ("Expected xsl:when or xsl:otherwise"); 167 } 168 } 169 170 if (conditions.length != entries) { 171 if (entries==0) { 173 return null; } 175 if (entries==1 && (conditions[0] instanceof BooleanValue)) { 176 if (((BooleanValue)conditions[0]).getBooleanValue()) { 177 return actions[0]; 179 } else { 180 return null; 182 } 183 } 184 Expression[] conditions2 = new Expression[entries]; 185 System.arraycopy(conditions, 0, conditions2, 0, entries); 186 Expression[] actions2 = new Expression[entries]; 187 System.arraycopy(actions, 0, actions2, 0, entries); 188 conditions = conditions2; 189 actions = actions2; 190 } 191 192 Choose ch = new Choose(conditions, actions); 193 ExpressionTool.makeParentReferences(ch); 194 return ch; 195 } 196 197 } 198 199 | Popular Tags |