View Javadoc

1   package org.apache.torque.om;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.math.BigDecimal;
23  
24  /***
25   * This class can be used as an ObjectKey to uniquely identify an
26   * object within an application where the id  consists
27   * of a single entity such a GUID or the value of a db row's primary key.
28   *
29   * @author <a href="mailto:jmcnally@apache.org">John McNally</a>
30   * @author <a href="mailto:stephenh@chase3000.com">Stephen Haberman</a>
31   * @author <a href="mailto:rg@onepercentsoftware.com">Runako Godfrey</a>
32   * @version $Id: NumberKey.java 473821 2006-11-11 22:37:25Z tv $
33   */
34  public class NumberKey extends SimpleKey
35  {
36      /***
37       * Serial version
38       */
39      private static final long serialVersionUID = -5566819786708264162L;
40  
41      /***
42       * Creates a NumberKey whose internal representation will be
43       * set later, through a set method
44       */
45      public NumberKey()
46      {
47      }
48  
49      /***
50       * Creates a NumberKey equivalent to <code>key</code>.
51       *
52       * @param key the key value
53       */
54      public NumberKey(String key)
55      {
56          this.key = new BigDecimal(key);
57      }
58  
59      /***
60       * Creates a NumberKey equivalent to <code>key</code>.
61       *
62       * @param key the key value
63       */
64      public NumberKey(BigDecimal key)
65      {
66          this.key = key;
67      }
68  
69      /***
70       * Creates a NumberKey equivalent to <code>key</code>.
71       *
72       * @param key the key value
73       */
74      public NumberKey(NumberKey key)
75      {
76          if (key != null)
77          {
78              this.key = key.getValue();
79          }
80          else
81          {
82              this.key = null;
83          }
84      }
85  
86      /***
87       * Creates a NumberKey equivalent to <code>key</code>.
88       *
89       * @param key the key value
90       */
91      public NumberKey(long key)
92      {
93          this.key = BigDecimal.valueOf(key);
94      }
95  
96      /***
97       * Creates a NumberKey equivalent to <code>key</code>.
98       *
99       * @param key the key value
100      */
101     public NumberKey(double key)
102     {
103         this.key = new BigDecimal(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(int key)
113     {
114         this((long) key);
115     }
116 
117     /***
118      * Creates a NumberKey equivalent to <code>key</code>.
119      * Convenience only.
120      *
121      * @param key the key value
122      */
123     public NumberKey(Number key)
124     {
125         if (key != null)
126         {
127             this.key = new BigDecimal(key.toString());
128         }
129         else
130         {
131             this.key = null;
132         }
133     }
134 
135     /***
136      * Sets the internal representation using a String representation
137      * of a number
138      *
139      * @param key the key value
140      * @throws NumberFormatException if key is not a valid number
141      */
142     public void setValue(String key) throws NumberFormatException
143     {
144         this.key = new BigDecimal(key);
145     }
146 
147     /***
148      * Sets the underlying object
149      *
150      * @param key the key value
151      */
152     public void setValue(BigDecimal key)
153     {
154         this.key = key;
155     }
156 
157     /***
158      * Sets the internal representation to the same object used by key.
159      *
160      * @param key the key value
161      */
162     public void setValue(NumberKey key)
163     {
164         this.key = (key == null ? null : key.getValue());
165     }
166 
167     /***
168      * Access the underlying BigDecimal object.
169      *
170      * @return a <code>BigDecimal</code> value
171      */
172     public BigDecimal getBigDecimal()
173     {
174         return (BigDecimal) key;
175     }
176 
177     /***
178      * Two ObjectKeys that both contain null values <strong>are not</strong>
179      * considered equal.
180      *
181      * @param keyObj the key to compare values to
182      * @return whether the two objects are equal
183      */
184     public boolean equals(Object keyObj)
185     {
186         if (keyObj == this)
187         {
188             return true;
189         }
190 
191         if (!(keyObj instanceof NumberKey))
192         {
193             // NumberKeys used to be comparable to Strings.  This behavior has
194             // been changed, I don't think it is a good idea to fail silently
195             // as code may be dependent on the old behavior.
196             if (keyObj instanceof String)
197             {
198                 throw new IllegalArgumentException(
199                     "NumberKeys are not comparable to Strings");
200             }
201 
202             return false;
203         }
204 
205         if (getValue() != null)
206         {
207             return getValue().equals(((NumberKey) keyObj).getValue());
208         }
209         else
210         {
211             // Even if they are both null...still return false.
212             return false;
213         }
214     }
215 
216     /***
217      * @return a hash code based on the value
218      */
219     public int hashCode()
220     {
221         if (getValue() == null)
222         {
223             return super.hashCode();
224         }
225         else
226         {
227             return getValue().hashCode();
228         }
229     }
230 
231     /***
232      * @param o the comparison value
233      * @return a numeric comparison of the two values
234      */
235     public int compareTo(Object o)
236     {
237         return getBigDecimal().compareTo(((NumberKey) o).getBigDecimal());
238     }
239 
240     /***
241      * Invokes the toString() method on the object.  An empty string
242      * is returned is the value is null.
243      *
244      * @return a String representation of the key value
245      */
246     public String toString()
247     {
248         if (key != null)
249         {
250             return key.toString();
251         }
252         return "";
253     }
254 
255     /***
256      * Returns the value of this NumberKey as a byte. This value is subject
257      * to the conversion rules set out in
258      * {@link java.math.BigDecimal#byteValue()}
259      *
260      * @return the NumberKey converted to a byte
261      */
262     public byte byteValue()
263     {
264         return getBigDecimal().byteValue();
265     }
266 
267     /***
268      * Returns the value of this NumberKey as an int. This value is subject
269      * to the conversion rules set out in
270      * {@link java.math.BigDecimal#intValue()}, importantly any fractional part
271      * will be discarded and if the underlying value is too big to fit in an
272      * int, only the low-order 32 bits are returned. Note that this
273      * conversion can lose information about the overall magnitude and
274      * precision of the NumberKey value as well as return a result with the
275      * opposite sign.
276      *
277      * @return the NumberKey converted to an int
278      */
279     public int intValue()
280     {
281         return getBigDecimal().intValue();
282     }
283 
284     /***
285      * Returns the value of this NumberKey as a short. This value is subject
286      * to the conversion rules set out in
287      * {@link java.math.BigDecimal#intValue()}, importantly any fractional part
288      *  will be discarded and if the underlying value is too big to fit
289      * in a long, only the low-order 64 bits are returned. Note that this
290      * conversion can lose information about the overall magnitude and
291      * precision of the NumberKey value as well as return a result with the
292      * opposite sign.
293      *
294      * @return the NumberKey converted to a short
295      */
296     public short shortValue()
297     {
298         return getBigDecimal().shortValue();
299     }
300 
301     /***
302      * Returns the value of this NumberKey as a long. This value is subject
303      * to the conversion rules set out in
304      * {@link java.math.BigDecimal#intValue()}
305      *
306      * @return the NumberKey converted to a long
307      */
308     public long longValue()
309     {
310         return getBigDecimal().longValue();
311     }
312 
313     /***
314      * Returns the value of this NumberKey as a float. This value is subject to
315      * the conversion rules set out in
316      * {@link java.math.BigDecimal#floatValue()}, most importantly if the
317      * underlying value has too great a magnitude to represent as a
318      * float, it will be converted to Float.NEGATIVE_INFINITY
319      * or Float.POSITIVE_INFINITY as appropriate.
320      *
321      * @return the NumberKey converted to a float
322      */
323     public float floatValue()
324     {
325         return getBigDecimal().floatValue();
326     }
327 
328     /***
329      * Returns the value of this NumberKey as a double. This value is subject
330      * to the conversion rules set out in
331      * {@link java.math.BigDecimal#doubleValue()}, most importantly if the
332      * underlying value has too great a magnitude to represent as a
333      * double, it will be converted to Double.NEGATIVE_INFINITY
334      * or Double.POSITIVE_INFINITY as appropriate.
335      *
336      * @return the NumberKey converted to a double
337      */
338     public double doubleValue()
339     {
340         return getBigDecimal().doubleValue();
341     }
342 }