View Javadoc

1   /*
2    * Copyright 2004-2010 the Seasar Foundation and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of 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,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  
17  package org.seasar.cubby.converter.impl;
18  
19  import java.math.BigDecimal;
20  import java.math.BigInteger;
21  
22  import org.seasar.cubby.action.MessageInfo;
23  import org.seasar.cubby.converter.ConversionException;
24  import org.seasar.cubby.converter.ConversionHelper;
25  
26  /**
27   * 整数への変換を行うコンバータの抽象クラスです。
28   * <p>
29   * 変換元のオブジェクトの文字列表現を値とする{@link BigInteger}からサブクラスが変換した結果を変換先とします。
30   * </p>
31   * 
32   * @author baba
33   */
34  public abstract class AbstractIntegerNumberConverter extends AbstractConverter {
35  
36  	/**
37  	 * {@inheritDoc}
38  	 */
39  	public Object convertToObject(final Object value,
40  			final Class<?> objectType, final ConversionHelper helper)
41  			throws ConversionException {
42  		if (value == null) {
43  			return null;
44  		}
45  		return convert(value.toString());
46  	}
47  
48  	/**
49  	 * 数を表す文字列から数値に変換して返します。
50  	 * <p>
51  	 * 型変換に失敗した場合はメッセージのキーを <code>valid.number</code> とした
52  	 * {@link ConversionException} をスローします。
53  	 * </p>
54  	 * 
55  	 * @param value
56  	 *            数を表す文字列
57  	 * @return 変換結果の数値
58  	 * @throws ConversionException
59  	 *             型変換に失敗した場合
60  	 */
61  	protected Number convert(final String value) throws ConversionException {
62  		if (value == null || value.length() == 0) {
63  			return null;
64  		}
65  
66  		final BigDecimal decimal;
67  		try {
68  			decimal = new BigDecimal(value);
69  		} catch (final NumberFormatException e) {
70  			final MessageInfo messageInfo = new MessageInfo();
71  			messageInfo.setKey("valid.number");
72  			throw new ConversionException(messageInfo);
73  		}
74  
75  		final BigInteger integer;
76  		try {
77  			integer = decimal.toBigIntegerExact();
78  		} catch (final ArithmeticException e) {
79  			final MessageInfo messageInfo = new MessageInfo();
80  			messageInfo.setKey("valid.integer");
81  			throw new ConversionException(messageInfo);
82  		}
83  
84  		final BigInteger min = this.getMinValue();
85  		final BigInteger max = this.getMaxValue();
86  		if ((min != null && min.compareTo(integer) > 0)
87  				|| (max != null && max.compareTo(integer) < 0)) {
88  			final MessageInfo messageInfo = new MessageInfo();
89  			messageInfo.setKey("valid.range");
90  			messageInfo.setArguments(min, max);
91  			throw new ConversionException(messageInfo);
92  		}
93  
94  		return convert(integer);
95  	}
96  
97  	/**
98  	 * 数値を変換して返します。
99  	 * 
100 	 * @param integer
101 	 *            変換元の数値
102 	 * @return 変換結果の数値
103 	 */
104 	protected abstract Number convert(BigInteger integer);
105 
106 	/**
107 	 * 最小値を取得します。
108 	 * <p>
109 	 * 最小値をチェックしない場合は <code>null</code> を返します。
110 	 * </p>
111 	 * 
112 	 * @return 最小値
113 	 */
114 	protected abstract BigInteger getMinValue();
115 
116 	/**
117 	 * 最大値を取得します。
118 	 * <p>
119 	 * 最大値をチェックしない場合は <code>null</code> を返します。
120 	 * </p>
121 	 * 
122 	 * @return 最大値
123 	 */
124 	protected abstract BigInteger getMaxValue();
125 
126 	/**
127 	 * {@inheritDoc}
128 	 */
129 	public String convertToString(final Object value,
130 			final ConversionHelper helper) {
131 		if (value == null) {
132 			return null;
133 		}
134 		return value.toString();
135 	}
136 
137 }