001: package org.apache.torque.om;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import java.math.BigDecimal;
023:
024: /**
025: * This class can be used as an ObjectKey to uniquely identify an
026: * object within an application where the id consists
027: * of a single entity such a GUID or the value of a db row's primary key.
028: *
029: * @author <a href="mailto:jmcnally@apache.org">John McNally</a>
030: * @author <a href="mailto:stephenh@chase3000.com">Stephen Haberman</a>
031: * @author <a href="mailto:rg@onepercentsoftware.com">Runako Godfrey</a>
032: * @version $Id: NumberKey.java 473821 2006-11-11 22:37:25Z tv $
033: */
034: public class NumberKey extends SimpleKey {
035: /**
036: * Serial version
037: */
038: private static final long serialVersionUID = -5566819786708264162L;
039:
040: /**
041: * Creates a NumberKey whose internal representation will be
042: * set later, through a set method
043: */
044: public NumberKey() {
045: }
046:
047: /**
048: * Creates a NumberKey equivalent to <code>key</code>.
049: *
050: * @param key the key value
051: */
052: public NumberKey(String key) {
053: this .key = new BigDecimal(key);
054: }
055:
056: /**
057: * Creates a NumberKey equivalent to <code>key</code>.
058: *
059: * @param key the key value
060: */
061: public NumberKey(BigDecimal key) {
062: this .key = key;
063: }
064:
065: /**
066: * Creates a NumberKey equivalent to <code>key</code>.
067: *
068: * @param key the key value
069: */
070: public NumberKey(NumberKey key) {
071: if (key != null) {
072: this .key = key.getValue();
073: } else {
074: this .key = null;
075: }
076: }
077:
078: /**
079: * Creates a NumberKey equivalent to <code>key</code>.
080: *
081: * @param key the key value
082: */
083: public NumberKey(long key) {
084: this .key = BigDecimal.valueOf(key);
085: }
086:
087: /**
088: * Creates a NumberKey equivalent to <code>key</code>.
089: *
090: * @param key the key value
091: */
092: public NumberKey(double key) {
093: this .key = new BigDecimal(key);
094: }
095:
096: /**
097: * Creates a NumberKey equivalent to <code>key</code>.
098: * Convenience only.
099: *
100: * @param key the key value
101: */
102: public NumberKey(int key) {
103: this ((long) key);
104: }
105:
106: /**
107: * Creates a NumberKey equivalent to <code>key</code>.
108: * Convenience only.
109: *
110: * @param key the key value
111: */
112: public NumberKey(Number key) {
113: if (key != null) {
114: this .key = new BigDecimal(key.toString());
115: } else {
116: this .key = null;
117: }
118: }
119:
120: /**
121: * Sets the internal representation using a String representation
122: * of a number
123: *
124: * @param key the key value
125: * @throws NumberFormatException if key is not a valid number
126: */
127: public void setValue(String key) throws NumberFormatException {
128: this .key = new BigDecimal(key);
129: }
130:
131: /**
132: * Sets the underlying object
133: *
134: * @param key the key value
135: */
136: public void setValue(BigDecimal key) {
137: this .key = key;
138: }
139:
140: /**
141: * Sets the internal representation to the same object used by key.
142: *
143: * @param key the key value
144: */
145: public void setValue(NumberKey key) {
146: this .key = (key == null ? null : key.getValue());
147: }
148:
149: /**
150: * Access the underlying BigDecimal object.
151: *
152: * @return a <code>BigDecimal</code> value
153: */
154: public BigDecimal getBigDecimal() {
155: return (BigDecimal) key;
156: }
157:
158: /**
159: * Two ObjectKeys that both contain null values <strong>are not</strong>
160: * considered equal.
161: *
162: * @param keyObj the key to compare values to
163: * @return whether the two objects are equal
164: */
165: public boolean equals(Object keyObj) {
166: if (keyObj == this ) {
167: return true;
168: }
169:
170: if (!(keyObj instanceof NumberKey)) {
171: // NumberKeys used to be comparable to Strings. This behavior has
172: // been changed, I don't think it is a good idea to fail silently
173: // as code may be dependent on the old behavior.
174: if (keyObj instanceof String) {
175: throw new IllegalArgumentException(
176: "NumberKeys are not comparable to Strings");
177: }
178:
179: return false;
180: }
181:
182: if (getValue() != null) {
183: return getValue().equals(((NumberKey) keyObj).getValue());
184: } else {
185: // Even if they are both null...still return false.
186: return false;
187: }
188: }
189:
190: /**
191: * @return a hash code based on the value
192: */
193: public int hashCode() {
194: if (getValue() == null) {
195: return super .hashCode();
196: } else {
197: return getValue().hashCode();
198: }
199: }
200:
201: /**
202: * @param o the comparison value
203: * @return a numeric comparison of the two values
204: */
205: public int compareTo(Object o) {
206: return getBigDecimal().compareTo(
207: ((NumberKey) o).getBigDecimal());
208: }
209:
210: /**
211: * Invokes the toString() method on the object. An empty string
212: * is returned is the value is null.
213: *
214: * @return a String representation of the key value
215: */
216: public String toString() {
217: if (key != null) {
218: return key.toString();
219: }
220: return "";
221: }
222:
223: /**
224: * Returns the value of this NumberKey as a byte. This value is subject
225: * to the conversion rules set out in
226: * {@link java.math.BigDecimal#byteValue()}
227: *
228: * @return the NumberKey converted to a byte
229: */
230: public byte byteValue() {
231: return getBigDecimal().byteValue();
232: }
233:
234: /**
235: * Returns the value of this NumberKey as an int. This value is subject
236: * to the conversion rules set out in
237: * {@link java.math.BigDecimal#intValue()}, importantly any fractional part
238: * will be discarded and if the underlying value is too big to fit in an
239: * int, only the low-order 32 bits are returned. Note that this
240: * conversion can lose information about the overall magnitude and
241: * precision of the NumberKey value as well as return a result with the
242: * opposite sign.
243: *
244: * @return the NumberKey converted to an int
245: */
246: public int intValue() {
247: return getBigDecimal().intValue();
248: }
249:
250: /**
251: * Returns the value of this NumberKey as a short. This value is subject
252: * to the conversion rules set out in
253: * {@link java.math.BigDecimal#intValue()}, importantly any fractional part
254: * will be discarded and if the underlying value is too big to fit
255: * in a long, only the low-order 64 bits are returned. Note that this
256: * conversion can lose information about the overall magnitude and
257: * precision of the NumberKey value as well as return a result with the
258: * opposite sign.
259: *
260: * @return the NumberKey converted to a short
261: */
262: public short shortValue() {
263: return getBigDecimal().shortValue();
264: }
265:
266: /**
267: * Returns the value of this NumberKey as a long. This value is subject
268: * to the conversion rules set out in
269: * {@link java.math.BigDecimal#intValue()}
270: *
271: * @return the NumberKey converted to a long
272: */
273: public long longValue() {
274: return getBigDecimal().longValue();
275: }
276:
277: /**
278: * Returns the value of this NumberKey as a float. This value is subject to
279: * the conversion rules set out in
280: * {@link java.math.BigDecimal#floatValue()}, most importantly if the
281: * underlying value has too great a magnitude to represent as a
282: * float, it will be converted to Float.NEGATIVE_INFINITY
283: * or Float.POSITIVE_INFINITY as appropriate.
284: *
285: * @return the NumberKey converted to a float
286: */
287: public float floatValue() {
288: return getBigDecimal().floatValue();
289: }
290:
291: /**
292: * Returns the value of this NumberKey as a double. This value is subject
293: * to the conversion rules set out in
294: * {@link java.math.BigDecimal#doubleValue()}, most importantly if the
295: * underlying value has too great a magnitude to represent as a
296: * double, it will be converted to Double.NEGATIVE_INFINITY
297: * or Double.POSITIVE_INFINITY as appropriate.
298: *
299: * @return the NumberKey converted to a double
300: */
301: public double doubleValue() {
302: return getBigDecimal().doubleValue();
303: }
304: }
|