1 package net.sf.saxon.sort; 2 import net.sf.saxon.expr.*; 3 import net.sf.saxon.om.EmptyIterator; 4 import net.sf.saxon.om.NamePool; 5 import net.sf.saxon.om.SequenceIterator; 6 import net.sf.saxon.trans.XPathException; 7 import net.sf.saxon.type.ItemType; 8 import net.sf.saxon.value.Cardinality; 9 import net.sf.saxon.value.Value; 10 11 import java.io.PrintStream ; 12 import java.util.ArrayList ; 13 import java.util.Iterator ; 14 import java.util.List ; 15 16 20 21 public class SortExpression extends ComputedExpression { 22 23 private Expression select = null; 24 private SortKeyDefinition[] sortKeys = null; 25 private FixedSortKeyDefinition[] fixedSortKeys = null; 26 27 public SortExpression( Expression select, 28 SortKeyDefinition[] sortKeys ) { 29 this.select = select; 30 this.sortKeys = sortKeys; 31 boolean fixed = true; 32 for (int i = 0; i < sortKeys.length; i++) { 33 if (!(sortKeys[i] instanceof FixedSortKeyDefinition)) { 34 fixed = false; 35 break; 36 }; 37 sortKeys[i].setParentExpression(this); 38 } 39 if (fixed) { 40 fixedSortKeys = new FixedSortKeyDefinition[sortKeys.length]; 41 System.arraycopy(sortKeys, 0, fixedSortKeys, 0, sortKeys.length); 42 } 43 Iterator children = iterateSubExpressions(); 44 while (children.hasNext()) { 45 Expression exp = (Expression)children.next(); 46 adoptChildExpression(exp); 47 } 48 } 49 50 56 57 public Iterator iterateSubExpressions() { 58 List list = new ArrayList (8); 59 list.add(select); 60 for (int i=0; i<sortKeys.length; i++) { 61 list.add(sortKeys[i].getSortKey()); 62 Expression e = sortKeys[i].order; 63 if (e != null && !(e instanceof Value)) { 64 list.add(e); 65 } 66 e = sortKeys[i].caseOrder; 67 if (e != null && !(e instanceof Value)) { 68 list.add(e); 69 } 70 e = sortKeys[i].dataTypeExpression; 71 if (e != null && !(e instanceof Value)) { 72 list.add(e); 73 } 74 e = sortKeys[i].language; 75 if (e != null && !(e instanceof Value)) { 76 list.add(e); 77 } 78 e = sortKeys[i].collationName; 79 if (e != null && !(e instanceof Value)) { 80 list.add(e); 81 } 82 } 83 return list.iterator(); 84 } 85 86 89 90 public Expression simplify(StaticContext env) throws XPathException { 91 select = select.simplify(env); 92 return this; 93 } 94 95 98 99 public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException { 100 select = select.typeCheck(env, contextItemType); 101 return this; 102 } 103 104 121 122 public Expression optimize(Optimizer opt, StaticContext env, ItemType contextItemType) throws XPathException { 123 if (Cardinality.allowsMany(select.getCardinality())) { 124 return this; 125 } else { 126 return select; 127 } 128 } 129 130 146 147 public Expression promote(PromotionOffer offer) throws XPathException { 148 Expression exp = offer.accept(this); 149 if (exp!=null) { 150 return exp; 151 } else { 152 select = doPromotion(select, offer); 153 for (int i=0; i<sortKeys.length; i++) { 154 sortKeys[i].setSortKey((sortKeys[i].getSortKey().promote(offer))); 155 if (sortKeys[i].caseOrder != null) { 156 sortKeys[i].caseOrder = sortKeys[i].caseOrder.promote(offer); 157 } 158 if (sortKeys[i].dataTypeExpression != null) { 159 sortKeys[i].dataTypeExpression = sortKeys[i].dataTypeExpression.promote(offer); 160 } 161 if (sortKeys[i].language != null) { 162 sortKeys[i].language = sortKeys[i].language.promote(offer); 163 } 164 if (sortKeys[i].collationName != null) { 165 sortKeys[i].collationName = sortKeys[i].collationName.promote(offer); 166 } 167 } 168 return this; 169 } 170 } 171 172 175 176 public boolean isSortKey(Expression child) { 177 for (int i=0; i<sortKeys.length; i++) { 178 Expression exp = sortKeys[i].getSortKey(); 179 if (exp == child) { 180 return true; 181 } 182 } 183 return false; 184 } 185 186 189 190 public int computeCardinality() { 191 return select.getCardinality(); 192 } 193 194 199 200 public ItemType getItemType() { 201 return select.getItemType(); 202 } 203 208 209 public int computeSpecialProperties() { 210 int props = 0; 211 if ((select.getSpecialProperties() & StaticProperty.CONTEXT_DOCUMENT_NODESET) != 0) { 212 props |= StaticProperty.CONTEXT_DOCUMENT_NODESET; 213 } 214 if ((select.getSpecialProperties() & StaticProperty.SINGLE_DOCUMENT_NODESET) != 0) { 215 props |= StaticProperty.SINGLE_DOCUMENT_NODESET; 216 } 217 if ((select.getSpecialProperties() & StaticProperty.NON_CREATIVE) != 0) { 218 props |= StaticProperty.NON_CREATIVE; 219 } 220 return props; 221 } 222 223 226 227 public SequenceIterator iterate(XPathContext context) throws XPathException { 228 229 SequenceIterator iter = select.iterate(context); 230 if (iter instanceof EmptyIterator) { 231 return iter; 232 } 233 XPathContext xpc = context.newMinorContext(); 234 xpc.setOrigin(this); 235 236 FixedSortKeyDefinition[] reducedSortKeys; 237 if (fixedSortKeys != null) { 238 reducedSortKeys = fixedSortKeys; 239 } else { 240 reducedSortKeys = new FixedSortKeyDefinition[sortKeys.length]; 241 for (int s=0; s<sortKeys.length; s++) { 242 reducedSortKeys[s] = sortKeys[s].reduce(xpc); 243 } 244 } 245 iter = new SortedIterator( xpc, 246 iter, 247 reducedSortKeys); 248 return iter; 249 } 250 251 public void display(int level, NamePool pool, PrintStream out) { 252 out.println(ExpressionTool.indent(level) + "sort"); 253 select.display(level+1, pool, out); 254 } 255 } 256 257 258 259 260 261 | Popular Tags |