1 package net.sf.saxon.sort; 2 3 import net.sf.saxon.expr.Expression; 4 import net.sf.saxon.expr.XPathContext; 5 import net.sf.saxon.om.Item; 6 import net.sf.saxon.om.ListIterator; 7 import net.sf.saxon.om.LookaheadIterator; 8 import net.sf.saxon.om.SequenceIterator; 9 import net.sf.saxon.trans.DynamicError; 10 import net.sf.saxon.trans.XPathException; 11 import net.sf.saxon.value.AtomicValue; 12 13 import java.util.ArrayList ; 14 import java.util.Comparator ; 15 import java.util.List ; 16 17 22 23 public class GroupAdjacentIterator implements GroupIterator, LookaheadIterator { 24 25 private SequenceIterator population; 26 private Expression keyExpression; 27 private Comparator collator; 28 private AtomicSortComparer comparer; 29 private AtomicSortComparer.ComparisonKey currentComparisonKey; 30 private XPathContext baseContext; 31 private XPathContext runningContext; 32 private AtomicValue currentKey = null; 33 private List currentMembers; 34 private AtomicValue nextKey = null; 35 private Item next; 36 private Item current = null; 37 private int position = 0; 38 39 public GroupAdjacentIterator(SequenceIterator population, Expression keyExpression, 40 XPathContext baseContext, Comparator collator) 41 throws XPathException { 42 this.population = population; 43 this.keyExpression = keyExpression; 44 this.baseContext = baseContext; 45 this.runningContext = baseContext.newMinorContext(); 46 runningContext.setCurrentIterator(population); 48 this.collator = collator; 49 this.comparer = new AtomicSortComparer(collator, baseContext); 50 next = population.next(); 51 if (next != null) { 52 nextKey = (AtomicValue)keyExpression.evaluateItem(runningContext); 53 } 54 } 55 56 private void advance() throws XPathException { 57 currentMembers = new ArrayList (20); 58 currentMembers.add(current); 59 while (true) { 60 Item nextCandidate = population.next(); 61 if (nextCandidate == null) { 62 break; 63 } 64 AtomicValue candidateKey = 65 (AtomicValue)keyExpression.evaluateItem(runningContext); 66 try { 67 if (currentComparisonKey.equals(comparer.getComparisonKey(candidateKey))) { 68 currentMembers.add(nextCandidate); 69 } else { 70 next = nextCandidate; 71 nextKey = candidateKey; 72 return; 73 } 74 } catch (ClassCastException e) { 75 DynamicError err = new DynamicError("Grouping key values are of non-comparable types (" + 76 currentKey.getItemType() + 77 " and " + 78 candidateKey.getItemType() + ')'); 79 err.setIsTypeError(true); 80 err.setXPathContext(runningContext); 81 throw err; 82 } 83 } 84 next = null; 85 nextKey = null; 86 } 87 88 public AtomicValue getCurrentGroupingKey() { 89 return currentKey; 90 } 91 92 public SequenceIterator iterateCurrentGroup() { 93 return new ListIterator(currentMembers); 94 } 95 96 public boolean hasNext() { 97 return next != null; 98 } 99 100 public Item next() throws XPathException { 101 if (next == null) { 102 current = null; 103 position = -1; 104 return null; 105 } 106 current = next; 107 currentKey = nextKey; 108 currentComparisonKey = comparer.getComparisonKey(currentKey); 109 position++; 110 advance(); 111 return current; 112 } 113 114 public Item current() { 115 return current; 116 } 117 118 public int position() { 119 return position; 120 } 121 122 public SequenceIterator getAnother() throws XPathException { 123 return new GroupAdjacentIterator(population.getAnother(), keyExpression, baseContext, collator); 124 } 125 126 135 136 public int getProperties() { 137 return LOOKAHEAD; 138 } 139 140 141 } 142 143 144 | Popular Tags |