001: package net.sf.saxon.xpath;
002:
003: import net.sf.saxon.expr.*;
004: import net.sf.saxon.om.SequenceIterator;
005: import net.sf.saxon.om.ValueRepresentation;
006: import net.sf.saxon.trans.DynamicError;
007: import net.sf.saxon.trans.XPathException;
008: import net.sf.saxon.type.ItemType;
009: import net.sf.saxon.type.Type;
010: import net.sf.saxon.type.TypeHierarchy;
011: import net.sf.saxon.value.SequenceType;
012: import net.sf.saxon.value.Value;
013: import net.sf.saxon.Configuration;
014:
015: import javax.xml.xpath.XPathFunction;
016: import javax.xml.xpath.XPathFunctionException;
017: import java.util.ArrayList;
018: import java.util.List;
019:
020: /**
021: * This class is an expression that calls an external function supplied using the
022: * JAXP XPathFunction interface
023: */
024:
025: public class XPathFunctionCall extends FunctionCall {
026:
027: private XPathFunction function;
028:
029: /**
030: * Default constructor
031: */
032:
033: public XPathFunctionCall(XPathFunction function) {
034: this .function = function;
035: }
036:
037: /**
038: * preEvaluate: this method suppresses compile-time evaluation by doing nothing
039: * (because the external function might have side-effects and might use the context)
040: */
041:
042: public Expression preEvaluate(StaticContext env) {
043: return this ;
044: }
045:
046: /**
047: * Method called by the expression parser when all arguments have been supplied
048: */
049:
050: public void checkArguments(StaticContext env) throws XPathException {
051: }
052:
053: /**
054: * Determine which aspects of the context the expression depends on. XPath external
055: * functions are given no access to context information so they cannot have any
056: * dependencies on it.
057: */
058:
059: public int getIntrinsicDependencies() {
060: return 0;
061: }
062:
063: /**
064: * Evaluate the function. <br>
065: * @param context The context in which the function is to be evaluated
066: * @return a Value representing the result of the function.
067: * @throws XPathException if the function cannot be evaluated.
068: */
069:
070: public SequenceIterator iterate(XPathContext context)
071: throws XPathException {
072: ValueRepresentation[] argValues = new ValueRepresentation[argument.length];
073: for (int i = 0; i < argValues.length; i++) {
074: argValues[i] = ExpressionTool.lazyEvaluate(argument[i],
075: context, 10);
076: }
077: return call(argValues, context);
078: }
079:
080: /**
081: * Call an extension function previously identified using the bind() method. A subclass
082: * can override this method.
083: * @param argValues The values of the arguments
084: * @return The value returned by the extension function
085: */
086:
087: public SequenceIterator call(ValueRepresentation[] argValues,
088: XPathContext context) throws XPathException {
089: List convertedArgs = new ArrayList(argValues.length);
090: for (int i = 0; i < argValues.length; i++) {
091: convertedArgs.add(Value.asValue(argValues[i])
092: .convertToJava(Object.class, context));
093: }
094: try {
095: Object result = function.evaluate(convertedArgs);
096: Configuration config = context.getConfiguration();
097: return Value.convertJavaObjectToXPath(result,
098: SequenceType.ANY_SEQUENCE, config).iterate(context);
099: } catch (XPathFunctionException e) {
100: throw new DynamicError(e);
101: }
102: }
103:
104: /**
105: * Determine the data type of the expression, if possible. All expressions return
106: * sequences, in general; this method determines the type of the items within the
107: * sequence, assuming that (a) this is known in advance, and (b) it is the same for
108: * all items in the sequence.
109: *
110: * <p>This method will always return a result, though it may be the best approximation
111: * that is available at the time.</p>
112: *
113: * @return the item type
114: * @param th
115: */
116:
117: public ItemType getItemType(TypeHierarchy th) {
118: return Type.ITEM_TYPE;
119: }
120:
121: /**
122: * Determine the cardinality of the result
123: * @return ZERO_OR_MORE (we don't know)
124: */
125: public int computeCardinality() {
126: return StaticProperty.ALLOWS_ZERO_OR_MORE;
127: }
128:
129: }
130:
131: //
132: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
133: // you may not use this file except in compliance with the License. You may obtain a copy of the
134: // License at http://www.mozilla.org/MPL/
135: //
136: // Software distributed under the License is distributed on an "AS IS" basis,
137: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
138: // See the License for the specific language governing rights and limitations under the License.
139: //
140: // The Original Code is: all this file.
141: //
142: // The Initial Developer of the Original Code is Michael H. Kay.
143: //
144: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
145: //
146: // Contributor(s): Gunther Schadow (changes to allow access to public fields; also wrapping
147: // of extensions and mapping of null to empty sequence).
148: //
|