001: package net.sf.saxon.query;
002:
003: import net.sf.saxon.Configuration;
004: import net.sf.saxon.StandardErrorListener;
005: import net.sf.saxon.functions.Component;
006: import net.sf.saxon.om.Item;
007: import net.sf.saxon.om.NodeInfo;
008: import net.sf.saxon.trans.DynamicError;
009: import net.sf.saxon.trans.XPathException;
010: import net.sf.saxon.value.DateTimeValue;
011:
012: import javax.xml.transform.ErrorListener;
013: import javax.xml.transform.URIResolver;
014: import java.util.HashMap;
015:
016: /**
017: * This object represents a dynamic context for query execution. This class is used
018: * by the application writer to set up aspects of the dynamic context; it is not used
019: * operationally (or modified) by the XQuery processor itself, which copies all required
020: * information into its own internal representation.
021: */
022:
023: public class DynamicQueryContext {
024:
025: private Item contextItem;
026: private HashMap parameters;
027: private Configuration config;
028: private URIResolver uriResolver;
029: private ErrorListener errorListener;
030:
031: private DateTimeValue currentDateTime;
032:
033: public DynamicQueryContext(Configuration config) {
034: this .config = config;
035: uriResolver = config.getURIResolver();
036: errorListener = config.getErrorListener();
037: if (errorListener instanceof StandardErrorListener) {
038: ((StandardErrorListener) errorListener)
039: .setRecoveryPolicy(Configuration.DO_NOT_RECOVER);
040: }
041: }
042:
043: /**
044: * Set the context item for evaluating the expression to be a node. If this method is not called,
045: * the context node will be undefined. The context node is available as the value of
046: * the expression ".".
047: * To obtain a NodeInfo by parsing a source document, see the method
048: * {@link net.sf.saxon.query.StaticQueryContext#buildDocument buildDocument}
049: * in class QueryProcessor.
050: *
051: * @param node The node that is to be the context node for the query
052: * @since 8.4
053: */
054:
055: public void setContextNode(NodeInfo node) {
056: if (node == null) {
057: throw new NullPointerException(
058: "Context node cannot be null");
059: }
060: contextItem = node;
061: }
062:
063: /**
064: * Set the context item for evaluating the expression. If this method is not called,
065: * the context node will be undefined. The context item is available as the value of
066: * the expression ".",.
067: * To obtain a node by parsing a source document, see the method
068: * {@link net.sf.saxon.query.StaticQueryContext#buildDocument buildDocument}
069: * in class QueryProcessor.
070: * @param item The item that is to be the context item for the query
071: * @since 8.4
072: */
073:
074: public void setContextItem(Item item) {
075: if (item == null) {
076: throw new NullPointerException(
077: "Context item cannot be null");
078: }
079: contextItem = item;
080: }
081:
082: /**
083: * Get the context node for the query, as set using setContextNode()
084: * or getContextItem() (provided the item is a node).
085: * @return the context node if set, or null otherwise.
086: */
087:
088: public NodeInfo getContextNode() {
089: return (contextItem instanceof NodeInfo ? (NodeInfo) contextItem
090: : null);
091: }
092:
093: /**
094: * Get the context item for the query, as set using setContextItem() or setContextNode().
095: * @return the context item if set, or null otherwise.
096: * @since 8.4
097: */
098:
099: public Item getContextItem() {
100: return contextItem;
101: }
102:
103: /**
104: * Set a parameter for the query.
105: *
106: * @param expandedName The name of the parameter in "{uri}local-name" format.
107: * It is not an error to supply a value for a parameter that has not been
108: * declared, the parameter will simply be ignored. If the parameter has
109: * been declared in the query (as an external global variable) then it
110: * will be initialized with the value supplied.
111: * @param value The value of the parameter. This can be any valid Java
112: * object. It follows the same conversion rules as a value returned
113: * from a Saxon extension function. An error will occur at query
114: * execution time if the supplied value cannot be converted to the required
115: * type as declared in the query. For precise control of the type of the
116: * value, instantiate one of the classes in the net.sf.saxon.value package,
117: * for example net.sf.saxon.value.DayTimeDuration.
118: * @since 8.4
119: */
120:
121: public void setParameter(String expandedName, Object value) {
122: if (parameters == null) {
123: parameters = new HashMap(10);
124: }
125: parameters.put(expandedName, value);
126: }
127:
128: /**
129: * Reset the parameters to an empty list.
130: */
131:
132: public void clearParameters() {
133: parameters = null;
134: }
135:
136: /**
137: * Get the actual value of a parameter to the query.
138: *
139: * @param expandedName the name of the required parameter, in
140: * "{uri}local-name" format
141: * @return the value of the parameter, if it exists, or null otherwise
142: */
143:
144: public Object getParameter(String expandedName) {
145: if (parameters == null)
146: return null;
147: return parameters.get(expandedName);
148: }
149:
150: /**
151: * Get the supplied parameters as a HashMap
152: */
153:
154: protected HashMap getParameters() {
155: return parameters;
156: }
157:
158: /**
159: * Set an object that will be used to resolve URIs used in
160: * fn:document() and related functions.
161: *
162: * @param resolver An object that implements the URIResolver interface, or
163: * null.
164: * @since 8.4
165: */
166:
167: public void setURIResolver(URIResolver resolver) {
168: // System.err.println("Setting uriresolver to " + resolver + " on " + this);
169: uriResolver = resolver;
170: }
171:
172: /**
173: * Get the URI resolver.
174: *
175: * @return the user-supplied URI resolver if there is one, or the
176: * system-defined one otherwise
177: * @since 8.4
178: */
179:
180: public URIResolver getURIResolver() {
181: return uriResolver;
182: }
183:
184: /**
185: * Set the error listener. The error listener receives reports of all run-time
186: * errors and can decide how to report them.
187: *
188: * @param listener the ErrorListener to be used
189: * @since 8.4
190: */
191:
192: public void setErrorListener(ErrorListener listener) {
193: errorListener = listener;
194: }
195:
196: /**
197: * Get the error listener.
198: *
199: * @return the ErrorListener in use
200: * @since 8.4
201: */
202:
203: public ErrorListener getErrorListener() {
204: return errorListener;
205: }
206:
207: /**
208: * Get the date and time set previously using {@link #setCurrentDateTime(net.sf.saxon.value.DateTimeValue)}
209: * or null if none has been set.
210: * @return the current date and time, if it has been set.
211: * @since 8.5
212: */
213:
214: public DateTimeValue getCurrentDateTime() {
215: return currentDateTime;
216: }
217:
218: /**
219: * Set a value to be used as the current date and time for the query. By default, the "real" current date and
220: * time are used. The main purpose of this method is that it allows repeatable results to be achieved when
221: * testing queries
222: * @param dateTime The value to be used as the current date and time. This must include a timezone.
223: * @since 8.5
224: */
225:
226: public void setCurrentDateTime(DateTimeValue dateTime)
227: throws XPathException {
228: this .currentDateTime = dateTime;
229: if (dateTime.getComponent(Component.TIMEZONE) == null) {
230: throw new DynamicError(
231: "Supplied date/time must include a timezone");
232: }
233: }
234:
235: }
236:
237: //
238: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
239: // you may not use this file except in compliance with the License. You may obtain a copy of the
240: // License at http://www.mozilla.org/MPL/
241: //
242: // Software distributed under the License is distributed on an "AS IS" basis,
243: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
244: // See the License for the specific language governing rights and limitations under the License.
245: //
246: // The Original Code is: all this file.
247: //
248: // The Initial Developer of the Original Code is Michael H. Kay
249: //
250: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
251: //
252: // Contributor(s): none
253: //
|