1 22 23 package org.xquark.mediator.plan; 24 25 import java.util.ArrayList ; 26 27 import org.xml.sax.ContentHandler ; 28 import org.xquark.mediator.DOMUtils.*; 29 import org.xquark.mediator.runtime.MediatorException; 30 import org.xquark.schema.validation.PSVInfoSetProvider; 31 import org.xquark.xml.xdbc.XMLDBCException; 32 import org.xquark.xquery.parser.Step; 33 import org.xquark.xquery.parser.XQueryException; 34 import org.xquark.xquery.parser.XQueryExpression; 35 import org.xquark.xquery.typing.QAtomicSerializer; 36 37 public abstract class ResultSet { 38 private static final String RCSRevision = "$Revision: 1.16 $"; 42 private static final String RCSName = "$Name: $"; 43 protected TypedDOMReader dom2sax = null; 47 protected QAtomicSerializer ser = null; 48 49 protected XQueryExpression expression = null; 50 protected Operator operator; 51 private boolean first_time = true; 52 private boolean finished_when_empty = false; 53 54 protected BufferTuple buftuples = null; 55 private Tuple cur_tuple = null; 56 private Tuple next_tuple = null; 57 protected ArrayList paths; 58 59 protected DynamicContext context = null; 60 61 67 public ResultSet(Operator operator, DynamicContext context) { 68 this.operator = operator; 69 this.context = context; 70 dom2sax = new TypedDOMReader(); 71 ser = new QAtomicSerializer(); 72 dom2sax.setQAtomicSerializer(ser); 73 init(operator); 74 } 75 76 public void init(Operator operator) { 77 if (operator != null) { 78 expression = operator.getExpression(); 79 paths = operator.getPaths(); 80 buftuples = new BufferTuple(paths, operator.getIdSize()); 81 buftuples.setIndexesSpec(operator.getIndexesSpec()); 82 } 83 } 84 85 protected void generateTuple() throws MediatorException { 86 if (!buftuples.isEmpty()) 88 return; 89 90 evaluate(!operator.isLet()); 92 } 93 94 100 protected abstract void evaluate(boolean non_blocking) throws MediatorException; 101 102 protected void setFinishedWhenEmpty() throws MediatorException { 103 this.finished_when_empty = true; 104 } 105 106 public Operator getOperator() { 107 return operator; 108 } 109 110 public SortedKeyMap getIndex(int index) { 111 return buftuples.getIndex(index); 112 } 113 114 119 public Tuple next() throws MediatorException { 120 if (next_tuple != null) { 121 cur_tuple = next_tuple; 122 next_tuple = null; 123 return cur_tuple; 124 } 125 126 if (first_time) { 127 hasNext(); 128 if (buftuples.isEmpty()) 129 throw new MediatorException("No more results"); 130 } 131 132 if (buftuples.isEmpty()) { 134 generateTuple(); 135 if (buftuples.isEmpty()) 136 throw new MediatorException("No more results"); 137 } 138 139 if (!buftuples.isEmpty()) { 140 cur_tuple = (Tuple) buftuples.remove(0); 141 return cur_tuple; 142 } 143 144 return cur_tuple; 145 } 146 147 151 public boolean hasNext() throws MediatorException { 152 153 if (next_tuple != null) 154 return true; 155 156 if (first_time) { 157 generateTuple(); 158 first_time = false; 159 } 160 161 if ((finished_when_empty) && (buftuples == null || buftuples.isEmpty())) 162 return false; 163 164 if (buftuples.isEmpty()) 165 generateTuple(); 166 167 return (!((finished_when_empty) && (buftuples == null || buftuples.isEmpty()))); 168 } 169 170 179 public void close() throws MediatorException { 180 buftuples = null; 181 } 182 183 191 public String fetch(String path, int nodeAccessor, String loopID, PSVInfoSetProvider psvisp) throws XMLDBCException { 192 String alias = path; 193 while ((alias = operator.getPlan().getAlias(path)) != null) { 194 path = alias; 195 } 196 int pos = buftuples.getPos(path); 198 if (pos != -1) 199 return cur_tuple.makeStringPath(pos, ser); 200 switch (nodeAccessor) { 201 case Step.CHILD_TEXT : 202 pos = buftuples.getPos(path + "/child::text()"); 204 break; 205 209 case Step.CHILD_NODE : 210 pos = buftuples.getPos(path + "/child::node()"); 212 break; 213 229 case Step.SELF_TEXT : 230 pos = buftuples.getPos(path + "/self::text()"); 232 break; 233 case Step.SELF_NODE : 234 pos = buftuples.getPos(path + "/self::node()"); 236 break; 237 } 238 if (pos == -1) 239 pos = buftuples.getPos(path); 240 if (pos == -1) 241 throw new XMLDBCException("No column " + path + " in tuple."); 242 return cur_tuple.makeStringPath(pos, ser); 243 } 245 246 253 public void generate(ContentHandler handler, String path, int nodeAccessor, String loopID, PSVInfoSetProvider psvisp) throws XMLDBCException { 254 String alias = path; 255 while ((alias = operator.getPlan().getAlias(path)) != null) { 256 path = alias; 257 } 258 int pos = -1; 260 switch (nodeAccessor) { 261 case Step.CHILD_TEXT : 262 pos = buftuples.getPos(path + "/child::text()"); 264 break; 265 269 case Step.CHILD_NODE : 270 pos = buftuples.getPos(path + "/child::node()"); 272 break; 273 289 case Step.SELF_TEXT : 290 pos = buftuples.getPos(path + "/self::text()"); 292 break; 293 case Step.SELF_NODE : 294 pos = buftuples.getPos(path + "/self::node()"); 296 break; 297 } 298 if (pos == -1) 299 pos = buftuples.getPos(path); 300 if (pos == -1) 301 throw new XMLDBCException("No column " + path + " in tuple."); 302 try { 303 dom2sax.setPSVInfoSetProvider(psvisp); 304 cur_tuple.makeEventPath(dom2sax, handler, pos); 305 } catch (XQueryException e) { 306 throw new XMLDBCException(e.getMessage()); 307 } 308 } 309 310 315 public void getIdentifiers(Object [] identifiers) { 316 if (cur_tuple == null) 317 return; 318 cur_tuple.getIdentifiers(identifiers); 319 } 320 321 327 public void getNextIdentifiers(Object [] identifiers) throws MediatorException { 328 if (next_tuple != null) { 333 next_tuple.getIdentifiers(identifiers); 334 return; 335 } 336 if (!hasNext()) { 337 next_tuple = null; 338 return; 339 } 340 Tuple old_tuple = cur_tuple; 341 next(); 342 next_tuple = cur_tuple; 343 next_tuple.getIdentifiers(identifiers); 344 cur_tuple = old_tuple; 345 } 346 } 347 | Popular Tags |