KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > value > UntypedAtomicValue


1 package net.sf.saxon.value;
2 import net.sf.saxon.trans.XPathException;
3 import net.sf.saxon.type.AtomicType;
4 import net.sf.saxon.type.BuiltInAtomicType;
5 import net.sf.saxon.type.ItemType;
6 import net.sf.saxon.type.Type;
7 import net.sf.saxon.ConversionContext;
8 import net.sf.saxon.sort.CodepointCollator;
9
10 import java.util.Comparator JavaDoc;
11
12 /**
13 * An Untyped Atomic value. This inherits from StringValue for implementation convenience, even
14 * though an untypedAtomic value is not a String in the data model type hierarchy.
15 */

16
17 public class UntypedAtomicValue extends StringValue {
18
19     public static final UntypedAtomicValue ZERO_LENGTH_UNTYPED =
20             new UntypedAtomicValue("");
21
22     // If the value is used once as a number, it's likely that it will be used
23
// repeatedly as a number, so we cache the result of conversion
24

25     DoubleValue doubleValue = null;
26
27     /**
28     * Constructor
29     * @param value the String value. Null is taken as equivalent to "".
30     */

31
32     public UntypedAtomicValue(CharSequence JavaDoc value) {
33         this.value = (value==null ? "" : value);
34     }
35
36     /**
37     * Return the type of the expression
38     * @return Type.UNTYPED_ATOMIC (always)
39     */

40
41     public ItemType getItemType() {
42         return Type.UNTYPED_ATOMIC_TYPE;
43     }
44
45     /**
46     * Convert to target data type
47     */

48
49     public AtomicValue convertPrimitive(BuiltInAtomicType requiredType, boolean validate, ConversionContext conversion) {
50         int req = requiredType.getFingerprint();
51         if (req==Type.STRING) {
52             if (value.length() == 0) {
53                 // this case is common!
54
return StringValue.EMPTY_STRING;
55             } else {
56                 return new StringValue(value);
57             }
58         } else if (req==Type.DOUBLE || req==Type.NUMBER) {
59             // for conversion to double (common in 1.0 mode), cache the result
60
if (doubleValue==null) {
61                 AtomicValue v = super.convertPrimitive(requiredType, validate, conversion);
62                 if (v instanceof DoubleValue) {
63                     // the alternative is that it's an ErrorValue
64
doubleValue = (DoubleValue)v;
65                 }
66                 return v;
67             }
68             return doubleValue;
69         } else {
70             return super.convertPrimitive(requiredType, validate, conversion);
71         }
72     }
73
74     /**
75     * Compare an untypedAtomic value with another value, using a given collator to perform
76     * any string comparisons. This works by converting the untypedAtomic value to the type
77      * of the other operand, which is the correct behavior for operators like "=" and "!=",
78      * but not for "eq" and "ne": in the latter case, the untypedAtomic value is converted
79      * to a string and this method is therefore not used.
80      * @return -1 if the this value is less than the other, 0 if they are equal, +1 if this
81      * value is greater.
82     */

83
84     public int compareTo(Object JavaDoc other, Comparator JavaDoc collator, ConversionContext conversion) {
85         if (other instanceof NumericValue) {
86             if (doubleValue == null) {
87                 try {
88                     doubleValue = (DoubleValue)convert(Type.DOUBLE, null);
89                 } catch (XPathException err) {
90                 throw new ClassCastException JavaDoc("Cannot convert untyped value " +
91                         '\"' + getStringValueCS() + "\" to a double");
92                 }
93             }
94             return doubleValue.compareTo(other);
95         } else if (other instanceof StringValue) {
96             if (collator instanceof CodepointCollator) {
97                 // This optimization avoids creating String objects for the purpose of the comparison
98
return ((CodepointCollator)collator).compareCS(getStringValueCS(),
99                                                               ((StringValue)other).getStringValueCS());
100             } else {
101                 return collator.compare(getStringValue(), ((StringValue)other).getStringValue());
102             }
103         } else if (other instanceof AtomicValue) {
104             AtomicValue conv =
105                     convert((AtomicType)((Value)other).getItemType(), conversion, true);
106             if (conv instanceof ValidationErrorValue) {
107                 throw new ClassCastException JavaDoc("Cannot convert untyped atomic value '" + getStringValue()
108                         + "' to type " + ((Value)other).getItemType());
109             }
110             if (!(conv instanceof Comparable JavaDoc)) {
111                 throw new ClassCastException JavaDoc("Type " + ((Value)other).getItemType() + " is not ordered");
112             }
113             return ((Comparable JavaDoc)conv).compareTo(other);
114
115         } else {
116             // I'm not sure if we need this, but it does no harm
117
return collator.compare(getStringValue(), other.toString());
118         }
119     }
120
121     /**
122      * Compare two values for equality. This supports identity constraints in XML Schema,
123      * which allow list-valued elements and attributes to participate in key and uniqueness constraints.
124      * This method returns false if any error occurs during the comparison, or if any of the items
125      * in either sequence is a node rather than an atomic value. The default implementation of
126      * schemaEquals() is the same as equals(), but subclasses can override this.
127      */

128
129     public boolean schemaEquals(Value obj) {
130         throw new UnsupportedOperationException JavaDoc("schemaEquals() cannot be applied to untyped atomic values");
131     }
132
133 }
134
135 //
136
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
137
// you may not use this file except in compliance with the License. You may obtain a copy of the
138
// License at http://www.mozilla.org/MPL/
139
//
140
// Software distributed under the License is distributed on an "AS IS" basis,
141
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
142
// See the License for the specific language governing rights and limitations under the License.
143
//
144
// The Original Code is: all this file.
145
//
146
// The Initial Developer of the Original Code is Michael H. Kay.
147
//
148
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
149
//
150
// Contributor(s): none.
151
//
152

153
Popular Tags