KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xerces > impl > dv > xs > DecimalDV


1 /*
2  * Copyright 2001,2002,2004,2005 The Apache Software Foundation.
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, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.xerces.impl.dv.xs;
18
19 import java.math.BigDecimal JavaDoc;
20 import java.math.BigInteger JavaDoc;
21
22 import org.apache.xerces.impl.dv.InvalidDatatypeValueException;
23 import org.apache.xerces.impl.dv.ValidationContext;
24 import org.apache.xerces.xs.datatypes.XSDecimal;
25
26 /**
27  * Represent the schema type "decimal"
28  *
29  * @xerces.internal
30  *
31  * @author Neeraj Bajaj, Sun Microsystems, inc.
32  * @author Sandy Gao, IBM
33  *
34  * @version $Id: DecimalDV.java,v 1.13 2005/01/05 21:13:49 mrglavas Exp $
35  */

36 public class DecimalDV extends TypeValidator {
37
38     public final short getAllowedFacets(){
39         return ( XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION |XSSimpleTypeDecl.FACET_MAXINCLUSIVE |XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE | XSSimpleTypeDecl.FACET_MINEXCLUSIVE | XSSimpleTypeDecl.FACET_TOTALDIGITS | XSSimpleTypeDecl.FACET_FRACTIONDIGITS);
40     }
41
42     public Object JavaDoc getActualValue(String JavaDoc content, ValidationContext context) throws InvalidDatatypeValueException {
43         try {
44             return new XDecimal(content);
45         } catch (NumberFormatException JavaDoc nfe) {
46             throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object JavaDoc[]{content, "decimal"});
47         }
48     }
49
50     public final int compare(Object JavaDoc value1, Object JavaDoc value2){
51         return ((XDecimal)value1).compareTo((XDecimal)value2);
52     }
53
54     public final int getTotalDigits(Object JavaDoc value){
55         return ((XDecimal)value).totalDigits;
56     }
57
58     public final int getFractionDigits(Object JavaDoc value){
59         return ((XDecimal)value).fracDigits;
60     }
61     
62     // Avoid using the heavy-weight java.math.BigDecimal
63
static class XDecimal implements XSDecimal {
64         // sign: 0 for vlaue 0; 1 for positive values; -1 for negative values
65
int sign = 1;
66         // total digits. >= 1
67
int totalDigits = 0;
68         // integer digits when sign != 0
69
int intDigits = 0;
70         // fraction digits when sign != 0
71
int fracDigits = 0;
72         // the string representing the integer part
73
String JavaDoc ivalue = "";
74         // the string representing the fraction part
75
String JavaDoc fvalue = "";
76         // whether the canonical form contains decimal point
77
boolean integer = false;
78         
79         XDecimal(String JavaDoc content) throws NumberFormatException JavaDoc {
80             initD(content);
81         }
82         XDecimal(String JavaDoc content, boolean integer) throws NumberFormatException JavaDoc {
83             if (integer)
84                 initI(content);
85             else
86                 initD(content);
87         }
88         void initD(String JavaDoc content) throws NumberFormatException JavaDoc {
89             int len = content.length();
90             if (len == 0)
91                 throw new NumberFormatException JavaDoc();
92     
93             // these 4 variables are used to indicate where the integre/fraction
94
// parts start/end.
95
int intStart = 0, intEnd = 0, fracStart = 0, fracEnd = 0;
96             
97             // Deal with leading sign symbol if present
98
if (content.charAt(0) == '+') {
99                 // skip '+', so intStart should be 1
100
intStart = 1;
101             }
102             else if (content.charAt(0) == '-') {
103                 // keep '-', so intStart is stil 0
104
intStart = 1;
105                 sign = -1;
106             }
107     
108             // skip leading zeroes in integer part
109
int actualIntStart = intStart;
110             while (actualIntStart < len && content.charAt(actualIntStart) == '0') {
111                 actualIntStart++;
112             }
113     
114             // Find the ending position of the integer part
115
for (intEnd = actualIntStart;
116                  intEnd < len && TypeValidator.isDigit(content.charAt(intEnd));
117                  intEnd++);
118     
119             // Not reached the end yet
120
if (intEnd < len) {
121                 // the remaining part is not ".DDD", error
122
if (content.charAt(intEnd) != '.')
123                     throw new NumberFormatException JavaDoc();
124     
125                 // fraction part starts after '.', and ends at the end of the input
126
fracStart = intEnd + 1;
127                 fracEnd = len;
128             }
129     
130             // no integer part, no fraction part, error.
131
if (intStart == intEnd && fracStart == fracEnd)
132                 throw new NumberFormatException JavaDoc();
133     
134             // ignore trailing zeroes in fraction part
135
while (fracEnd > fracStart && content.charAt(fracEnd-1) == '0') {
136                 fracEnd--;
137             }
138     
139             // check whether there is non-digit characters in the fraction part
140
for (int fracPos = fracStart; fracPos < fracEnd; fracPos++) {
141                 if (!TypeValidator.isDigit(content.charAt(fracPos)))
142                     throw new NumberFormatException JavaDoc();
143             }
144     
145             intDigits = intEnd - actualIntStart;
146             fracDigits = fracEnd - fracStart;
147             totalDigits = intDigits + fracDigits;
148     
149             if (intDigits > 0) {
150                 ivalue = content.substring(actualIntStart, intEnd);
151                 if (fracDigits > 0)
152                     fvalue = content.substring(fracStart, fracEnd);
153             }
154             else {
155                 if (fracDigits > 0) {
156                     fvalue = content.substring(fracStart, fracEnd);
157                 }
158                 else {
159                     // ".00", treat it as "0"
160
sign = 0;
161                 }
162             }
163         }
164         void initI(String JavaDoc content) throws NumberFormatException JavaDoc {
165             int len = content.length();
166             if (len == 0)
167                 throw new NumberFormatException JavaDoc();
168     
169             // these 2 variables are used to indicate where the integre start/end.
170
int intStart = 0, intEnd = 0;
171     
172             // Deal with leading sign symbol if present
173
if (content.charAt(0) == '+') {
174                 // skip '+', so intStart should be 1
175
intStart = 1;
176             }
177             else if (content.charAt(0) == '-') {
178                 // keep '-', so intStart is stil 0
179
intStart = 1;
180                 sign = -1;
181             }
182     
183             // skip leading zeroes in integer part
184
int actualIntStart = intStart;
185             while (actualIntStart < len && content.charAt(actualIntStart) == '0') {
186                 actualIntStart++;
187             }
188     
189             // Find the ending position of the integer part
190
for (intEnd = actualIntStart;
191                  intEnd < len && TypeValidator.isDigit(content.charAt(intEnd));
192                  intEnd++);
193     
194             // Not reached the end yet, error
195
if (intEnd < len)
196                 throw new NumberFormatException JavaDoc();
197     
198             // no integer part, error.
199
if (intStart == intEnd)
200                 throw new NumberFormatException JavaDoc();
201     
202             intDigits = intEnd - actualIntStart;
203             fracDigits = 0;
204             totalDigits = intDigits;
205     
206             if (intDigits > 0) {
207                 ivalue = content.substring(actualIntStart, intEnd);
208             }
209             else {
210                 // "00", treat it as "0"
211
sign = 0;
212             }
213             
214             integer = true;
215         }
216         public boolean equals(Object JavaDoc val) {
217             if (val == this)
218                 return true;
219     
220             if (!(val instanceof XDecimal))
221                 return false;
222             XDecimal oval = (XDecimal)val;
223             
224             if (sign != oval.sign)
225                return false;
226             if (sign == 0)
227                 return true;
228             
229             return intDigits == oval.intDigits && fracDigits == oval.fracDigits &&
230                    ivalue.equals(oval.ivalue) && fvalue.equals(oval.fvalue);
231         }
232         public int compareTo(XDecimal val) {
233             if (sign != val.sign)
234                 return sign > val.sign ? 1 : -1;
235             if (sign == 0)
236                 return 0;
237             return sign * intComp(val);
238         }
239         private int intComp(XDecimal val) {
240             if (intDigits != val.intDigits)
241                 return intDigits > val.intDigits ? 1 : -1;
242             int ret = ivalue.compareTo(val.ivalue);
243             if (ret != 0)
244                 return ret > 0 ? 1 : -1;;
245             ret = fvalue.compareTo(val.fvalue);
246             return ret == 0 ? 0 : (ret > 0 ? 1 : -1);
247         }
248         private String JavaDoc canonical;
249         public synchronized String JavaDoc toString() {
250             if (canonical == null) {
251                 makeCanonical();
252             }
253             return canonical;
254         }
255         
256         private void makeCanonical() {
257             if (sign == 0) {
258                 if (integer)
259                     canonical = "0";
260                 else
261                     canonical = "0.0";
262                 return;
263             }
264             if (integer && sign > 0) {
265                 canonical = ivalue;
266                 return;
267             }
268             // for -0.1, total digits is 1, so we need 3 extra spots
269
StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(totalDigits+3);
270             if (sign == -1)
271                 buffer.append('-');
272             if (intDigits != 0)
273                 buffer.append(ivalue);
274             else
275                 buffer.append('0');
276             if (!integer) {
277                 buffer.append('.');
278                 if (fracDigits != 0) {
279                     buffer.append(fvalue);
280                 }
281                 else {
282                     buffer.append('0');
283                 }
284             }
285             canonical = buffer.toString();
286         }
287         
288         public BigDecimal JavaDoc getBigDecimal() {
289             if (sign == 0) {
290                 return new BigDecimal JavaDoc(BigInteger.ZERO);
291             }
292             return new BigDecimal JavaDoc(toString());
293         }
294         
295         public BigInteger JavaDoc getBigInteger() throws NumberFormatException JavaDoc {
296             if (fracDigits != 0) {
297                 throw new NumberFormatException JavaDoc();
298             }
299             if (sign == 0) {
300                 return BigInteger.ZERO;
301             }
302             if (sign == 1) {
303                 return new BigInteger JavaDoc(ivalue);
304             }
305             return new BigInteger JavaDoc("-" + ivalue);
306         }
307         
308         public long getLong() throws NumberFormatException JavaDoc {
309             if (fracDigits != 0) {
310                 throw new NumberFormatException JavaDoc();
311             }
312             if (sign == 0) {
313                 return 0L;
314             }
315             if (sign == 1) {
316                 return Long.parseLong(ivalue);
317             }
318             return Long.parseLong("-" + ivalue);
319         }
320         
321         public int getInt() throws NumberFormatException JavaDoc {
322             if (fracDigits != 0) {
323                 throw new NumberFormatException JavaDoc();
324             }
325             if (sign == 0) {
326                 return 0;
327             }
328             if (sign == 1) {
329                 return Integer.parseInt(ivalue);
330             }
331             return Integer.parseInt("-" + ivalue);
332         }
333         
334         public short getShort() throws NumberFormatException JavaDoc {
335             if (fracDigits != 0) {
336                 throw new NumberFormatException JavaDoc();
337             }
338             if (sign == 0) {
339                 return 0;
340             }
341             if (sign == 1) {
342                 return Short.parseShort(ivalue);
343             }
344             return Short.parseShort("-" + ivalue);
345         }
346         
347         public byte getByte() throws NumberFormatException JavaDoc {
348             if (fracDigits != 0) {
349                 throw new NumberFormatException JavaDoc();
350             }
351             if (sign == 0) {
352                 return 0;
353             }
354             if (sign == 1) {
355                 return Byte.parseByte(ivalue);
356             }
357             return Byte.parseByte("-" + ivalue);
358         }
359     }
360 } // class DecimalDV
361

362
Popular Tags