001: package net.sf.saxon.functions;
002:
003: import net.sf.saxon.expr.*;
004: import net.sf.saxon.om.Item;
005: import net.sf.saxon.trans.XPathException;
006: import net.sf.saxon.value.AtomicValue;
007: import net.sf.saxon.value.IntegerValue;
008: import net.sf.saxon.value.StringValue;
009:
010: /**
011: * Implement the XPath string-length() function
012: */
013:
014: public class StringLength extends SystemFunction {
015:
016: private boolean shortcut = false;
017:
018: // if this is set we return 0 for a zero length string,
019: // 1 for any other. Used by the optimizer.
020: /**
021: * Simplify and validate.
022: * This is a pure function so it can be simplified in advance if the arguments are known
023: */
024:
025: public Expression simplify(StaticContext env) throws XPathException {
026: //useContextItemAsDefault();
027: return simplifyArguments(env);
028: }
029:
030: /**
031: * Determine the intrinsic dependencies of an expression, that is, those which are not derived
032: * from the dependencies of its subexpressions. For example, position() has an intrinsic dependency
033: * on the context position, while (position()+1) does not. The default implementation
034: * of the method returns 0, indicating "no dependencies".
035: *
036: * @return a set of bit-significant flags identifying the "intrinsic"
037: * dependencies. The flags are documented in class net.sf.saxon.value.StaticProperty
038: */
039:
040: public int getIntrinsicDependencies() {
041: int d = super .getIntrinsicDependencies();
042: if (argument.length == 0) {
043: d |= StaticProperty.DEPENDS_ON_CONTEXT_ITEM;
044: }
045: return d;
046: }
047:
048: /**
049: * Pre-evaluate a function at compile time. Functions that do not allow
050: * pre-evaluation, or that need access to context information, can override this method.
051: */
052:
053: public Expression preEvaluate(StaticContext env)
054: throws XPathException {
055: if (argument.length == 0) {
056: return this ;
057: } else {
058: return ExpressionTool.eagerEvaluate(this , env
059: .makeEarlyEvaluationContext());
060: }
061: }
062:
063: /**
064: * setShortCut() - used by optimizer when we only need to know if the length is non-zero
065: */
066:
067: public void setShortcut() {
068: shortcut = true;
069: }
070:
071: /**
072: * Evaluate in a general context
073: */
074:
075: public Item evaluateItem(XPathContext c) throws XPathException {
076: AtomicValue sv;
077: if (argument.length == 0) {
078: final Item contextItem = c.getContextItem();
079: if (contextItem == null) {
080: dynamicError(
081: "The context item for string-length() is not set",
082: "FONC0001", c);
083: }
084: sv = StringValue.makeStringValue(contextItem
085: .getStringValueCS());
086: } else {
087: sv = (AtomicValue) argument[0].evaluateItem(c);
088: }
089: if (sv == null) {
090: return IntegerValue.ZERO;
091: }
092: CharSequence s = sv.getStringValueCS();
093:
094: if (shortcut) {
095: return new IntegerValue((s.length() > 0 ? 1 : 0));
096: } else {
097: return new IntegerValue(StringValue.getStringLength(s));
098: }
099: }
100:
101: }
102:
103: //
104: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
105: // you may not use this file except in compliance with the License. You may obtain a copy of the
106: // License at http://www.mozilla.org/MPL/
107: //
108: // Software distributed under the License is distributed on an "AS IS" basis,
109: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
110: // See the License for the specific language governing rights and limitations under the License.
111: //
112: // The Original Code is: all this file.
113: //
114: // The Initial Developer of the Original Code is Michael H. Kay.
115: //
116: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
117: //
118: // Contributor(s): none.
119: //
|