KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > value > ValueDecimal


1 /*
2  * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
3  * Initial Developer: H2 Group
4  */

5 package org.h2.value;
6
7 import java.math.BigDecimal JavaDoc;
8 import java.sql.PreparedStatement JavaDoc;
9 import java.sql.SQLException JavaDoc;
10
11 import org.h2.message.Message;
12 import org.h2.util.MathUtils;
13
14 /**
15  * @author Thomas
16  */

17 public class ValueDecimal extends Value {
18     // TODO doc: document differences for BigDecimal 1.5 <> 1.4
19
private BigDecimal JavaDoc value;
20     private String JavaDoc valueString;
21     private int precision;
22
23     private static final BigDecimal JavaDoc DEC_ZERO = new BigDecimal JavaDoc("0");
24     private static final BigDecimal JavaDoc DEC_ONE = new BigDecimal JavaDoc("1");
25     private static final ValueDecimal ZERO = new ValueDecimal(DEC_ZERO);
26     private static final ValueDecimal ONE = new ValueDecimal(DEC_ONE);
27     
28     public static final int DEFAULT_PRECISION = 65535;
29     public static final int DEFAULT_SCALE = 32767;
30     private static final int DIVIDE_SCALE_ADD = 25;
31
32     private ValueDecimal(BigDecimal JavaDoc value) {
33         if (value == null) {
34             throw new NullPointerException JavaDoc();
35         } else if(!value.getClass().equals(BigDecimal JavaDoc.class)) {
36             SQLException JavaDoc e = Message.getSQLException(Message.INVALID_CLASS_2, new String JavaDoc[]{BigDecimal JavaDoc.class.getName(), value.getClass().getName()}, null);
37             throw Message.convertToInternal(e);
38         }
39         this.value = value;
40     }
41
42     public Value add(Value v) {
43         ValueDecimal dec = (ValueDecimal) v;
44         return ValueDecimal.get(value.add(dec.value));
45     }
46
47     public Value subtract(Value v) {
48         ValueDecimal dec = (ValueDecimal) v;
49         return ValueDecimal.get(value.subtract(dec.value));
50     }
51
52     public Value negate() {
53         return ValueDecimal.get(value.negate());
54     }
55
56     public Value multiply(Value v) {
57         ValueDecimal dec = (ValueDecimal) v;
58         return ValueDecimal.get(value.multiply(dec.value));
59     }
60
61     public Value divide(Value v) throws SQLException JavaDoc {
62         ValueDecimal dec = (ValueDecimal) v;
63         // TODO value: divide decimal: rounding?
64
if (dec.value.signum() == 0) {
65             throw Message.getSQLException(Message.DIVISION_BY_ZERO_1, getSQL());
66         }
67         BigDecimal JavaDoc bd = value.divide(dec.value, value.scale()+DIVIDE_SCALE_ADD, BigDecimal.ROUND_HALF_DOWN);
68         if(bd.signum()==0) {
69             bd = DEC_ZERO;
70         } else if(bd.scale()>0) {
71             if(!bd.unscaledValue().testBit(0)) {
72                 String JavaDoc s = bd.toString();
73                 int i=s.length() - 1;
74                 while(i>=0 && s.charAt(i) == '0') {
75                     i--;
76                 }
77                 if(i < s.length() - 1) {
78                     s = s.substring(0, i+1);
79                     bd = new BigDecimal JavaDoc(s);
80                 }
81             }
82         }
83         return ValueDecimal.get(bd);
84     }
85
86     public String JavaDoc getSQL() {
87         return getString();
88     }
89
90     public int getType() {
91         return Value.DECIMAL;
92     }
93
94     protected int compareSecure(Value o, CompareMode mode) {
95         ValueDecimal v = (ValueDecimal) o;
96         int c = value.compareTo(v.value);
97         return c == 0 ? 0 : (c < 0 ? -1 : 1);
98     }
99
100     public int getSignum() {
101         return value.signum();
102     }
103
104     public BigDecimal JavaDoc getBigDecimal() {
105         return value;
106     }
107
108     public String JavaDoc getString() {
109         if(valueString == null) {
110             valueString = value.toString();
111         }
112         return valueString;
113     }
114
115     public long getPrecision() {
116         if(precision == 0) {
117             precision = value.unscaledValue().abs().toString().length();
118         }
119         return precision;
120     }
121
122     public int getScale() {
123         return value.scale();
124     }
125
126     public int hashCode() {
127         return value.hashCode();
128     }
129
130     public Object JavaDoc getObject() {
131         return value;
132     }
133
134     public void set(PreparedStatement JavaDoc prep, int parameterIndex) throws SQLException JavaDoc {
135         prep.setBigDecimal(parameterIndex, value);
136     }
137
138     public Value convertScale(boolean onlyToSmallerScale, int targetScale) throws SQLException JavaDoc {
139         if (value.scale() == targetScale) {
140             return this;
141         }
142         if (onlyToSmallerScale || targetScale >= DEFAULT_SCALE) {
143             if (value.scale() < targetScale) {
144                 return this;
145             }
146         }
147         BigDecimal JavaDoc bd = MathUtils.setScale(value, targetScale);
148         return ValueDecimal.get(bd);
149     }
150
151     public Value convertPrecision(long precision) throws SQLException JavaDoc {
152         if (getPrecision() <= precision) {
153             return this;
154         }
155         throw Message.getSQLException(Message.VALUE_TOO_LARGE_FOR_PRECISION_1, "" + precision);
156     }
157
158     public static ValueDecimal get(BigDecimal JavaDoc dec) {
159         if (DEC_ZERO.equals(dec)) {
160             return ZERO;
161         } else if (DEC_ONE.equals(dec)) {
162             return ONE;
163         }
164         // TODO value optimization: find a way to read size of bigdecimal,
165
// check max cache size
166
return (ValueDecimal) Value.cache(new ValueDecimal(dec));
167     }
168
169 // public String getJavaString() {
170
// return toString();
171
// }
172

173     public int getDisplaySize() {
174         // TODO displaySize: this is probably very slow
175
return getString().length();
176     }
177     
178     protected boolean isEqual(Value v) {
179         return v instanceof ValueDecimal && value.equals(((ValueDecimal)v).value);
180     }
181
182 }
183
Popular Tags