001: package net.sf.saxon.expr;
002:
003: import net.sf.saxon.om.Item;
004: import net.sf.saxon.sort.AtomicComparer;
005: import net.sf.saxon.trans.DynamicError;
006: import net.sf.saxon.trans.XPathException;
007: import net.sf.saxon.type.ItemType;
008: import net.sf.saxon.type.Type;
009: import net.sf.saxon.type.TypeHierarchy;
010: import net.sf.saxon.value.AtomicValue;
011: import net.sf.saxon.value.BooleanValue;
012:
013: import java.util.Comparator;
014:
015: /**
016: * Class to handle comparisons of singletons. Unlike ValueComparison, this class
017: * converts untyped atomic values to the type of the other argument, and returns false
018: * (rather than ()) if either operand is ().
019: */
020:
021: public class SingletonComparison extends BinaryExpression {
022:
023: private AtomicComparer comparer;
024:
025: public SingletonComparison(Expression p1, int operator,
026: Expression p2) {
027: super (p1, operator, p2);
028: }
029:
030: public void setComparator(Comparator comp, XPathContext context) {
031: if (comp instanceof AtomicComparer) {
032: comparer = (AtomicComparer) comp;
033: } else {
034: comparer = new AtomicComparer(comp, context);
035: }
036: }
037:
038: /**
039: * Determine the static cardinality. Returns [1..1]
040: */
041:
042: public int computeCardinality() {
043: return StaticProperty.EXACTLY_ONE;
044: }
045:
046: /**
047: * Determine the data type of the expression
048: * @return Type.BOOLEAN
049: * @param th
050: */
051:
052: public ItemType getItemType(TypeHierarchy th) {
053: return Type.BOOLEAN_TYPE;
054: }
055:
056: /**
057: * Evaluate the expression in a given context
058: * @param context the given context for evaluation
059: * @return a BooleanValue representing the result of the numeric comparison of the two operands
060: */
061:
062: public Item evaluateItem(XPathContext context)
063: throws XPathException {
064: return BooleanValue.get(effectiveBooleanValue(context));
065: }
066:
067: /**
068: * Evaluate the expression in a boolean context
069: * @param context the given context for evaluation
070: * @return a boolean representing the result of the numeric comparison of the two operands
071: */
072:
073: public boolean effectiveBooleanValue(XPathContext context)
074: throws XPathException {
075: AtomicValue v1 = (AtomicValue) operand0.evaluateItem(context);
076: if (v1 == null)
077: return false;
078: AtomicValue v2 = (AtomicValue) operand1.evaluateItem(context);
079: if (v2 == null)
080: return false;
081:
082: try {
083: return GeneralComparison.compare(v1, operator, v2,
084: comparer, context);
085: } catch (DynamicError e) {
086: // re-throw the exception with location information added
087: if (e.getXPathContext() == null) {
088: e.setXPathContext(context);
089: }
090: if (e.getLocator() == null) {
091: e.setLocator(this );
092: }
093: throw e;
094: }
095: }
096:
097: protected String displayOperator() {
098: return "singleton " + super .displayOperator();
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: //
|