1 package net.sf.saxon.instruct; 2 import net.sf.saxon.Controller; 3 import net.sf.saxon.expr.*; 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.trace.TraceListener; 9 import net.sf.saxon.trans.XPathException; 10 import net.sf.saxon.type.ItemType; 11 import net.sf.saxon.type.SchemaType; 12 import net.sf.saxon.value.EmptySequence; 13 14 import java.io.PrintStream ; 15 import java.util.Iterator ; 16 17 18 21 22 public class ForEach extends Instruction implements MappingFunction { 23 24 private Expression select; 25 private Expression action; 26 27 public ForEach(Expression select, Expression action) { 28 this.select = select; 29 this.action = action; 30 adoptChildExpression(select); 31 adoptChildExpression(action); 32 } 33 34 37 38 public int getInstructionNameCode() { 39 return StandardNames.XSL_FOR_EACH; 40 } 41 42 45 46 public Expression getActionExpression() { 47 return action; 48 } 49 50 54 55 public final ItemType getItemType() { 56 return action.getItemType(); 57 } 58 59 64 65 public final boolean createsNewNodes() { 66 int props = action.getSpecialProperties(); 67 return ((props & StaticProperty.NON_CREATIVE) == 0); 68 } 69 70 78 79 public Expression simplify(StaticContext env) throws XPathException { 80 select = select.simplify(env); 81 action = action.simplify(env); 82 return this; 83 } 84 85 public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException { 86 select = select.typeCheck(env, contextItemType); 87 adoptChildExpression(select); 88 action = action.typeCheck(env, select.getItemType()); 89 adoptChildExpression(action); 90 if (select instanceof EmptySequence) { 91 return EmptySequence.getInstance(); 92 } 93 if (action instanceof EmptySequence) { 94 return EmptySequence.getInstance(); 95 } 96 return this; 97 } 98 99 public Expression optimize(Optimizer opt, StaticContext env, ItemType contextItemType) throws XPathException { 100 select = select.optimize(opt, env, contextItemType); 101 adoptChildExpression(select); 102 action = action.optimize(opt, env, select.getItemType()); 103 adoptChildExpression(action); 104 if (select instanceof EmptySequence) { 105 return EmptySequence.getInstance(); 106 } 107 if (action instanceof EmptySequence) { 108 return EmptySequence.getInstance(); 109 } 110 111 114 PromotionOffer offer = new PromotionOffer(opt); 115 offer.action = PromotionOffer.FOCUS_INDEPENDENT; 116 offer.promoteDocumentDependent = (select.getSpecialProperties() & StaticProperty.CONTEXT_DOCUMENT_NODESET) != 0; 117 offer.promoteXSLTFunctions = false; 118 offer.containingExpression = this; 119 action = doPromotion(action, offer); 120 121 if (offer.containingExpression instanceof LetExpression) { 122 offer.containingExpression = 123 offer.containingExpression.typeCheck(env, contextItemType).optimize(opt, env, contextItemType); 124 } 125 return offer.containingExpression; 126 } 127 128 129 138 139 public int computeDependencies() { 140 int dependencies = 0; 143 dependencies |= select.getDependencies(); 144 dependencies |= (action.getDependencies() & ~StaticProperty.DEPENDS_ON_FOCUS); 145 return dependencies; 146 } 147 148 149 154 155 protected void promoteInst(PromotionOffer offer) throws XPathException { 156 select = doPromotion(select, offer); 157 action = doPromotion(action, offer); 158 } 159 160 165 166 public Iterator iterateSubExpressions() { 167 return new PairIterator(select, action); 168 } 169 170 175 176 public int getImplementationMethod() { 177 return ITERATE_METHOD | PROCESS_METHOD; 178 } 179 180 187 188 public void checkPermittedContents(SchemaType parentType, StaticContext env, boolean whole) throws XPathException { 189 action.checkPermittedContents(parentType, env, false); 190 } 191 192 public TailCall processLeavingTail(XPathContext context) throws XPathException { 193 Controller controller = context.getController(); 194 SequenceIterator iter = select.iterate(context); 195 196 XPathContextMajor c2 = context.newContext(); 197 c2.setOrigin(this); 198 c2.setCurrentIterator(iter); 199 c2.setCurrentTemplate(null); 200 201 if (controller.isTracing()) { 202 TraceListener listener = controller.getTraceListener(); 203 while(true) { 204 Item item = iter.next(); 205 if (item == null) { 206 break; 207 } 208 listener.startCurrentItem(item); 209 action.process(c2); 210 listener.endCurrentItem(item); 211 } 212 } else { 213 while(true) { 214 Item item = iter.next(); 215 if (item == null) { 216 break; 217 } 218 action.process(c2); 219 } 220 } 221 return null; 222 } 223 224 240 241 public SequenceIterator iterate(XPathContext context) throws XPathException { 242 SequenceIterator master = select.iterate(context); 243 XPathContextMajor c2 = context.newContext(); 244 c2.setOrigin(this); 245 c2.setCurrentTemplate(null); 246 c2.setCurrentIterator(master); 247 master = new MappingIterator(master, this, c2); 248 return master; 249 } 250 251 261 262 public Object map(Item item, XPathContext context) throws XPathException { 263 return action.iterate(context); 264 } 265 266 273 274 public void display(int level, NamePool pool, PrintStream out) { 275 out.println(ExpressionTool.indent(level) + "for-each"); 276 select.display(level+1, pool, out); 277 out.println(ExpressionTool.indent(level) + "return"); 278 action.display(level+1, pool, out); 279 } 280 281 } 282 283 | Popular Tags |