1 package net.sf.saxon.instruct; 2 import net.sf.saxon.expr.*; 3 import net.sf.saxon.om.EmptyIterator; 4 import net.sf.saxon.om.Item; 5 import net.sf.saxon.om.NamePool; 6 import net.sf.saxon.om.SequenceIterator; 7 import net.sf.saxon.style.StandardNames; 8 import net.sf.saxon.trans.XPathException; 9 import net.sf.saxon.type.ItemType; 10 import net.sf.saxon.type.SchemaType; 11 import net.sf.saxon.type.Type; 12 import net.sf.saxon.value.Value; 13 14 import java.io.PrintStream ; 15 import java.util.ArrayList ; 16 import java.util.Iterator ; 17 18 22 23 public class Choose extends Instruction { 24 25 32 private Expression[] conditions; 33 private Expression[] actions; 34 35 36 41 42 public Choose(Expression[] conditions, Expression[] actions) { 43 this.conditions = conditions; 44 this.actions = actions; 45 for (int i=0; i<conditions.length; i++) { 46 adoptChildExpression(conditions[i]); 47 } 48 for (int i=0; i<actions.length; i++) { 49 adoptChildExpression(actions[i]); 50 } 51 } 52 53 59 60 61 public int getInstructionNameCode() { 62 return (conditions.length==1 ? StandardNames.XSL_IF : StandardNames.XSL_CHOOSE); 63 } 64 65 73 74 public Expression simplify(StaticContext env) throws XPathException { 75 for (int i=0; i<conditions.length; i++) { 76 conditions[i] = conditions[i].simplify(env); 77 } 78 for (int i=0; i<actions.length; i++) { 79 actions[i] = actions[i].simplify(env); 80 } 81 return this; 82 } 83 84 public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException { 85 for (int i=0; i<conditions.length; i++) { 86 conditions[i] = conditions[i].typeCheck(env, contextItemType); 87 adoptChildExpression(conditions[i]); 88 } 89 for (int i=0; i<actions.length; i++) { 90 actions[i] = actions[i].typeCheck(env, contextItemType); 91 adoptChildExpression(actions[i]); 92 } 93 return this; 94 } 95 96 public Expression optimize(Optimizer opt, StaticContext env, ItemType contextItemType) throws XPathException { 97 for (int i=0; i<conditions.length; i++) { 98 conditions[i] = conditions[i].optimize(opt, env, contextItemType); 99 adoptChildExpression(conditions[i]); 100 if (conditions[i] instanceof Value) { 101 try { 102 boolean b = ExpressionTool.effectiveBooleanValue(conditions[i].iterate(null)); 103 if (b) { 104 if (i==0) { 106 return actions[0]; 107 } else if (i != conditions.length - 1) { 108 Expression[] c2 = new Expression[i+1]; 109 Expression[] a2 = new Expression[i+1]; 110 System.arraycopy(conditions, 0, c2, 0, i+1); 111 System.arraycopy(actions, 0, a2, 0, i+1); 112 conditions = c2; 113 actions = a2; 114 break; 115 } 116 } else { 117 Expression[] c2 = new Expression[conditions.length - 1]; 119 Expression[] a2 = new Expression[conditions.length - 1]; 120 System.arraycopy(conditions, 0, c2, 0, i); 121 System.arraycopy(actions, 0, a2, 0, i); 122 System.arraycopy(conditions, i+1, c2, i, conditions.length - i - 1); 123 System.arraycopy(actions, i+1, a2, i, conditions.length - i - 1); 124 conditions = c2; 125 actions = a2; 126 i--; 127 } 128 } catch (Exception e) {}; 129 } 130 } 131 for (int i=0; i<actions.length; i++) { 132 actions[i] = actions[i].optimize(opt, env, contextItemType); 133 adoptChildExpression(actions[i]); 134 } 135 return this; 136 } 137 138 139 143 144 public ItemType getItemType() { 145 ItemType type = actions[0].getItemType(); 146 for (int i=1; i<actions.length; i++) { 147 type = Type.getCommonSuperType(type, actions[i].getItemType()); 148 } 149 return type; 150 } 151 152 157 158 public final boolean createsNewNodes() { 159 for (int i=0; i<actions.length; i++) { 160 int props = actions[i].getSpecialProperties(); 161 if ((props & StaticProperty.NON_CREATIVE) == 0) { 162 return true; 163 }; 164 } 165 return false; 166 } 167 168 173 174 public Iterator iterateSubExpressions() { 175 ArrayList list = new ArrayList (conditions.length + actions.length); 176 for (int i=0; i<conditions.length; i++) { 177 list.add(conditions[i]); 178 } 179 for (int i=0; i<actions.length; i++) { 180 list.add(actions[i]); 181 } 182 return list.iterator(); 183 } 184 185 190 191 protected void promoteInst(PromotionOffer offer) throws XPathException { 192 if (offer.action == PromotionOffer.UNORDERED || 196 offer.action == PromotionOffer.INLINE_VARIABLE_REFERENCES || 197 offer.action == PromotionOffer.REPLACE_CURRENT) { 198 for (int i=0; i<conditions.length; i++) { 199 conditions[i] = doPromotion(conditions[i], offer); 200 } 201 for (int i=0; i<actions.length; i++) { 202 actions[i] = doPromotion(actions[i], offer); 203 } 204 } else { 205 conditions[0] = doPromotion(conditions[0], offer); 207 } 208 } 209 210 217 218 public void checkPermittedContents(SchemaType parentType, StaticContext env, boolean whole) throws XPathException { 219 for (int i=0; i<actions.length; i++) { 220 actions[i].checkPermittedContents(parentType, env, whole); 221 } 222 } 223 224 231 232 public void display(int level, NamePool pool, PrintStream out) { 233 for (int i=0; i<conditions.length; i++) { 234 out.println(ExpressionTool.indent(level) + (i==0 ? "if" : "else if")); 235 conditions[i].display(level+1, pool, out); 236 out.println(ExpressionTool.indent(level) + "then"); 237 actions[i].display(level+1, pool, out); 238 } 239 } 240 241 250 251 public TailCall processLeavingTail(XPathContext context) throws XPathException { 252 for (int i=0; i<conditions.length; i++) { 253 if (conditions[i].effectiveBooleanValue(context)) { 254 if (actions[i] instanceof TailCallReturner) { 255 return ((TailCallReturner)actions[i]).processLeavingTail(context); 256 } else { 257 actions[i].process(context); 258 return null; 259 } 260 } 261 } 262 return null; 263 } 264 265 279 280 public Item evaluateItem(XPathContext context) throws XPathException { 281 for (int i=0; i<conditions.length; i++) { 282 if (conditions[i].effectiveBooleanValue(context)) { 283 return actions[i].evaluateItem(context); 284 } 285 } 286 return null; 287 } 288 289 305 306 public SequenceIterator iterate(XPathContext context) throws XPathException { 307 for (int i=0; i<conditions.length; i++) { 308 if (conditions[i].effectiveBooleanValue(context)) { 309 return (actions[i]).iterate(context); 310 } 311 } 312 return EmptyIterator.getInstance(); 313 } 314 } 315 316 | Popular Tags |