KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > xquery > typing > QAtomicSerializer


1 /*
2  * This file belongs to the XQuark distribution.
3  * Copyright (C) 2003 XQuark Group.
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.xquery.typing;
24
25 import java.math.BigDecimal JavaDoc;
26
27 import org.xquark.schema.SimpleType;
28 import org.xquark.schema.datatypes.*;
29 import org.xquark.schema.validation.ValidationContextProvider;
30 import org.xquark.xquery.parser.XQueryException;
31
32 /**
33  * Implements XQuery serialization for atomic values. Inputs are java classes
34  * used for values in the XQuark XML schema implementation (see
35  * @link org.xquark.schema.datatypes) and produce the XQuery conformant string
36  * output.
37  * NOTE: XQuery serialization is not strictly implemented here for performance
38  * reasons. Especially, decimal are using Java serialization because it is
39  * considered not only more efficient but "smarter"...
40  */

41 public class QAtomicSerializer {
42
43     private static final String JavaDoc NAN = "NaN";
44     private static final String JavaDoc INF = "INF";
45     private static final String JavaDoc POSITIVE_INF = "+INF";
46     private static final String JavaDoc NEGATIVE_INF = "-INF";
47     private static final double MAX_DECIMAL = 1E+6;
48     private static final double MIN_DECIMAL = 1E-6;
49     private static final String JavaDoc ZERO = "0";
50     private static final Double JavaDoc NEG_ZERO_D = new Double JavaDoc("-0.0");
51     private static final Float JavaDoc NEG_ZERO_F = new Float JavaDoc("-0.0");
52
53     //private DecimalFormat format = (DecimalFormat)DecimalFormat.getInstance(Locale.US);
54
private ValidationContextProvider context = null;
55
56     public QAtomicSerializer() {
57     }
58
59     public QAtomicSerializer(ValidationContextProvider contextProvider) {
60         context = contextProvider;
61     }
62
63     //
64
// SPECIFIC XQUERY rules
65
//
66
public String JavaDoc serialize(QName sValue) throws XQueryException {
67         throw new XQueryException("QName cannot be cast to string.");
68     }
69     public String JavaDoc serialize(URI sValue) throws XQueryException {
70         if (sValue == null)
71             return null;
72         return sValue.toString();
73     }
74
75     public String JavaDoc serialize(SimpleType sType, String JavaDoc sValue) {
76         if (sValue == null)
77             return null;
78         return sType.normalizedValue(sValue);
79     }
80
81     //
82
// TIME TYPES
83
//
84
public String JavaDoc serialize(SimpleType sType, DateTime sValue) throws XQueryException {
85         if (sValue == null)
86             return null;
87         String JavaDoc ret = sType.toXMLString(sValue, context);
88         switch (sType.getPrimitive().getType()) {
89             case PrimitiveType.DATE_TIME :
90             case PrimitiveType.TIME :
91             case PrimitiveType.DATE :
92                 if (sValue.hasTimeZone() && sValue.getTimeZone() == 0) // remove 'z'
93
ret = ret.substring(0, ret.length() - 1);
94                 break;
95             default :
96                 }
97         return ret;
98     }
99
100     //
101
// NUMERIC TYPES:
102
// NOTE: looks like schema processing but slightly different, but piping to
103
// schema conversion as specified would be too slow...
104

105     public String JavaDoc serialize(Long JavaDoc sValue) throws XQueryException {
106         if (sValue == null)
107             return null;
108         return sValue.toString();
109     }
110
111     public String JavaDoc serialize(BigDecimal JavaDoc sValue) throws XQueryException {
112         if (sValue == null)
113             return null;
114         // check if there are significant decimal digits
115
return removeNotSignificantDigits(sValue.toString());
116     }
117
118     public String JavaDoc removeNotSignificantDigits(String JavaDoc decimal) {
119         int index = decimal.length(), lastZero = index;
120         char wChar;
121         do {
122             if (index == 0)
123                 return decimal;
124             wChar = decimal.charAt(--index);
125             if (wChar == '0' && lastZero == index + 1)
126                 lastZero = index;
127             if (wChar == 'E')
128                 return decimal; // scientific notation used by Double.toString()
129
} while (wChar != '.');
130         if (lastZero == index + 1)
131             return decimal.substring(0, index);
132         else
133             return decimal.substring(0, lastZero);
134     }
135
136     public String JavaDoc serialize(Double JavaDoc sValue) throws XQueryException {
137         if (sValue == null)
138             return null;
139         if (sValue.isNaN())
140             return NAN;
141
142         if (sValue.isInfinite()) {
143             if (sValue.doubleValue() > 0)
144                 return INF;
145             else
146                 return NEGATIVE_INF;
147         } else {
148             if (sValue.equals(NEG_ZERO_D))
149                 return ZERO;
150             else
151                 return removeNotSignificantDigits(sValue.toString());
152         }
153
154         // SPECIFICATION IMPLEMENTATION (SLOW)
155
// double value = sValue.doubleValue();
156
// if (value == 0) return ZERO;
157
//
158
// double abs = Math.abs(value);
159
// if (MIN_DECIMAL <= abs && abs <= MAX_DECIMAL) // TODO: format directly double using decimal rules
160
// return serialize(new BigDecimal(sValue.toString())); //NOTE: not efficient but a "clean" method to transform floating point into decimals...
161
// else if (sValue.isInfinite()) {
162
// if (sValue.doubleValue() > 0)
163
// return INF;
164
// else
165
// return NEGATIVE_INF;
166
// }
167
// else {
168
// format.applyPattern("0.0##############E0");
169
// return format.format(value);
170
// }
171
}
172
173     public String JavaDoc serialize(Float JavaDoc sValue) throws XQueryException {
174         if (sValue == null)
175             return null;
176         if (sValue.isNaN())
177             return NAN;
178
179         if (sValue.isInfinite()) {
180             if (sValue.floatValue() > 0)
181                 return INF;
182             else
183                 return NEGATIVE_INF;
184         } else {
185             if (sValue.equals(NEG_ZERO_F))
186                 return ZERO;
187             else
188                 return removeNotSignificantDigits(sValue.toString());
189         }
190
191         //SPECIFICATION IMPLEMENTATION (SLOW)
192
// float value = sValue.floatValue();
193
// if (value == 0) return ZERO;
194
//
195
// float abs = Math.abs(value);
196
// if (MIN_DECIMAL <= abs && abs <= MAX_DECIMAL) // TODO: format directly double using decimal rules
197
// return serialize(new BigDecimal(sValue.toString())); //NOTE: not efficient but a "clean" method to transform floating point into decimals...
198
// else if (sValue.isInfinite()) {
199
// if (sValue.floatValue() > 0)
200
// return INF;
201
// else
202
// return NEGATIVE_INF;
203
// }
204
// else {
205
// format.applyPattern("0.0######E0");
206
// return format.format(value);
207
// }
208
}
209
210     //
211
// SCHEMA RULES
212
//
213
public String JavaDoc serialize(SimpleType sType, Boolean JavaDoc sValue) throws XQueryException {
214         if (sValue == null)
215             return null;
216         return sType.toXMLString(sValue, context);
217     }
218
219     public String JavaDoc serialize(SimpleType sType, ByteArray sValue) throws XQueryException {
220         if (sValue == null)
221             return null;
222         return sType.toXMLString(sValue, context);
223     }
224
225     public String JavaDoc serialize(SimpleType sType, byte[] sValue) throws XQueryException {
226         if (sValue == null)
227             return null;
228         return sType.toXMLString(sValue, context);
229     }
230
231     public String JavaDoc serialize(SimpleType sType, Duration sValue) throws XQueryException {
232         if (sValue == null)
233             return null;
234         return sType.toXMLString(sValue, context);
235     }
236
237     // ADD 29/03/04
238
public String JavaDoc serialize(SimpleType sType, Object JavaDoc obj) throws XQueryException {
239         // TODO see if sType should not be always not null
240
if (obj == null)
241             return null;
242         if (sType == null) {
243             return obj.toString();
244         }
245         switch (sType.getPrimitive().getType()) {
246             case PrimitiveType.DECIMAL :
247                 // TODO use info from simple type to dispatch cases
248
if (obj instanceof BigDecimal JavaDoc)
249                     return serialize((BigDecimal JavaDoc) obj);
250                 else
251                     return serialize((Long JavaDoc) obj);
252             case PrimitiveType.DOUBLE :
253                 return serialize((Double JavaDoc) obj);
254             case PrimitiveType.FLOAT :
255                 return serialize((Float JavaDoc) obj);
256             case PrimitiveType.QNAME :
257                 return serialize((QName) obj);
258             case PrimitiveType.DATE_TIME :
259                 return serialize(sType, (DateTime) obj);
260             case PrimitiveType.ANY_URI :
261                 return serialize((URI) obj);
262             case PrimitiveType.STRING :
263                 return serialize(sType, (String JavaDoc) obj);
264
265             case PrimitiveType.DATE :
266             case PrimitiveType.TIME :
267             case PrimitiveType.BOOLEAN :
268             case PrimitiveType.BASE64_BINARY :
269             case PrimitiveType.HEX_BINARY :
270             case PrimitiveType.DURATION :
271             default :
272                 return sType.toXMLString(obj, context);
273         }
274     }
275 }
276
Popular Tags