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.om.FastStringBuffer;
006: import net.sf.saxon.trans.XPathException;
007: import net.sf.saxon.value.AtomicValue;
008: import net.sf.saxon.value.StringValue;
009:
010: import java.util.StringTokenizer;
011:
012: /**
013: * Implement the XPath normalize-space() function
014: */
015:
016: public class NormalizeSpace extends SystemFunction {
017:
018: /**
019: * Simplify and validate.
020: */
021:
022: public Expression simplify(StaticContext env) throws XPathException {
023: return simplifyArguments(env);
024: }
025:
026: /**
027: * Determine the intrinsic dependencies of an expression, that is, those which are not derived
028: * from the dependencies of its subexpressions. For example, position() has an intrinsic dependency
029: * on the context position, while (position()+1) does not. The default implementation
030: * of the method returns 0, indicating "no dependencies".
031: *
032: * @return a set of bit-significant flags identifying the "intrinsic"
033: * dependencies. The flags are documented in class net.sf.saxon.value.StaticProperty
034: */
035:
036: public int getIntrinsicDependencies() {
037: int d = super .getIntrinsicDependencies();
038: if (argument.length == 0) {
039: d |= StaticProperty.DEPENDS_ON_CONTEXT_ITEM;
040: }
041: return d;
042: }
043:
044: /**
045: * Pre-evaluate a function at compile time. Functions that do not allow
046: * pre-evaluation, or that need access to context information, can override this method.
047: */
048:
049: public Expression preEvaluate(StaticContext env)
050: throws XPathException {
051: if (argument.length == 0) {
052: return this ;
053: } else {
054: return ExpressionTool.eagerEvaluate(this , env
055: .makeEarlyEvaluationContext());
056: }
057: }
058:
059: /**
060: * Evaluate in a general context
061: */
062:
063: public Item evaluateItem(XPathContext c) throws XPathException {
064: if (argument.length == 0) {
065: return StringValue.makeStringValue(normalize(c
066: .getContextItem().getStringValueCS()));
067: } else {
068: AtomicValue sv = (AtomicValue) argument[0].evaluateItem(c);
069: if (sv == null)
070: return StringValue.EMPTY_STRING;
071: return StringValue.makeStringValue(normalize(sv
072: .getStringValueCS()));
073: }
074: }
075:
076: /**
077: * The algorithm that does the work
078: */
079:
080: public static CharSequence normalize(CharSequence s) {
081: FastStringBuffer sb = new FastStringBuffer(s.length());
082: StringTokenizer st = new StringTokenizer(s.toString());
083: while (st.hasMoreTokens()) {
084: sb.append(st.nextToken());
085: if (st.hasMoreTokens()) {
086: sb.append(' ');
087: }
088: }
089: return sb.condense();
090: }
091:
092: }
093:
094: //
095: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
096: // you may not use this file except in compliance with the License. You may obtain a copy of the
097: // License at http://www.mozilla.org/MPL/
098: //
099: // Software distributed under the License is distributed on an "AS IS" basis,
100: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
101: // See the License for the specific language governing rights and limitations under the License.
102: //
103: // The Original Code is: all this file.
104: //
105: // The Initial Developer of the Original Code is Michael H. Kay.
106: //
107: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
108: //
109: // Contributor(s): none.
110: //
|