001: /*
002: * Copyright (c) 1998-2007 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Emil Ong
028: */
029:
030: package com.caucho.jaxb;
031:
032: import com.caucho.util.Base64;
033: import com.caucho.util.L10N;
034:
035: import java.math.BigDecimal;
036: import java.math.BigInteger;
037: import java.text.ParseException;
038: import java.text.SimpleDateFormat;
039: import java.util.Calendar;
040: import java.util.Date;
041: import java.util.TimeZone;
042: import javax.xml.bind.DatatypeConverterInterface;
043: import javax.xml.datatype.DatatypeFactory;
044: import javax.xml.datatype.DatatypeConfigurationException;
045: import javax.xml.datatype.XMLGregorianCalendar;
046: import javax.xml.namespace.NamespaceContext;
047: import javax.xml.namespace.QName;
048:
049: /**
050: */
051: public class DatatypeConverterImpl implements
052: DatatypeConverterInterface {
053: private static final L10N L = new L10N(DatatypeConverterImpl.class);
054: private static DatatypeFactory _datatypeFactory = null;
055:
056: private final char[] hexDigits = { '0', '1', '2', '3', '4', '5',
057: '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
058:
059: private final SimpleDateFormat dateFormat = new SimpleDateFormat(
060: "yyyy-MM-dd");
061: private final SimpleDateFormat timeFormat = new SimpleDateFormat(
062: "HH:mm:ss");
063: private final SimpleDateFormat dateTimeFormat = new SimpleDateFormat(
064: "yyyy-MM-dd'T'HH:mm:ss.SSSZ");
065:
066: public DatatypeConverterImpl() {
067: TimeZone gmt = TimeZone.getTimeZone("GMT");
068: dateFormat.getCalendar().setTimeZone(gmt);
069: timeFormat.getCalendar().setTimeZone(gmt);
070: dateTimeFormat.getCalendar().setTimeZone(gmt);
071: }
072:
073: //
074: // Parsers
075: //
076:
077: public String parseAnySimpleType(String lexicalXSDAnySimpleType) {
078: return lexicalXSDAnySimpleType;
079: }
080:
081: public byte[] parseBase64Binary(String lexicalXSDBase64Binary) {
082: return Base64.decodeToByteArray(lexicalXSDBase64Binary);
083: }
084:
085: public boolean parseBoolean(String lexicalXSDBoolean) {
086: return Boolean.parseBoolean(lexicalXSDBoolean);
087: }
088:
089: public byte parseByte(String lexicalXSDByte) {
090: return Byte.parseByte(lexicalXSDByte);
091: }
092:
093: public Calendar parseDate(String lexicalXSDDate)
094: throws IllegalArgumentException {
095: XMLGregorianCalendar xmlCal = getDatatypeFactory()
096: .newXMLGregorianCalendar(lexicalXSDDate);
097:
098: return xmlCal.toGregorianCalendar();
099: }
100:
101: public Calendar parseDateTime(String lexicalXSDDateTime)
102: throws IllegalArgumentException {
103: XMLGregorianCalendar xmlCal = getDatatypeFactory()
104: .newXMLGregorianCalendar(lexicalXSDDateTime);
105:
106: return xmlCal.toGregorianCalendar();
107: }
108:
109: public BigDecimal parseDecimal(String lexicalXSDDecimal) {
110: return new BigDecimal(lexicalXSDDecimal);
111: }
112:
113: public double parseDouble(String lexicalXSDDouble) {
114: return Double.parseDouble(lexicalXSDDouble);
115: }
116:
117: public float parseFloat(String lexicalXSDFloat) {
118: return Float.parseFloat(lexicalXSDFloat);
119: }
120:
121: public byte[] parseHexBinary(String lexicalXSDHexBinary)
122: throws IllegalArgumentException {
123: if (lexicalXSDHexBinary.length() % 2 != 0)
124: throw new IllegalArgumentException();
125:
126: byte[] buffer = new byte[lexicalXSDHexBinary.length() / 2];
127:
128: for (int i = 0; i < buffer.length; i++) {
129: buffer[i] = (byte) Integer.parseInt(lexicalXSDHexBinary
130: .substring(2 * i, 2 * i + 2), 16);
131: }
132:
133: return buffer;
134: }
135:
136: public int parseInt(String lexicalXSDInt) {
137: return Integer.parseInt(lexicalXSDInt);
138: }
139:
140: public BigInteger parseInteger(String lexicalXSDInteger) {
141: return new BigInteger(lexicalXSDInteger);
142: }
143:
144: public long parseLong(String lexicalXSDLong) {
145: return Long.parseLong(lexicalXSDLong);
146: }
147:
148: public QName parseQName(String lexicalXSDQName, NamespaceContext nsc)
149: throws IllegalArgumentException {
150: String[] parts = lexicalXSDQName.split(":", 2);
151:
152: if (parts.length == 1)
153: return new QName(lexicalXSDQName);
154: else {
155: String namespaceURI = nsc.getNamespaceURI(parts[0]);
156:
157: if (namespaceURI == null)
158: throw new IllegalArgumentException(L.l(
159: "Unknown prefix {0}", parts[0]));
160:
161: return new QName(namespaceURI, parts[1], parts[0]);
162: }
163: }
164:
165: public short parseShort(String lexicalXSDShort) {
166: return Short.parseShort(lexicalXSDShort);
167: }
168:
169: public String parseString(String lexicalXSDString) {
170: return lexicalXSDString;
171: }
172:
173: public Calendar parseTime(String lexicalXSDTime)
174: throws IllegalArgumentException {
175: XMLGregorianCalendar xmlCal = getDatatypeFactory()
176: .newXMLGregorianCalendar(lexicalXSDTime);
177:
178: return xmlCal.toGregorianCalendar();
179: }
180:
181: public long parseUnsignedInt(String lexicalXSDUnsignedInt) {
182: long x = parseLong(lexicalXSDUnsignedInt);
183:
184: if (x < 0)
185: throw new IllegalArgumentException(L
186: .l("Input not unsigned"));
187:
188: return x;
189: }
190:
191: public int parseUnsignedShort(String lexicalXSDUnsignedShort) {
192: int x = parseInt(lexicalXSDUnsignedShort);
193:
194: if (x < 0)
195: throw new IllegalArgumentException(L
196: .l("Input not unsigned"));
197:
198: return x;
199: }
200:
201: //
202: // Printers
203: //
204:
205: public String printAnySimpleType(String val) {
206: return val;
207: }
208:
209: public String printBase64Binary(byte[] val) {
210: return Base64.encodeFromByteArray(val);
211: }
212:
213: public String printBoolean(boolean val) {
214: return String.valueOf(val);
215: }
216:
217: public String printByte(byte val) {
218: return String.valueOf((int) val);
219: }
220:
221: public String printDate(Calendar val) {
222: dateFormat.setCalendar(val);
223: return dateFormat.format(val.getTime());
224: }
225:
226: public String printDateTime(Calendar val) {
227: // ISO8601 fix
228: dateTimeFormat.setCalendar(val);
229: String base = dateTimeFormat.format(val.getTime());
230:
231: return base.substring(0, base.length() - 2) + ':'
232: + base.substring(base.length() - 2);
233: }
234:
235: public String printDecimal(BigDecimal val) {
236: return val.toString();
237: }
238:
239: public String printDouble(double val) {
240: return String.valueOf(val);
241: }
242:
243: public String printFloat(float val) {
244: return String.valueOf(val);
245: }
246:
247: public String printHexBinary(byte[] val) {
248: StringBuilder sb = new StringBuilder();
249:
250: for (int i = 0; i < val.length; i++) {
251: sb.append(hexDigits[((int) val[i] & 0xff) >>> 4]);
252: sb.append(hexDigits[val[i] & 0x0f]);
253: }
254:
255: return sb.toString();
256: }
257:
258: public String printInt(int val) {
259: return String.valueOf(val);
260: }
261:
262: public String printInteger(BigInteger val) {
263: return val.toString();
264: }
265:
266: public String printLong(long val) {
267: return String.valueOf(val);
268: }
269:
270: public String printQName(QName val, NamespaceContext nsc) {
271: if (val.getPrefix() != null && !"".equals(val.getPrefix()))
272: return val.getPrefix() + ":" + val.getLocalPart();
273:
274: if (val.getNamespaceURI() == null
275: || "".equals(val.getNamespaceURI()))
276: return val.getLocalPart();
277:
278: String prefix = nsc.getPrefix(val.getNamespaceURI());
279:
280: if (prefix == null)
281: throw new IllegalArgumentException(L.l(
282: "No prefix found for namespace {0}", val
283: .getNamespaceURI()));
284:
285: return prefix + ":" + val.getLocalPart();
286: }
287:
288: public String printShort(short val) {
289: return String.valueOf(val);
290: }
291:
292: public String printString(String val) {
293: return val;
294: }
295:
296: public String printTime(Calendar val) {
297: timeFormat.setCalendar(val);
298: return timeFormat.format(val.getTime());
299: }
300:
301: public String printUnsignedInt(long val) {
302: return String.valueOf(val);
303: }
304:
305: public String printUnsignedShort(int val) {
306: return String.valueOf(val);
307: }
308:
309: private static DatatypeFactory getDatatypeFactory() {
310: if (_datatypeFactory == null) {
311: try {
312: _datatypeFactory = DatatypeFactory.newInstance();
313: } catch (DatatypeConfigurationException e) {
314: throw new RuntimeException(e);
315: }
316: }
317:
318: return _datatypeFactory;
319: }
320: }
|