View Javadoc

1   /*
2    * Copyright 2004-2005 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5    * use this file except in compliance with the License. You may obtain a copy of
6    * the License at
7    * 
8    * http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations under
14   * the License.
15   */
16  package net.sf.morph.transform.support;
17  
18  import java.math.BigDecimal;
19  
20  import net.sf.morph.util.NumberUtils;
21  
22  /**
23   * @author Matt Sgarlata
24   * @since Dec 15, 2004
25   */
26  public abstract class NumberRounder {
27  	
28  	/**
29  	 * Rounding mode specified in {@link BigDecimal}.
30  	 * 
31  	 * @see BigDecimal#ROUND_CEILING
32  	 */
33  	public static final String ROUND_CEILING = "ROUND_CEILING";
34  	/**
35  	 * Rounding mode specified in {@link BigDecimal}.
36  	 * 
37  	 * @see BigDecimal#ROUND_DOWN
38  	 */
39  	public static final String ROUND_DOWN = "ROUND_DOWN";
40  	/**
41  	 * Rounding mode specified in {@link BigDecimal}.
42  	 * 
43  	 * @see BigDecimal#ROUND_FLOOR
44  	 */
45  	public static final String ROUND_FLOOR = "ROUND_FLOOR";
46  	/**
47  	 * Rounding mode specified in {@link BigDecimal}.
48  	 * 
49  	 * @see BigDecimal#ROUND_HALF_DOWN
50  	 */
51  	public static final String ROUND_HALF_DOWN = "ROUND_HALF_DOWN";
52  	/**
53  	 * Rounding mode specified in {@link BigDecimal}.
54  	 * 
55  	 * @see BigDecimal#ROUND_HALF_EVEN
56  	 */
57  	public static final String ROUND_HALF_EVEN = "ROUND_HALF_EVEN";
58  	/**
59  	 * Rounding mode specified in {@link BigDecimal}.
60  	 * 
61  	 * @see BigDecimal#ROUND_HALF_UP
62  	 */
63  	public static final String ROUND_HALF_UP = "ROUND_HALF_UP";
64  	/**
65  	 * Rounding mode specified in {@link BigDecimal}.
66  	 * 
67  	 * @see BigDecimal#ROUND_UP
68  	 */
69  	public static final String ROUND_UP = "ROUND_UP";
70  	
71  	/**
72  	 * Converts a rounding mode defined in this class to one of the rounding
73  	 * mode <code>int</code>s specified in the {@link BigDecimal} class.
74  	 * 
75  	 * @param mode
76  	 *            the String representation of the mode, as defined in one of
77  	 *            the constants of this class
78  	 * @return the int representation of the mode, as defined in the
79  	 *         {@link BigDecimal} class.
80  	 * @throws IllegalArgumentException
81  	 *             if an invalid rounding mode was specified
82  	 */
83  	public static int getBigDecimalRoundMode(String mode)
84  		throws IllegalArgumentException {
85  		if (ROUND_CEILING.equals(mode)) {
86  			return BigDecimal.ROUND_CEILING;
87  		}
88  		if (ROUND_DOWN.equals(mode)) {
89  			return BigDecimal.ROUND_DOWN;
90  		}
91  		if (ROUND_FLOOR.equals(mode)) {
92  			return BigDecimal.ROUND_FLOOR;
93  		}
94  		if (ROUND_HALF_DOWN.equals(mode)) {
95  			return BigDecimal.ROUND_HALF_DOWN;
96  		}
97  		if (ROUND_HALF_EVEN.equals(mode)) {
98  			return BigDecimal.ROUND_HALF_EVEN;
99  		}
100 		if (ROUND_HALF_UP.equals(mode)) {
101 			return BigDecimal.ROUND_HALF_UP;
102 		}
103 		if (ROUND_UP.equals(mode)) {
104 			return BigDecimal.ROUND_UP;
105 		}
106 		throw new IllegalArgumentException("'" + mode + "' is not a valid rounding mode.  Please specify one of the constants defined in " + NumberRounder.class.getName());
107 	}
108 
109 	/**
110 	 * Rounds the given number using the given rounding mode. The type of the
111 	 * number is maintained (e.g. - if the number was a Float, it will remain
112 	 * so).
113 	 * 
114 	 * @param number
115 	 *            the number to round
116 	 * @param mode
117 	 *            the rounding mode, as specified by one of the constants in
118 	 *            this class
119 	 * @return <code>null</code>, if <code>number</code> is
120 	 *         <code>null</code> or <br>
121 	 *         <code>number</code> rounded as requested, otherwise
122 	 * @throws IllegalArgumentException
123 	 *             if an invalid rounding mode is specified
124 	 */
125 	public static Number round(Number number, String mode)
126 		throws IllegalArgumentException {
127 		if (NumberUtils.isDecimal(number)) {
128 			BigDecimal bigDecimal = NumberUtils.numberToBigDecimal(number);
129 			BigDecimal rounded = bigDecimal.setScale(0, getBigDecimalRoundMode(mode));
130 			if (number instanceof BigDecimal) {
131 				return rounded;
132 			}
133 			if (number instanceof Double) {
134 				return new Double(rounded.doubleValue());
135 			}
136 			if (number instanceof Float) {
137 				return new Float(rounded.floatValue());
138 			}
139 		}
140 		return number;
141 	}
142 
143 }