Source Code Cross Referenced for XQueryExpression.java in  » XML » XPath-Saxon » net » sf » saxon » query » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML » XPath Saxon » net.sf.saxon.query 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package net.sf.saxon.query;
002:
003:        import net.sf.saxon.Configuration;
004:        import net.sf.saxon.Controller;
005:        import net.sf.saxon.event.*;
006:        import net.sf.saxon.expr.*;
007:        import net.sf.saxon.instruct.Bindery;
008:        import net.sf.saxon.instruct.DocumentInstr;
009:        import net.sf.saxon.instruct.Executable;
010:        import net.sf.saxon.instruct.SlotManager;
011:        import net.sf.saxon.om.*;
012:        import net.sf.saxon.pull.PullFromIterator;
013:        import net.sf.saxon.pull.PullNamespaceReducer;
014:        import net.sf.saxon.pull.PullProvider;
015:        import net.sf.saxon.pull.PullPushCopier;
016:        import net.sf.saxon.trace.TraceListener;
017:        import net.sf.saxon.trans.DynamicError;
018:        import net.sf.saxon.trans.UncheckedXPathException;
019:        import net.sf.saxon.trans.XPathException;
020:        import net.sf.saxon.type.Type;
021:        import net.sf.saxon.value.DateTimeValue;
022:        import net.sf.saxon.value.Value;
023:
024:        import javax.xml.transform.ErrorListener;
025:        import javax.xml.transform.Result;
026:        import javax.xml.transform.TransformerException;
027:        import javax.xml.transform.stream.StreamResult;
028:        import java.io.OutputStream;
029:        import java.util.*;
030:
031:        /**
032:         * XQueryExpression represents a compiled query. This object is immutable and thread-safe,
033:         * the same compiled query may be executed many times in series or in parallel. The object
034:         * can be created only by using the compileQuery method of the QueryProcessor class.
035:         * <p/>
036:         * <p>Various methods are provided for evaluating the query, with different options for
037:         * delivery of the results.</p>
038:         */
039:        public class XQueryExpression implements  Container {
040:
041:            private Expression expression;
042:            private SlotManager stackFrameMap;
043:            private Executable executable;
044:            private StaticQueryContext staticContext;
045:
046:            // The documentInstruction is a document{...} wrapper around the expression as written by the user
047:            private DocumentInstr documentInstruction;
048:
049:            /**
050:             * The constructor is protected, to ensure that instances can only be
051:             * created using the compileQuery() methods of StaticQueryContext
052:             */
053:
054:            protected XQueryExpression(Expression exp, Executable exec,
055:                    StaticQueryContext staticEnv, Configuration config)
056:                    throws XPathException {
057:                stackFrameMap = staticEnv.getStackFrameMap();
058:                executable = exec;
059:                if (exp instanceof  ComputedExpression) {
060:                    ((ComputedExpression) exp).setParentExpression(this );
061:                }
062:                ExpressionTool.makeParentReferences(exp);
063:                try {
064:                    exp = exp.simplify(staticEnv);
065:                    exp = exp.typeCheck(staticEnv, Type.ITEM_TYPE);
066:                    exp = exp.optimize(exec.getConfiguration().getOptimizer(),
067:                            staticEnv, Type.ITEM_TYPE);
068:                } catch (XPathException err) {
069:                    config.reportFatalError(err);
070:                    throw err;
071:                }
072:                ExpressionTool.allocateSlots(exp, 0, staticEnv
073:                        .getStackFrameMap());
074:
075:                expression = exp;
076:                executable.setConfiguration(config);
077:                executable.setDefaultCollationName(staticEnv
078:                        .getDefaultCollationName());
079:                executable.setCollationTable(staticEnv.getAllCollations());
080:                staticContext = staticEnv;
081:
082:            }
083:
084:            /**
085:             * Get the expression wrapped in this XQueryExpression object
086:             *
087:             * @return the underlying expression
088:             */
089:
090:            public Expression getExpression() {
091:                return expression;
092:            }
093:
094:            /**
095:             * Get the static context in which this expression was compiled. Note, this will be an internal
096:             * copy of the original user-created StaticQueryContext object. The user-created object is not modified
097:             * by Saxon, whereas the copy includes additional information found in the query prolog.
098:             *
099:             * @return the internal copy of the StaticQueryContext
100:             */
101:            public StaticQueryContext getStaticContext() {
102:                return staticContext;
103:            }
104:
105:            protected void setDocumentInstruction(DocumentInstr doc) {
106:                documentInstruction = doc;
107:                doc.setParentExpression(this );
108:            }
109:
110:            /**
111:             * Execute a the compiled Query, returning the results as a List.
112:             *
113:             * @param env Provides the dynamic query evaluation context
114:             * @return The results of the expression, as a List. The List represents the sequence
115:             *         of items returned by the expression. Each item in the list will either be an
116:             *         object representing a node, or an object representing an atomic value.
117:             *         For the types of Java object that may be returned, see the description of the
118:             *         {@link net.sf.saxon.xpath.XPathEvaluator#evaluate evaluate} method
119:             *         of class XPathProcessor
120:             */
121:
122:            public List evaluate(DynamicQueryContext env) throws XPathException {
123:                SequenceIterator iterator = iterator(env);
124:                ArrayList list = new ArrayList(100);
125:                while (true) {
126:                    Item item = iterator.next();
127:                    if (item == null) {
128:                        return list;
129:                    }
130:                    list.add(Value.convert(item));
131:                }
132:            }
133:
134:            /**
135:             * Execute the compiled Query, returning the first item in the result.
136:             * This is useful where it is known that the expression will only return
137:             * a singleton value (for example, a single node, or a boolean).
138:             *
139:             * @param env Provides the dynamic query evaluation context
140:             * @return The first item in the sequence returned by the expression. If the expression
141:             *         returns an empty sequence, this method returns null. Otherwise, it returns the first
142:             *         item in the result sequence, represented as a Java object using the same mapping as for
143:             *         the {@link XQueryExpression#evaluate evaluate} method
144:             */
145:
146:            public Object evaluateSingle(DynamicQueryContext env)
147:                    throws XPathException {
148:                SequenceIterator iterator = iterator(env);
149:                Item item = iterator.next();
150:                if (item == null) {
151:                    return null;
152:                }
153:                return Value.convert(item);
154:            }
155:
156:            /**
157:             * Get an iterator over the results of the expression. This returns results without
158:             * any conversion of the returned items to "native" Java classes. The iterator will
159:             * deliver a sequence of Item objects, each item being either a NodeInfo (representing
160:             * a node) or an AtomicValue (representing an atomic value).
161:             * <p/>
162:             * <p>To get the results of the query in the form of an XML document in which each
163:             * item is wrapped by an element indicating its type, use:</p>
164:             * <p/>
165:             * <p><code>QueryResult.wrap(iterator(env))</code></p>
166:             * <p/>
167:             * <p>To serialize the results to a file, use the QueryResult.serialize() method.</p>
168:             *
169:             * @param env Provides the dynamic query evaluation context
170:             * @return an iterator over the results of the query. The class SequenceIterator
171:             *         is modeled on the standard Java Iterator class, but has extra functionality
172:             *         and can throw exceptions when errors occur.
173:             * @throws XPathException if a dynamic error occurs in evaluating the query. Some
174:             *                        dynamic errors will not be reported by this method, but will only be reported
175:             *                        when the individual items of the result are accessed using the returned iterator.
176:             */
177:
178:            public SequenceIterator iterator(DynamicQueryContext env)
179:                    throws XPathException {
180:                Controller controller = newController();
181:                initializeController(env, controller);
182:
183:                try {
184:                    NodeInfo node = env.getContextNode();
185:
186:                    Bindery bindery = controller.getBindery();
187:                    //bindery.openStackFrame();
188:                    controller.defineGlobalParameters(bindery);
189:                    XPathContextMajor context = controller.newXPathContext();
190:
191:                    if (node != null) {
192:                        AxisIterator single = SingletonIterator
193:                                .makeIterator(node);
194:                        single.next();
195:                        context.setCurrentIterator(single);
196:                        controller.setPrincipalSourceDocument(node
197:                                .getDocumentRoot());
198:                    }
199:
200:                    // In tracing/debugging mode, evaluate all the global variables first
201:                    if (controller.getConfiguration().getTraceListener() != null) {
202:                        controller.preEvaluateGlobals(context);
203:                    }
204:
205:                    context.openStackFrame(stackFrameMap);
206:
207:                    SequenceIterator iterator = expression.iterate(context);
208:                    return new ErrorReportingIterator(iterator, controller
209:                            .getErrorListener());
210:                } catch (XPathException err) {
211:                    TransformerException terr = err;
212:                    while (terr.getException() instanceof  TransformerException) {
213:                        terr = (TransformerException) terr.getException();
214:                    }
215:                    DynamicError de = DynamicError.makeDynamicError(terr);
216:                    controller.reportFatalError(de);
217:                    throw de;
218:                }
219:            }
220:
221:            private void initializeController(DynamicQueryContext env,
222:                    Controller controller) {
223:                HashMap parameters = env.getParameters();
224:                if (parameters != null) {
225:                    Iterator iter = parameters.keySet().iterator();
226:                    while (iter.hasNext()) {
227:                        String paramName = (String) iter.next();
228:                        Object paramValue = parameters.get(paramName);
229:                        controller.setParameter(paramName, paramValue);
230:                    }
231:                }
232:
233:                controller.setURIResolver(env.getURIResolver());
234:                controller.setErrorListener(env.getErrorListener());
235:                DateTimeValue currentDateTime = env.getCurrentDateTime();
236:                if (currentDateTime != null) {
237:                    try {
238:                        controller.setCurrentDateTime(currentDateTime);
239:                    } catch (XPathException e) {
240:                        throw new AssertionError(e); // the value should already have been checked
241:                    }
242:                }
243:            }
244:
245:            /**
246:             * Run the query, sending the results directly to a JAXP Result object. This way of executing
247:             * the query is most efficient in the case of queries that produce a single document (or parentless
248:             * element) as their output, because it avoids constructing the result tree in memory: instead,
249:             * it is piped straight to the serializer.
250:             *
251:             * @param env              the dynamic query context
252:             * @param result           the destination for the results of the query. The query is effectively wrapped
253:             *                         in a document{} constructor, so that the items in the result are concatenated to form a single
254:             *                         document; this is then written to the requested Result destination, which may be (for example)
255:             *                         a DOMResult, a SAXResult, or a StreamResult
256:             * @param outputProperties Supplies serialization properties, in JAXP format, if the result is to
257:             *                         be serialized. This parameter can be defaulted to null.
258:             * @throws XPathException if the query fails.
259:             */
260:
261:            public void run(DynamicQueryContext env, Result result,
262:                    Properties outputProperties) throws XPathException {
263:
264:                Controller controller = newController();
265:                initializeController(env, controller);
266:
267:                // Validate the serialization properties requested
268:
269:                Properties baseProperties = controller.getOutputProperties();
270:                if (outputProperties != null) {
271:                    Enumeration iter = outputProperties.propertyNames();
272:                    while (iter.hasMoreElements()) {
273:                        String key = (String) iter.nextElement();
274:                        String value = outputProperties.getProperty(key);
275:                        try {
276:                            SaxonOutputKeys.checkOutputProperty(key, value,
277:                                    controller.getConfiguration()
278:                                            .getNameChecker());
279:                            baseProperties.setProperty(key, value);
280:                        } catch (DynamicError dynamicError) {
281:                            try {
282:                                outputProperties.remove(key);
283:                                controller.getErrorListener().warning(
284:                                        dynamicError);
285:                            } catch (TransformerException err2) {
286:                                throw DynamicError.makeDynamicError(err2);
287:                            }
288:                        }
289:                    }
290:                }
291:                if (baseProperties.getProperty("method") == null) {
292:                    // XQuery forces the default method to XML, unlike XSLT where it depends on the contents of the result tree
293:                    baseProperties.setProperty("method", "xml");
294:                }
295:
296:                NodeInfo node = env.getContextNode();
297:
298:                Bindery bindery = controller.getBindery();
299:                controller.defineGlobalParameters(bindery);
300:
301:                XPathContextMajor context = controller.newXPathContext();
302:
303:                if (node != null) {
304:                    AxisIterator single = SingletonIterator.makeIterator(node);
305:                    context.setCurrentIterator(single);
306:                    single.next();
307:                    controller.setPrincipalSourceDocument(node
308:                            .getDocumentRoot());
309:                }
310:
311:                // In tracing/debugging mode, evaluate all the global variables first
312:                TraceListener tracer = controller.getConfiguration()
313:                        .getTraceListener();
314:                if (tracer != null) {
315:                    controller.preEvaluateGlobals(context);
316:                    tracer.open();
317:                }
318:
319:                context.openStackFrame(stackFrameMap);
320:
321:                boolean mustClose = (result instanceof  StreamResult && ((StreamResult) result)
322:                        .getOutputStream() == null);
323:                context.changeOutputDestination(baseProperties, result, true,
324:                        Validation.PRESERVE, null);
325:
326:                // Run the query
327:                try {
328:                    expression.process(context);
329:                } catch (XPathException err) {
330:                    controller.reportFatalError(err);
331:                    throw err;
332:                }
333:
334:                if (tracer != null) {
335:                    tracer.close();
336:                }
337:
338:                context.getReceiver().close();
339:                if (mustClose) {
340:                    OutputStream os = ((StreamResult) result).getOutputStream();
341:                    if (os != null) {
342:                        try {
343:                            os.close();
344:                        } catch (java.io.IOException err) {
345:                            throw new DynamicError(err);
346:                        }
347:                    }
348:                }
349:            }
350:
351:            /**
352:             * Run the query in pull mode.
353:             * <p/>
354:             * For maximum effect this method should be used when lazyConstructionMode has been set in the Configuration.
355:             *
356:             * @see Configuration#setLazyConstructionMode(boolean)
357:             */
358:
359:            public void pull(DynamicQueryContext dynamicEnv,
360:                    Result destination, Properties outputProperties)
361:                    throws XPathException {
362:                try {
363:                    SequenceIterator iter = iterator(dynamicEnv);
364:                    PullProvider pull = new PullFromIterator(iter);
365:                    pull = new PullNamespaceReducer(pull);
366:                    pull.setPipelineConfiguration(executable.getConfiguration()
367:                            .makePipelineConfiguration());
368:
369:                    Receiver receiver = ResultWrapper.getReceiver(destination,
370:                            pull.getPipelineConfiguration(), outputProperties);
371:                    //pull = new PullTracer(pull);
372:                    if ("yes".equals(outputProperties
373:                            .getProperty(SaxonOutputKeys.WRAP))) {
374:                        NamespaceReducer reducer = new NamespaceReducer();
375:                        reducer.setPipelineConfiguration(pull
376:                                .getPipelineConfiguration());
377:                        reducer.setUnderlyingReceiver(receiver);
378:                        receiver = new SequenceWrapper(reducer);
379:                    }
380:                    if (!(receiver instanceof  SequenceWrapper)) {
381:                        receiver = new TreeReceiver(receiver);
382:                    }
383:                    new PullPushCopier(pull, receiver).copy();
384:                } catch (UncheckedXPathException e) {
385:                    throw e.getXPathException();
386:                }
387:            }
388:
389:            /**
390:             * Get a controller that can be used to execute functions in this compiled query.
391:             * Functions in the query module can be found using {@link StaticQueryContext#getUserDefinedFunction}.
392:             * They can then be called directly from the Java application using {@link net.sf.saxon.instruct.UserFunction#call}
393:             * The same Controller can be used for a series of function calls.
394:             * <p/>
395:             * Note, this method is poorly named. It creates a new Controller each time it is called: which is useful
396:             * when a query is to be executed repeatedly.
397:             */
398:
399:            public Controller newController() {
400:                Controller controller = new Controller(executable
401:                        .getConfiguration(), executable);
402:                executable.initialiseBindery(controller.getBindery());
403:                return controller;
404:            }
405:
406:            /**
407:             * Deprecated synonym for {@link #newController}
408:             * @deprecated since 8.5.1 - use newController()
409:             */
410:
411:            public Controller getController() {
412:                return newController();
413:            }
414:
415:            /**
416:             * Diagnostic method: display a representation of the compiled query on the
417:             * System.err output stream.
418:             */
419:
420:            public void explain(NamePool pool) {
421:                System.err
422:                        .println("============ Compiled Expression ============");
423:                expression.display(10, pool, System.err);
424:                System.err
425:                        .println("=============================================");
426:            }
427:
428:            /**
429:             * Get the Executable (representing a complete stylesheet or query) of which this Container forms part
430:             */
431:
432:            public Executable getExecutable() {
433:                return executable;
434:            }
435:
436:            /**
437:             * Get the LocationProvider allowing location identifiers to be resolved.
438:             */
439:
440:            public LocationProvider getLocationProvider() {
441:                return executable.getLocationMap();
442:            }
443:
444:            /**
445:             * Return the public identifier for the current document event.
446:             * <p/>
447:             * <p>The return value is the public identifier of the document
448:             * entity or of the external parsed entity in which the markup that
449:             * triggered the event appears.</p>
450:             *
451:             * @return A string containing the public identifier, or
452:             *         null if none is available.
453:             * @see #getSystemId
454:             */
455:            public String getPublicId() {
456:                return null;
457:            }
458:
459:            /**
460:             * Return the system identifier for the current document event.
461:             * <p/>
462:             * <p>The return value is the system identifier of the document
463:             * entity or of the external parsed entity in which the markup that
464:             * triggered the event appears.</p>
465:             * <p/>
466:             * <p>If the system identifier is a URL, the parser must resolve it
467:             * fully before passing it to the application.</p>
468:             *
469:             * @return A string containing the system identifier, or null
470:             *         if none is available.
471:             * @see #getPublicId
472:             */
473:            public String getSystemId() {
474:                return null;
475:            }
476:
477:            /**
478:             * Return the line number where the current document event ends.
479:             * <p/>
480:             * <p><strong>Warning:</strong> The return value from the method
481:             * is intended only as an approximation for the sake of error
482:             * reporting; it is not intended to provide sufficient information
483:             * to edit the character content of the original XML document.</p>
484:             * <p/>
485:             * <p>The return value is an approximation of the line number
486:             * in the document entity or external parsed entity where the
487:             * markup that triggered the event appears.</p>
488:             *
489:             * @return The line number, or -1 if none is available.
490:             * @see #getColumnNumber
491:             */
492:            public int getLineNumber() {
493:                return -1;
494:            }
495:
496:            /**
497:             * Return the character position where the current document event ends.
498:             * <p/>
499:             * <p><strong>Warning:</strong> The return value from the method
500:             * is intended only as an approximation for the sake of error
501:             * reporting; it is not intended to provide sufficient information
502:             * to edit the character content of the original XML document.</p>
503:             * <p/>
504:             * <p>The return value is an approximation of the column number
505:             * in the document entity or external parsed entity where the
506:             * markup that triggered the event appears.</p>
507:             *
508:             * @return The column number, or -1 if none is available.
509:             * @see #getLineNumber
510:             */
511:            public int getColumnNumber() {
512:                return -1;
513:            }
514:
515:            /**
516:             * ErrorReportingIterator is an iterator that wraps a base iterator and reports
517:             * any exceptions that are raised to the ErrorListener
518:             */
519:
520:            private class ErrorReportingIterator implements  SequenceIterator {
521:                private SequenceIterator base;
522:                private ErrorListener listener;
523:
524:                public ErrorReportingIterator(SequenceIterator base,
525:                        ErrorListener listener) {
526:                    this .base = base;
527:                    this .listener = listener;
528:                }
529:
530:                public Item next() throws XPathException {
531:                    try {
532:                        return base.next();
533:                    } catch (XPathException e1) {
534:                        if (e1.getLocator() == null) {
535:                            e1
536:                                    .setLocator(ExpressionTool
537:                                            .getLocator(expression));
538:                        }
539:                        try {
540:                            listener.fatalError(e1);
541:                        } catch (TransformerException e2) {
542:                            //
543:                        }
544:                        e1.setHasBeenReported();
545:                        throw e1;
546:                    }
547:                }
548:
549:                public Item current() {
550:                    return base.current();
551:                }
552:
553:                public int position() {
554:                    return base.position();
555:                }
556:
557:                public SequenceIterator getAnother() throws XPathException {
558:                    return new ErrorReportingIterator(base.getAnother(),
559:                            listener);
560:                }
561:
562:                /**
563:                 * Get properties of this iterator, as a bit-significant integer.
564:                 *
565:                 * @return the properties of this iterator. This will be some combination of
566:                 *         properties such as {@link GROUNDED}, {@link LAST_POSITION_FINDER},
567:                 *         and {@link LOOKAHEAD}. It is always
568:                 *         acceptable to return the value zero, indicating that there are no known special properties.
569:                 *         It is acceptable for the properties of the iterator to change depending on its state.
570:                 */
571:
572:                public int getProperties() {
573:                    return 0;
574:                }
575:            }
576:
577:        }
578:
579:        //
580:        // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
581:        // you may not use this file except in compliance with the License. You may obtain a copy of the
582:        // License at http://www.mozilla.org/MPL/
583:        //
584:        // Software distributed under the License is distributed on an "AS IS" basis,
585:        // WITHOUT WARRANTY OF ANY KIND, either express or implied.
586:        // See the License for the specific language governing rights and limitations under the License.
587:        //
588:        // The Original Code is: all this file.
589:        //
590:        // The Initial Developer of the Original Code is Michael H. Kay
591:        //
592:        // Contributor(s):
593:        //
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.