001: /*
002: * Copyright 2006 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.opensource.org/licenses/ecl1.php
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.kuali.core.util;
017:
018: import java.math.BigDecimal;
019: import java.math.BigInteger;
020: import java.math.MathContext;
021: import java.math.RoundingMode;
022:
023: public class KualiInteger extends Number implements Comparable {
024: public static final int ROUND_BEHAVIOR = KualiDecimal.ROUND_BEHAVIOR;
025: public static final int SCALE = 0;
026:
027: public static KualiInteger ZERO = new KualiInteger(0);
028:
029: private final BigInteger value;
030:
031: /**
032: * Constructor - only accepts a string representation of the value.
033: *
034: * This is done to prevent unexpected inaccuracy by conversion to and from floating-point values.
035: *
036: * @param value String containing numeric value
037: * @throws IllegalArgumentException if the given String is null
038: */
039: public KualiInteger(String value) {
040: if (value == null) {
041: throw new IllegalArgumentException(
042: "invalid (null) String in KualiInteger constructor");
043: }
044:
045: this .value = new BigInteger(value);
046: }
047:
048: /**
049: * Initializes this instance to the given integer value with integer arithmetic.
050: */
051: public KualiInteger(long value) {
052: this .value = BigInteger.valueOf(value);
053: }
054:
055: /**
056: * Simple constructor, copies in the given BigInteger as the value for the instance.
057: *
058: * @param value BigInteger to be used as basis for value
059: * @throws IllegalArgumentException if the given BigDecimal is null
060: */
061: public KualiInteger(BigInteger value) {
062: if (value == null) {
063: throw new IllegalArgumentException(
064: "invalid (null) BigDecimal in KualiDecimal constructor");
065: }
066:
067: this .value = value;
068: }
069:
070: /**
071: * Simple constructor, copies in the given BigInteger as the value for the instance.
072: *
073: * @param value BigInteger to be used as basis for value
074: * @throws IllegalArgumentException if the given BigDecimal is null
075: */
076: public KualiInteger(BigDecimal value) {
077: if (value == null) {
078: throw new IllegalArgumentException(
079: "invalid (null) BigDecimal in KualiDecimal constructor");
080: }
081:
082: this .value = value.setScale(SCALE, ROUND_BEHAVIOR)
083: .toBigInteger();
084: }
085:
086: /**
087: * Simple constructor, rounds the given KualiDecimal according to the RoundingMode
088: *
089: * @param value KualiDecmial to be used as basis for value
090: * @param roundingMode RoundingMode for converting to Integer
091: * @throws IllegalArgumentException if the given KualiDecmial or RoundingMode is null
092: */
093: public KualiInteger(KualiDecimal value, RoundingMode roundingMode) {
094: if (value == null) {
095: throw new IllegalArgumentException(
096: "invalid (null) KualiDecimal in KualiInteger constructor");
097: }
098: if (roundingMode == null) {
099: throw new IllegalArgumentException(
100: "invalid (null) RoundingMode in KualiInteger constructor");
101: }
102:
103: this .value = value.bigDecimalValue().round(
104: new MathContext(0, roundingMode)).toBigInteger();
105: }
106:
107: /**
108: * Wraps BigDecimal's add method to accept and return KualiDecimal instances instead of BigDecimals, so that users of the class
109: * don't have to typecast the return value.
110: *
111: * @param addend
112: * @return result of adding the given addend to this value
113: * @throws IllegalArgumentException if the given addend is null
114: */
115: public KualiInteger add(KualiInteger addend) {
116: if (addend == null) {
117: throw new IllegalArgumentException("invalid (null) addend");
118: }
119:
120: BigInteger sum = this .value.add(addend.value);
121: return new KualiInteger(sum);
122: }
123:
124: /**
125: * Wraps BigDecimal's subtract method to accept and return KualiDecimal instances instead of BigDecimals, so that users of the
126: * class don't have to typecast the return value.
127: *
128: * @param subtrahend
129: * @return result of the subtracting the given subtrahend from this value
130: * @throws IllegalArgumentException if the given subtrahend is null
131: */
132: public KualiInteger subtract(KualiInteger subtrahend) {
133: if (subtrahend == null) {
134: throw new IllegalArgumentException(
135: "invalid (null) subtrahend");
136: }
137:
138: BigInteger difference = this .value.subtract(subtrahend.value);
139: return new KualiInteger(difference);
140: }
141:
142: /**
143: * Wraps BigDecimal's multiply method to accept and return KualiInteger instances instead of BigDecimals, so that users of the
144: * class don't have to typecast the return value.
145: *
146: * @param multiplicand
147: * @return result of multiplying this value by the given multiplier
148: * @throws IllegalArgumentException if the given multiplier is null
149: */
150: public KualiInteger multiply(KualiInteger multiplier) {
151: if (multiplier == null) {
152: throw new IllegalArgumentException(
153: "invalid (null) multiplier");
154: }
155:
156: BigInteger product = this .value.multiply(multiplier.value);
157: return new KualiInteger(product);
158: }
159:
160: public KualiInteger multiply(BigDecimal multiplier) {
161: if (multiplier == null) {
162: throw new IllegalArgumentException(
163: "invalid (null) multiplier");
164: }
165:
166: BigDecimal product = multiplier.multiply(new BigDecimal(
167: this .value));
168: return new KualiInteger(product);
169: }
170:
171: public KualiInteger multiply(KualiDecimal multiplier) {
172: return multiply(multiplier.bigDecimalValue());
173: }
174:
175: public BigDecimal divide(BigDecimal dividend) {
176: if (dividend == null) {
177: throw new IllegalArgumentException(
178: "invalid (null) dividend");
179: }
180:
181: return this .bigDecimalValue().divide(dividend, 8,
182: ROUND_BEHAVIOR);
183: }
184:
185: public BigDecimal divide(KualiInteger dividend) {
186: if (dividend == null) {
187: throw new IllegalArgumentException(
188: "invalid (null) dividend");
189: }
190:
191: return divide(dividend.bigDecimalValue());
192: }
193:
194: // Number methods
195: /**
196: * @see java.lang.Number#doubleValue()
197: */
198: public double doubleValue() {
199: return this .value.doubleValue();
200: }
201:
202: /**
203: * @see java.lang.Number#floatValue()
204: */
205: public float floatValue() {
206: return this .value.floatValue();
207: }
208:
209: /**
210: * @see java.lang.Number#intValue()
211: */
212: public int intValue() {
213: return this .value.intValue();
214: }
215:
216: /**
217: * @see java.lang.Number#longValue()
218: */
219: public long longValue() {
220: return this .value.longValue();
221: }
222:
223: /**
224: * @return the value of this instance as a BigDecimal.
225: */
226: public BigInteger bigIntegerValue() {
227: return this .value;
228: }
229:
230: /**
231: * @return the value of this instance as a BigDecimal.
232: */
233: public BigDecimal bigDecimalValue() {
234: return new BigDecimal(this .value);
235: }
236:
237: /**
238: * @return the value of this instance as a BigDecimal.
239: */
240: public KualiDecimal kualiDecimalValue() {
241: return new KualiDecimal(this .bigDecimalValue());
242: }
243:
244: /**
245: * @param operand
246: * @return true if this KualiDecimal is less than the given KualiDecimal
247: */
248: public boolean isLessThan(KualiInteger operand) {
249: if (operand == null) {
250: throw new IllegalArgumentException("invalid (null) operand");
251: }
252:
253: return (this .compareTo(operand) == -1);
254: }
255:
256: /**
257: * @param operand
258: * @return true if this KualiDecimal is greater than the given KualiDecimal
259: */
260: public boolean isGreaterThan(KualiInteger operand) {
261: if (operand == null) {
262: throw new IllegalArgumentException("invalid (null) operand");
263: }
264:
265: return (this .compareTo(operand) == 1);
266: }
267:
268: /**
269: * @param operand
270: * @return true if this KualiDecimal is less than or equal to the given KualiDecimal
271: */
272: public boolean isLessEqual(KualiInteger operand) {
273: if (operand == null) {
274: throw new IllegalArgumentException("invalid (null) operand");
275: }
276:
277: return !isGreaterThan(operand);
278: }
279:
280: /**
281: * @param operand
282: * @return true if this KualiDecimal is greater than or equal to the given KualiDecimal
283: */
284: public boolean isGreaterEqual(KualiInteger operand) {
285: if (operand == null) {
286: throw new IllegalArgumentException("invalid (null) operand");
287: }
288:
289: return !isLessThan(operand);
290: }
291:
292: /**
293: * @return true if this KualiDecimal is less than zero
294: */
295: public boolean isNegative() {
296: return (this .compareTo(ZERO) == -1);
297: }
298:
299: /**
300: * @return true if this KualiDecimal is greater than zero
301: */
302: public boolean isPositive() {
303: return (this .compareTo(ZERO) == 1);
304: }
305:
306: /**
307: * @return true if this KualiDecimal is equal to zero
308: */
309: public boolean isZero() {
310: return (this .compareTo(ZERO) == 0);
311: }
312:
313: /**
314: * @return true if this KualiDecimal is not equal to zero
315: */
316: public boolean isNonZero() {
317: return !this .isZero();
318: }
319:
320: /**
321: * @return a KualiInteger with the same scale and a negated value (iff the value is non-zero)
322: */
323: public KualiInteger negated() {
324: return multiply(new KualiInteger("-1"));
325: }
326:
327: // Comparable methods
328: /**
329: * Compares this KualiInteger with the specified Object. If the Object is a KualiInteger, this method behaves like
330: * java.lang.Comparable#compareTo(java.lang.Object).
331: *
332: * Otherwise, it throws a <tt>ClassCastException</tt> (as KualiIntegers are comparable only to other KualiIntegers).
333: *
334: * @see java.lang.Comparable#compareTo(java.lang.Object)
335: */
336: public int compareTo(Object o) {
337: return compareTo((KualiInteger) o);
338: }
339:
340: /**
341: * Returns the result of comparing the values of this KualiInteger and the given KualiInteger.
342: *
343: * @see java.lang.Comparable#compareTo(java.lang.Object)
344: */
345: public int compareTo(KualiInteger k) {
346: return this .value.compareTo(k.value);
347: }
348:
349: // Object methods
350: /**
351: * @see java.lang.Object#equals(java.lang.Object)
352: */
353: public boolean equals(Object obj) {
354: boolean equals = false;
355:
356: if (obj instanceof KualiInteger) {
357: KualiInteger k = (KualiInteger) obj;
358:
359: // using KualiInteger.compareTo instead of BigDecimal.equals since BigDecimal.equals only returns true if the
360: // scale and precision are equal, rather than comparing the actual (scaled) values
361: equals = (this .compareTo(k) == 0);
362: }
363:
364: return equals;
365: }
366:
367: /**
368: *
369: * @see java.lang.Object#hashCode()
370: */
371: public int hashCode() {
372: return this .value.hashCode();
373: }
374:
375: /**
376: * @see java.lang.Object#toString()
377: */
378: public String toString() {
379: return this.value.toString();
380: }
381:
382: }
|