001: package net.sf.saxon.functions;
002:
003: import net.sf.saxon.Controller;
004: import net.sf.saxon.event.Receiver;
005: import net.sf.saxon.expr.Expression;
006: import net.sf.saxon.expr.StaticContext;
007: import net.sf.saxon.expr.StaticProperty;
008: import net.sf.saxon.expr.XPathContext;
009: import net.sf.saxon.om.Item;
010: import net.sf.saxon.trans.XPathException;
011: import net.sf.saxon.value.AtomicValue;
012: import net.sf.saxon.value.BooleanValue;
013:
014: import javax.xml.transform.ErrorListener;
015: import javax.xml.transform.TransformerException;
016:
017: /**
018: * Implement the fn:doc() function - a simplified form of the Document function
019: */
020:
021: public class Doc extends SystemFunction {
022:
023: public static final int DOC = 0;
024: public static final int DOC_AVAILABLE = 1;
025:
026: private String expressionBaseURI = null;
027:
028: public void checkArguments(StaticContext env) throws XPathException {
029: if (expressionBaseURI == null) {
030: super .checkArguments(env);
031: expressionBaseURI = env.getBaseURI();
032: }
033: }
034:
035: /**
036: * preEvaluate: this method suppresses compile-time evaluation by doing nothing
037: */
038:
039: public Expression preEvaluate(StaticContext env) {
040: return this ;
041: }
042:
043: public Item evaluateItem(XPathContext context)
044: throws XPathException {
045: if (operation == DOC) {
046: return doc(context);
047: } else {
048: // operation == DOC_AVAILABLE
049: try {
050: Controller controller = context.getController();
051: // suppress all error messages while attempting to fetch the document
052: ErrorListener old = controller.getErrorListener();
053: controller.setErrorListener(new ErrorListener() {
054: public void warning(TransformerException exception) {
055: }
056:
057: public void error(TransformerException exception) {
058: }
059:
060: public void fatalError(
061: TransformerException exception) {
062: }
063: });
064: Item item = doc(context);
065: controller.setErrorListener(old);
066: return BooleanValue.get(item != null);
067: } catch (XPathException err) {
068: return BooleanValue.FALSE;
069: }
070: }
071: }
072:
073: /**
074: * Get the static properties of this expression (other than its type). The result is
075: * bit-signficant. These properties are used for optimizations. In general, if
076: * property bit is set, it is true, but if it is unset, the value is unknown.
077: */
078:
079: public int computeSpecialProperties() {
080: return StaticProperty.ORDERED_NODESET
081: | StaticProperty.PEER_NODESET
082: | StaticProperty.NON_CREATIVE;
083: // Declaring it as a peer node-set expression avoids sorting of expressions such as
084: // doc(XXX)/a/b/c
085: // The doc() function might appear to be creative: but it isn't, because multiple calls
086: // with the same arguments will produce identical results.
087: }
088:
089: private Item doc(XPathContext context) throws XPathException {
090: AtomicValue hrefVal = (AtomicValue) argument[0]
091: .evaluateItem(context);
092: if (hrefVal == null) {
093: return null;
094: }
095: String href = hrefVal.getStringValue();
096: Item item = Document.makeDoc(href, expressionBaseURI, context,
097: this );
098: if (item == null) {
099: // we failed to read the document
100: dynamicError("Failed to load document " + href, "FODC0005",
101: context);
102: return null;
103: }
104: return item;
105: }
106:
107: /**
108: * Copy the document identified by this expression to a given Receiver. This method is used only when it is
109: * known that the document is being copied, because there is then no problem about node identity.
110: */
111:
112: public void sendDocument(XPathContext context, Receiver out)
113: throws XPathException {
114: AtomicValue hrefVal = (AtomicValue) argument[0]
115: .evaluateItem(context);
116: if (hrefVal == null) {
117: return;
118: }
119: String href = hrefVal.getStringValue();
120: Document.sendDoc(href, expressionBaseURI, context, this , out);
121: }
122:
123: }
124:
125: //
126: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
127: // you may not use this file except in compliance with the License. You may obtain a copy of the
128: // License at http://www.mozilla.org/MPL/
129: //
130: // Software distributed under the License is distributed on an "AS IS" basis,
131: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
132: // See the License for the specific language governing rights and limitations under the License.
133: //
134: // The Original Code is: all this file.
135: //
136: // The Initial Developer of the Original Code is Michael H. Kay.
137: //
138: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
139: //
140: // Contributor(s): none.
141: //
|