1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package net.sf.webmancer.db;
23
24 import net.sf.webmancer.util.ContractChecker;
25
26
27
28
29
30 public class DecimalAttribute extends AbstractAttribute {
31
32
33
34 private double minimum;
35
36
37
38
39 private double maximum;
40
41
42
43
44 private int digits;
45
46
47
48
49 private int scale;
50
51
52
53
54
55 public DecimalAttribute(int digits, int scale) {
56 super();
57 ContractChecker.mustBePositive(digits, "digits");
58 ContractChecker.mustNotBeNegative(scale, "scale");
59 ContractChecker.mustBe(digits >= scale, "The 'digits' parameter must be greater or equal to 'scale'");
60
61 this.digits = digits;
62 this.scale = scale;
63 this.maximum = (Math.pow(10, digits) - 1) / Math.pow(10, scale);
64 this.minimum = -this.maximum;
65 }
66
67
68
69
70
71
72 public int getDigits() {
73 return digits;
74 }
75
76
77
78
79
80
81 public double getMaximum() {
82 return maximum;
83 }
84
85
86
87
88
89
90
91 public void setMaximum(double maximum) {
92 checkNumberOfDigits(maximum, "maximum");
93 this.maximum = maximum;
94 }
95
96
97
98
99
100
101 public double getMinimum() {
102 return minimum;
103 }
104
105
106
107
108
109
110
111 public void setMinimum(double minimum) {
112 checkNumberOfDigits(minimum, "minimum");
113 this.minimum = minimum;
114 }
115
116
117
118
119
120
121 public int getScale() {
122 return scale;
123 }
124
125
126
127
128 @Override
129 public int getMaximumInputLength() {
130
131 int maxlog = getDigitsBeforeDecimalPoint(this.getMaximum());
132 int minlog = getDigitsBeforeDecimalPoint(this.getMinimum());
133 int maxlen = Math.max(maxlog, minlog);
134
135
136 if (minlog >= maxlog) {
137 maxlen++;
138 }
139
140
141 if (this.getScale() > 0) {
142 maxlen += this.getScale() + 1;
143 if (this.getScale() == this.getDigits()) {
144 maxlen++;
145 }
146 }
147 return maxlen;
148 }
149
150
151
152
153
154 private int getDigitsBeforeDecimalPoint(double value) {
155 return (int) Math.floor(Math.log10(Math.abs(value))) + 1;
156 }
157
158
159
160
161 private void checkNumberOfDigits(double value, String parameter) {
162 int r = getDigitsBeforeDecimalPoint(value);
163 int mustBeMax = this.getDigits() - this.getScale();
164 if (r > mustBeMax) {
165 ContractChecker.mustBe(false, "The number of digits in '" + parameter + "' is too large: " + r + " (should be " + mustBeMax + " at maximum)");
166 }
167 }
168
169
170
171
172 @Override
173 public Object convertDbToInternal(Object dbValue) {
174
175 throw new UnsupportedOperationException("NumericAttribute.convertDbToInternal");
176 }
177
178
179
180
181 @Override
182 public String convertInternalToInput(Object internal) {
183 ContractChecker.mustBeInstanceOf(internal, Number.class, "internal");
184 Number theVal = (Number) internal;
185 return theVal.toString();
186 }
187
188
189
190
191 @Override
192 public String convertInternalToOutput(Object internal) {
193 ContractChecker.mustBeInstanceOf(internal, Number.class, "internal");
194 Number theVal = (Number) internal;
195 return theVal.toString();
196 }
197
198 }