1 package net.sf.saxon.query; 2 3 import net.sf.saxon.Configuration; 4 import net.sf.saxon.Controller; 5 import net.sf.saxon.event.*; 6 import net.sf.saxon.expr.*; 7 import net.sf.saxon.instruct.*; 8 import net.sf.saxon.om.*; 9 import net.sf.saxon.pull.PullFromIterator; 10 import net.sf.saxon.pull.PullNamespaceReducer; 11 import net.sf.saxon.pull.PullProvider; 12 import net.sf.saxon.pull.PullPushCopier; 13 import net.sf.saxon.trace.TraceListener; 14 import net.sf.saxon.trans.DynamicError; 15 import net.sf.saxon.trans.XPathException; 16 import net.sf.saxon.trans.UncheckedXPathException; 17 import net.sf.saxon.type.Type; 18 import net.sf.saxon.value.Value; 19 import net.sf.saxon.value.DateTimeValue; 20 21 import javax.xml.transform.ErrorListener ; 22 import javax.xml.transform.Result ; 23 import javax.xml.transform.TransformerException ; 24 import javax.xml.transform.stream.StreamResult ; 25 import java.io.OutputStream ; 26 import java.util.*; 27 28 36 public class XQueryExpression implements Container { 37 38 private Expression expression; 39 private SlotManager stackFrameMap; 40 private Executable executable; 41 private StaticQueryContext staticContext; 42 43 private DocumentInstr documentInstruction; 45 46 50 51 protected XQueryExpression(Expression exp, Executable exec, StaticQueryContext staticEnv, Configuration config) 52 throws XPathException { 53 stackFrameMap = staticEnv.getStackFrameMap(); 54 executable = exec; 55 if (exp instanceof ComputedExpression) { 56 ((ComputedExpression)exp).setParentExpression(this); 57 } 58 ExpressionTool.makeParentReferences(exp); 59 try { 60 exp = exp.simplify(staticEnv); 61 exp = exp.typeCheck(staticEnv, Type.ITEM_TYPE); 62 exp = exp.optimize(exec.getConfiguration().getOptimizer(), staticEnv, Type.ITEM_TYPE); 63 } catch (XPathException err) { 64 try { 65 config.getErrorListener().fatalError(err); 66 } catch (TransformerException e2) { 67 } 69 throw err; 70 } 71 ExpressionTool.allocateSlots(exp, 0, staticEnv.getStackFrameMap()); 72 73 expression = exp; 74 executable.setConfiguration(config); 75 executable.setDefaultCollationName(staticEnv.getDefaultCollationName()); 76 executable.setCollationTable(staticEnv.getAllCollations()); 77 staticContext = staticEnv; 78 79 } 80 81 86 87 public Expression getExpression() { 88 return expression; 89 } 90 91 98 public StaticQueryContext getStaticContext() { 99 return staticContext; 100 } 101 102 protected void setDocumentInstruction(DocumentInstr doc) { 103 documentInstruction = doc; 104 doc.setParentExpression(this); 105 } 106 107 118 119 public List evaluate(DynamicQueryContext env) throws XPathException { 120 SequenceIterator iterator = iterator(env); 121 ArrayList list = new ArrayList(100); 122 while (true) { 123 Item item = iterator.next(); 124 if (item == null) { 125 return list; 126 } 127 list.add(Value.convert(item)); 128 } 129 } 130 131 142 143 public Object evaluateSingle(DynamicQueryContext env) throws XPathException { 144 SequenceIterator iterator = iterator(env); 145 Item item = iterator.next(); 146 if (item == null) { 147 return null; 148 } 149 return Value.convert(item); 150 } 151 152 173 174 public SequenceIterator iterator(DynamicQueryContext env) throws XPathException { 175 Controller controller = newController(); 176 initializeController(env, controller); 177 178 try { 179 NodeInfo node = env.getContextNode(); 180 181 Bindery bindery = controller.getBindery(); 182 controller.defineGlobalParameters(bindery); 184 XPathContextMajor context = controller.newXPathContext(); 185 187 if (controller.getConfiguration().getTraceListener() != null) { 189 controller.preEvaluateGlobals(context); 190 } 191 192 context.openStackFrame(stackFrameMap); 193 if (node != null) { 194 AxisIterator single = SingletonIterator.makeIterator(node); 195 single.next(); 196 context.setCurrentIterator(single); 197 controller.setPrincipalSourceDocument(node.getDocumentRoot()); 198 } 199 SequenceIterator iterator = expression.iterate(context); 200 return new ErrorReportingIterator(iterator, controller.getErrorListener()); 201 } catch (XPathException err) { 202 TransformerException terr = err; 203 while (terr.getException() instanceof TransformerException ) { 204 terr = (TransformerException )terr.getException(); 205 } 206 try { 207 controller.getErrorListener().fatalError(terr); 208 } catch (TransformerException e) { 209 } 211 throw DynamicError.makeDynamicError(terr); 212 } 213 } 214 215 private void initializeController(DynamicQueryContext env, Controller controller) { 216 HashMap parameters = env.getParameters(); 217 if (parameters != null) { 218 Iterator iter = parameters.keySet().iterator(); 219 while (iter.hasNext()) { 220 String paramName = (String )iter.next(); 221 Object paramValue = parameters.get(paramName); 222 controller.setParameter(paramName, paramValue); 223 } 224 } 225 226 controller.setURIResolver(env.getURIResolver()); 227 controller.setErrorListener(env.getErrorListener()); 228 DateTimeValue currentDateTime = env.getCurrentDateTime(); 229 if (currentDateTime != null) { 230 try { 231 controller.setCurrentDateTime(currentDateTime); 232 } catch (XPathException e) { 233 throw new AssertionError (e); } 235 } 236 } 237 238 253 254 public void run(DynamicQueryContext env, Result result, Properties outputProperties) throws XPathException { 255 256 Controller controller = newController(); 257 initializeController(env, controller); 258 259 261 Properties baseProperties = controller.getOutputProperties(); 262 if (outputProperties != null) { 263 Enumeration iter = outputProperties.propertyNames(); 264 while (iter.hasMoreElements()) { 265 String key = (String )iter.nextElement(); 266 String value = outputProperties.getProperty(key); 267 try { 268 SaxonOutputKeys.checkOutputProperty(key, value); 269 baseProperties.setProperty(key, value); 270 } catch (DynamicError dynamicError) { 271 try { 272 controller.getErrorListener().fatalError(dynamicError); 273 throw dynamicError; 274 } catch (TransformerException err2) { 277 throw DynamicError.makeDynamicError(err2); 278 } 279 } 280 } 281 } 282 if (baseProperties.getProperty("method") == null) { 283 baseProperties.setProperty("method", "xml"); 285 } 286 287 NodeInfo node = env.getContextNode(); 288 289 Bindery bindery = controller.getBindery(); 290 controller.defineGlobalParameters(bindery); 291 292 XPathContextMajor context = controller.newXPathContext(); 293 294 TraceListener tracer = controller.getConfiguration().getTraceListener(); 296 if (tracer != null) { 297 controller.preEvaluateGlobals(context); 298 tracer.open(); 299 } 300 301 context.openStackFrame(stackFrameMap); 302 if (node != null) { 303 AxisIterator single = SingletonIterator.makeIterator(node); 304 context.setCurrentIterator(single); 305 single.next(); 306 controller.setPrincipalSourceDocument(node.getDocumentRoot()); 307 } 308 309 boolean mustClose = (result instanceof StreamResult && 310 ((StreamResult )result).getOutputStream() == null); 311 context.changeOutputDestination(baseProperties, result, true, Validation.PRESERVE, null); 312 313 try { 315 expression.process(context); 316 } catch (XPathException err) { 324 try { 325 controller.getErrorListener().fatalError(err); 326 } catch (TransformerException e) { 327 } 329 throw err; 330 } 331 332 if (tracer != null) { 333 tracer.close(); 334 } 335 336 context.getReceiver().close(); 337 if (mustClose) { 338 OutputStream os = ((StreamResult )result).getOutputStream(); 339 if (os != null) { 340 try { 341 os.close(); 342 } catch (java.io.IOException err) { 343 throw new DynamicError(err); 344 } 345 } 346 } 347 } 348 349 356 357 public void pull(DynamicQueryContext dynamicEnv, Result destination, Properties outputProperties) throws XPathException { 358 try { 359 SequenceIterator iter = iterator(dynamicEnv); 360 PullProvider pull = new PullFromIterator(iter); 361 pull = new PullNamespaceReducer(pull); 362 pull.setPipelineConfiguration(executable.getConfiguration().makePipelineConfiguration()); 363 364 Receiver receiver = 365 ResultWrapper.getReceiver(destination, 366 pull.getPipelineConfiguration(), 367 outputProperties); 368 if ("yes".equals(outputProperties.getProperty(SaxonOutputKeys.WRAP))) { 370 NamespaceReducer reducer = new NamespaceReducer(); 371 reducer.setPipelineConfiguration(pull.getPipelineConfiguration()); 372 reducer.setUnderlyingReceiver(receiver); 373 receiver = new SequenceWrapper(reducer); 374 } 375 if (!(receiver instanceof SequenceWrapper)) { 377 receiver = new TreeReceiver(receiver); 378 } 379 new PullPushCopier(pull, receiver).copy(); 380 } catch (UncheckedXPathException e) { 381 throw e.getXPathException(); 382 } 383 } 384 385 394 395 public Controller newController() { 396 Controller controller = new Controller(executable.getConfiguration(), executable); 397 executable.initialiseBindery(controller.getBindery()); 398 return controller; 399 } 400 401 405 406 public Controller getController() { 407 return newController(); 408 } 409 410 414 415 public void explain(NamePool pool) { 416 System.err.println("============ Compiled Expression ============"); 417 expression.display(10, pool, System.err); 418 System.err.println("============================================="); 419 } 420 421 424 425 public Executable getExecutable() { 426 return executable; 427 } 428 429 432 433 public LocationProvider getLocationProvider() { 434 return executable.getLocationMap(); 435 } 436 437 448 public String getPublicId() { 449 return null; 450 } 451 452 466 public String getSystemId() { 467 return null; 468 } 469 470 485 public int getLineNumber() { 486 return -1; 487 } 488 489 504 public int getColumnNumber() { 505 return -1; 506 } 507 508 512 513 private class ErrorReportingIterator implements SequenceIterator { 514 private SequenceIterator base; 515 private ErrorListener listener; 516 517 public ErrorReportingIterator(SequenceIterator base, ErrorListener listener) { 518 this.base = base; 519 this.listener = listener; 520 } 521 522 public Item next() throws XPathException { 523 try { 524 return base.next(); 525 } catch (XPathException e1) { 526 if (e1.getLocator() == null) { 527 e1.setLocator(ExpressionTool.getLocator(expression)); 528 } 529 try { 530 listener.fatalError(e1); 531 } catch (TransformerException e2) { 532 } 533 throw e1; 534 } 535 } 536 537 public Item current() { 538 return base.current(); 539 } 540 541 public int position() { 542 return base.position(); 543 } 544 545 public SequenceIterator getAnother() throws XPathException { 546 return new ErrorReportingIterator(base.getAnother(), listener); 547 } 548 549 558 559 public int getProperties() { 560 return 0; 561 } 562 } 563 564 } 565 566 582 | Popular Tags |