KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > schema > datatypes > DecimalType


1 /*
2  * This file belongs to the XQuark distribution.
3  * Copyright (C) 2003 Universite de Versailles Saint-Quentin.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307.
18  * You can also get it at http://www.gnu.org/licenses/lgpl.html
19  *
20  * For more information on this software, see http://www.xquark.org.
21  */

22
23 package org.xquark.schema.datatypes;
24
25 import java.math.BigDecimal JavaDoc;
26
27 import org.xquark.schema.SchemaException;
28 import org.xquark.schema.validation.ValidationContextProvider;
29
30
31 class DecimalType extends ComparableType {
32     private static final String JavaDoc RCSRevision = "$Revision: 1.3 $";
33     private static final String JavaDoc RCSName = "$Name: $";
34     
35     private static final BigDecimal JavaDoc MAX_LONG = new BigDecimal JavaDoc(Long.MAX_VALUE);
36     private static final BigDecimal JavaDoc MIN_LONG = new BigDecimal JavaDoc(Long.MIN_VALUE);
37
38     private int totalDigits = -1;
39     private int fractionDigits = -1;
40     private ComparableConstraints longConstraints = null;
41
42     DecimalType() {
43         super("decimal", PrimitiveType.DECIMAL);
44     }
45
46     public Object JavaDoc toValidType(Object JavaDoc data) {
47         if ((data instanceof Long JavaDoc) || (data instanceof BigDecimal JavaDoc)) {
48             return data;
49         } else if (data instanceof Number JavaDoc) {
50             return new Long JavaDoc(((Number JavaDoc)data).longValue());
51         } else {
52             return (Long JavaDoc)data;
53         }
54     }
55     
56
57     public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
58         DecimalType result = (DecimalType) super.clone();
59         initLongConstraints();
60         return result;
61     }
62
63     protected void setTotalDigits(String JavaDoc value, boolean fixed) throws SchemaException {
64         int val;
65         try {
66             val = Integer.parseInt(value.trim());
67         } catch (NumberFormatException JavaDoc nfe) {
68             // "illegal facet value";
69
throw new SchemaException("unknown-error-code.2");
70         }
71         if (val <= 0) {
72             // "illegal facet value";
73
throw new SchemaException("unknown-error-code.2");
74         }
75         if ((totalDigits != -1 && val > totalDigits) || (super.isFixed(PrimitiveType.TOTALDIGITS_FACET) && val != totalDigits)) {
76             // "totalDigits is " + val + ", but parent totalDigits is " + totalDigits;
77
throw new SchemaException("totalDigits-valid-restriction");
78         }
79         if (fractionDigits != -1 && fractionDigits > val) {
80             // "fractionDigits is " + fractionDigits + ", but totalDigits is " + val;
81
throw new SchemaException("fractionDigits-totalDigits");
82         }
83         totalDigits = val;
84         super.setFixed(PrimitiveType.TOTALDIGITS_FACET, fixed);
85     }
86
87     protected void setFractionDigits(String JavaDoc value, boolean fixed) throws SchemaException {
88         int val;
89         try {
90             val = Integer.parseInt(value.trim());
91         } catch (NumberFormatException JavaDoc nfe) {
92             // "illegal facet value";
93
throw new SchemaException("unknown-error-code.2");
94         }
95
96         if (val < 0) {
97             // "illegal facet value";
98
throw new SchemaException("unknown-error-code.2");
99         }
100
101         if ((fractionDigits != -1 && val > fractionDigits)
102             || (super.isFixed(PrimitiveType.FRACTIONDIGITS_FACET) && val != fractionDigits)) {
103             // "fractionDigits is " + val + ", but parent fractionDigits is " + totalDigits;
104
throw new SchemaException("fractionDigits-valid-restriction.1");
105         }
106         if (totalDigits != -1 && val > totalDigits) {
107             // "It is an ·error· for fractionDigits to be greater than totalDigits";
108
throw new SchemaException("fractionDigits-totalDigits");
109         }
110         fractionDigits = val;
111         super.setFixed(PrimitiveType.FRACTIONDIGITS_FACET, fixed);
112
113         initLongConstraints();
114     }
115
116     private void initLongConstraints() {
117         if (fractionDigits == 0) {
118             BigDecimal JavaDoc min = (BigDecimal JavaDoc)super.getMinValue();
119             BigDecimal JavaDoc max = (BigDecimal JavaDoc)super.getMaxValue();
120             if (min != null && min.compareTo(MIN_LONG) >= 0 && max != null && max.compareTo(MAX_LONG) <= 0) {
121                 longConstraints = new ComparableConstraints();
122                 longConstraints.setMinValue(new Long JavaDoc(min.longValue()), super.isMinInclusive());
123                 longConstraints.setMaxValue(new Long JavaDoc(max.longValue()), super.isMaxInclusive());
124             }
125         }
126     }
127
128     protected void setMinExclusive(String JavaDoc value, boolean fixed) throws SchemaException {
129         longConstraints = null;
130         super.setMinExclusive(value, fixed);
131         initLongConstraints();
132     }
133
134     protected void setMinInclusive(String JavaDoc value, boolean fixed) throws SchemaException {
135         longConstraints = null;
136         super.setMinInclusive(value, fixed);
137         initLongConstraints();
138     }
139
140     protected void setMaxExclusive(String JavaDoc value, boolean fixed) throws SchemaException {
141         longConstraints = null;
142         super.setMaxExclusive(value, fixed);
143         initLongConstraints();
144     }
145
146     protected void setMaxInclusive(String JavaDoc value, boolean fixed) throws SchemaException {
147         longConstraints = null;
148         super.setMaxInclusive(value, fixed);
149         initLongConstraints();
150     }
151
152     protected Comparable JavaDoc toComparable(String JavaDoc value) throws SchemaException {
153         Long JavaDoc longValue = toLong(value);
154         if (longValue != null) return longValue;
155         else return toBigDecimal(value);
156     }
157
158     private Long JavaDoc toLong(String JavaDoc value) throws SchemaException {
159         if (longConstraints == null) return null;
160         Long JavaDoc result = null;
161         try {
162             result = new Long JavaDoc(value);
163         } catch (NumberFormatException JavaDoc ex) {
164             result = null;
165         }
166         return result;
167     }
168     
169     private BigDecimal JavaDoc toBigDecimal(String JavaDoc value) throws SchemaException {
170 // if (value.indexOf('e') != -1 || value.indexOf('E') != -1) {
171
// super.invalidValue(value);
172
// }
173
BigDecimal JavaDoc result = null;
174         try {
175             result = new BigDecimal JavaDoc(value);
176         } catch (NumberFormatException JavaDoc ex) {
177             super.invalidValue(value);
178         }
179         return result;
180     }
181
182     protected Comparable JavaDoc checkComparable(Comparable JavaDoc comp) throws SchemaException {
183         if (longConstraints != null && comp instanceof Long JavaDoc) {
184             longConstraints.checkConstraints(comp);
185         } else {
186             super.checkComparable(comp);
187         }
188         return comp;
189     }
190     
191     protected void checkDecimal(Number JavaDoc dec) throws SchemaException {
192         int sc = 0;
193         if (dec instanceof BigDecimal JavaDoc) {
194             BigDecimal JavaDoc bigDec = (BigDecimal JavaDoc) dec;
195             sc = bigDec.scale();
196             if (fractionDigits != -1 && sc > fractionDigits)
197                 super.invalidFacet("cvc-fractionDigits-valid", new Integer JavaDoc(fractionDigits), bigDec.toString());
198         }
199         if (totalDigits != -1) {
200             double maxVal = Math.pow(10, totalDigits-sc);
201             if (Math.abs(dec.doubleValue()) >= maxVal)
202                 super.invalidFacet("cvc-totalDigits-valid", new Integer JavaDoc(totalDigits), dec.toString());
203         }
204     }
205
206     public void checkFacets(Object JavaDoc valueSpace) throws SchemaException {
207         super.checkFacets(valueSpace);
208         checkDecimal((Number JavaDoc)valueSpace);
209     }
210
211     public int getTotalDigits() {
212         return totalDigits;
213     }
214
215     public int getFractionDigits() {
216         return fractionDigits;
217     }
218
219     public String JavaDoc toXMLString(Object JavaDoc obj, ValidationContextProvider context) {
220         if (obj == null) return null;
221         if (obj instanceof Long JavaDoc) return obj.toString();
222         else {
223             String JavaDoc result = null;
224             BigDecimal JavaDoc data = (BigDecimal JavaDoc)obj;
225             result = data.toString();
226             if (fractionDigits == 0) {
227                 int index = result.indexOf('.');
228                 if (index != -1) return result.substring(0, index);
229                 else return result;
230             } else {
231                 int index = result.indexOf('.');
232                 int last = result.length() - 1;
233                 if (index == -1) {
234                     return result+".0";
235                 } else if (index == last) {
236                     return result+"0";
237                 } else {
238                     while (last > index+1 && result.charAt(last) == '0') last--;
239                     return result.substring(0, last+1);
240                 }
241             }
242         }
243     }
244     
245 }
246
Popular Tags