1 /*
2 * Copyright (c) 2003, 2018 Oracle and/or its affiliates. All rights reserved.
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Distribution License v. 1.0, which is available at
6 * http://www.eclipse.org/org/documents/edl-v10.php.
7 *
8 * SPDX-License-Identifier: BSD-3-Clause
9 */
10
11 package javax.xml.bind;
12
13 import javax.xml.namespace.NamespaceContext;
14
15 /**
16 * <p>
17 * The javaType binding declaration can be used to customize the binding of
18 * an XML schema datatype to a Java datatype. Customizations can involve
19 * writing a parse and print method for parsing and printing lexical
20 * representations of a XML schema datatype respectively. However, writing
21 * parse and print methods requires knowledge of the lexical representations (
22 * <a href="http://www.w3.org/TR/xmlschema-2/"> XML Schema Part2: Datatypes
23 * specification </a>) and hence may be difficult to write.
24 * </p>
25 * <p>
26 * This class makes it easier to write parse and print methods. It defines
27 * static parse and print methods that provide access to a JAXB provider's
28 * implementation of parse and print methods. These methods are invoked by
29 * custom parse and print methods. For example, the binding of xsd:dateTime
30 * to a long can be customized using parse and print methods as follows:
31 * <blockquote>
32 * <pre>
33 * // Customized parse method
34 * public long myParseCal( String dateTimeString ) {
35 * java.util.Calendar cal = DatatypeConverter.parseDateTime(dateTimeString);
36 * long longval = convert_calendar_to_long(cal); //application specific
37 * return longval;
38 * }
39 *
40 * // Customized print method
41 * public String myPrintCal( Long longval ) {
42 * java.util.Calendar cal = convert_long_to_calendar(longval) ; //application specific
43 * String dateTimeString = DatatypeConverter.printDateTime(cal);
44 * return dateTimeString;
45 * }
46 * </pre>
47 * </blockquote>
48 * <p>
49 * There is a static parse and print method corresponding to each parse and
50 * print method respectively in the {@link DatatypeConverterInterface
51 * DatatypeConverterInterface}.
52 * <p>
53 * The static methods defined in the class can also be used to specify
54 * a parse or a print method in a javaType binding declaration.
55 * </p>
56 * <p>
57 * JAXB Providers are required to call the
58 * {@link #setDatatypeConverter(DatatypeConverterInterface)
59 * setDatatypeConverter} api at some point before the first marshal or unmarshal
60 * operation (perhaps during the call to JAXBContext.newInstance). This step is
61 * necessary to configure the converter that should be used to perform the
62 * print and parse functionality.
63 * </p>
64 *
65 * <p>
66 * A print method for a XML schema datatype can output any lexical
67 * representation that is valid with respect to the XML schema datatype.
68 * If an error is encountered during conversion, then an IllegalArgumentException,
69 * or a subclass of IllegalArgumentException must be thrown by the method.
70 * </p>
71 *
72 * @author <ul><li>Sekhar Vajjhala, Sun Microsystems, Inc.</li><li>Joe Fialli, Sun Microsystems Inc.</li><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Ryan Shoemaker,Sun Microsystems Inc.</li></ul>
73 * @see DatatypeConverterInterface
74 * @see ParseConversionEvent
75 * @see PrintConversionEvent
76 * @since 1.6, JAXB 1.0
77 */
78
79 final public class DatatypeConverter {
80
81 // delegate to this instance of DatatypeConverter
82 private static volatile DatatypeConverterInterface theConverter = null;
83
84 private final static JAXBPermission SET_DATATYPE_CONVERTER_PERMISSION =
85 new JAXBPermission("setDatatypeConverter");
86
87 private DatatypeConverter() {
88 // private constructor
89 }
90
91 /**
92 * This method is for JAXB provider use only.
93 * <p>
94 * JAXB Providers are required to call this method at some point before
95 * allowing any of the JAXB client marshal or unmarshal operations to
96 * occur. This is necessary to configure the datatype converter that
97 * should be used to perform the print and parse conversions.
98 *
99 * <p>
100 * Calling this api repeatedly will have no effect - the
101 * DatatypeConverterInterface instance passed into the first invocation is
102 * the one that will be used from then on.
103 *
104 * @param converter an instance of a class that implements the
105 * DatatypeConverterInterface class - this parameter must not be null.
106 * @throws IllegalArgumentException if the parameter is null
107 * @throws SecurityException
108 * If the {@link SecurityManager} in charge denies the access to
109 * set the datatype converter.
110 * @see JAXBPermission
111 */
112 public static void setDatatypeConverter( DatatypeConverterInterface converter ) {
113 if( converter == null ) {
114 throw new IllegalArgumentException(
115 Messages.format( Messages.CONVERTER_MUST_NOT_BE_NULL ) );
116 } else if( theConverter == null ) {
117 SecurityManager sm = System.getSecurityManager();
118 if (sm != null)
119 sm.checkPermission(SET_DATATYPE_CONVERTER_PERMISSION);
120 theConverter = converter;
121 }
122 }
123
124 private static synchronized void initConverter() {
125 theConverter = new DatatypeConverterImpl();
126 }
127
128 /**
129 * <p>
130 * Convert the lexical XSD string argument into a String value.
131 * @param lexicalXSDString
132 * A string containing a lexical representation of
133 * xsd:string.
134 * @return
135 * A String value represented by the string argument.
136 */
137 public static String parseString( String lexicalXSDString ) {
138 if (theConverter == null) initConverter();
139 return theConverter.parseString( lexicalXSDString );
140 }
141
142 /**
143 * <p>
144 * Convert the string argument into a BigInteger value.
145 * @param lexicalXSDInteger
146 * A string containing a lexical representation of
147 * xsd:integer.
148 * @return
149 * A BigInteger value represented by the string argument.
150 * @throws NumberFormatException <code>lexicalXSDInteger</code> is not a valid string representation of a {@link java.math.BigInteger} value.
151 */
152 public static java.math.BigInteger parseInteger( String lexicalXSDInteger ) {
153 if (theConverter == null) initConverter();
154 return theConverter.parseInteger( lexicalXSDInteger );
155 }
156
157 /**
158 * <p>
159 * Convert the string argument into an int value.
160 * @param lexicalXSDInt
161 * A string containing a lexical representation of
162 * xsd:int.
163 * @return
164 * A int value represented by the string argument.
165 * @throws NumberFormatException <code>lexicalXSDInt</code> is not a valid string representation of an <code>int</code> value.
166 */
167 public static int parseInt( String lexicalXSDInt ) {
168 if (theConverter == null) initConverter();
169 return theConverter.parseInt( lexicalXSDInt );
170 }
171
172 /**
173 * <p>
174 * Converts the string argument into a long value.
175 * @param lexicalXSDLong
176 * A string containing lexical representation of
177 * xsd:long.
178 * @return
179 * A long value represented by the string argument.
180 * @throws NumberFormatException <code>lexicalXSDLong</code> is not a valid string representation of a <code>long</code> value.
181 */
182 public static long parseLong( String lexicalXSDLong ) {
183 if (theConverter == null) initConverter();
184 return theConverter.parseLong( lexicalXSDLong );
185 }
186
187 /**
188 * <p>
189 * Converts the string argument into a short value.
190 * @param lexicalXSDShort
191 * A string containing lexical representation of
192 * xsd:short.
193 * @return
194 * A short value represented by the string argument.
195 * @throws NumberFormatException <code>lexicalXSDShort</code> is not a valid string representation of a <code>short</code> value.
196 */
197 public static short parseShort( String lexicalXSDShort ) {
198 if (theConverter == null) initConverter();
199 return theConverter.parseShort( lexicalXSDShort );
200 }
201
202 /**
203 * <p>
204 * Converts the string argument into a BigDecimal value.
205 * @param lexicalXSDDecimal
206 * A string containing lexical representation of
207 * xsd:decimal.
208 * @return
209 * A BigDecimal value represented by the string argument.
210 * @throws NumberFormatException <code>lexicalXSDDecimal</code> is not a valid string representation of {@link java.math.BigDecimal}.
211 */
212 public static java.math.BigDecimal parseDecimal( String lexicalXSDDecimal ) {
213 if (theConverter == null) initConverter();
214 return theConverter.parseDecimal( lexicalXSDDecimal );
215 }
216
217 /**
218 * <p>
219 * Converts the string argument into a float value.
220 * @param lexicalXSDFloat
221 * A string containing lexical representation of
222 * xsd:float.
223 * @return
224 * A float value represented by the string argument.
225 * @throws NumberFormatException <code>lexicalXSDFloat</code> is not a valid string representation of a <code>float</code> value.
226 */
227 public static float parseFloat( String lexicalXSDFloat ) {
228 if (theConverter == null) initConverter();
229 return theConverter.parseFloat( lexicalXSDFloat );
230 }
231
232 /**
233 * <p>
234 * Converts the string argument into a double value.
235 * @param lexicalXSDDouble
236 * A string containing lexical representation of
237 * xsd:double.
238 * @return
239 * A double value represented by the string argument.
240 * @throws NumberFormatException <code>lexicalXSDDouble</code> is not a valid string representation of a <code>double</code> value.
241 */
242 public static double parseDouble( String lexicalXSDDouble ) {
243 if (theConverter == null) initConverter();
244 return theConverter.parseDouble( lexicalXSDDouble );
245 }
246
247 /**
248 * <p>
249 * Converts the string argument into a boolean value.
250 * @param lexicalXSDBoolean
251 * A string containing lexical representation of
252 * xsd:boolean.
253 * @return
254 * A boolean value represented by the string argument.
255 * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:boolean.
256 */
257 public static boolean parseBoolean( String lexicalXSDBoolean ) {
258 if (theConverter == null) initConverter();
259 return theConverter.parseBoolean( lexicalXSDBoolean );
260 }
261
262 /**
263 * <p>
264 * Converts the string argument into a byte value.
265 * @param lexicalXSDByte
266 * A string containing lexical representation of
267 * xsd:byte.
268 * @return
269 * A byte value represented by the string argument.
270 * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:byte.
271 */
272 public static byte parseByte( String lexicalXSDByte ) {
273 if (theConverter == null) initConverter();
274 return theConverter.parseByte( lexicalXSDByte );
275 }
276
277 /**
278 * <p>
279 * Converts the string argument into a byte value.
280 *
281 * <p>
282 * String parameter {@code lexicalXSDQname} must conform to lexical value space specifed at
283 * <a href="http://www.w3.org/TR/xmlschema-2/#QName">XML Schema Part 2:Datatypes specification:QNames</a>
284 *
285 * @param lexicalXSDQName
286 * A string containing lexical representation of xsd:QName.
287 * @param nsc
288 * A namespace context for interpreting a prefix within a QName.
289 * @return
290 * A QName value represented by the string argument.
291 * @throws IllegalArgumentException if string parameter does not conform to XML Schema Part 2 specification or
292 * if namespace prefix of {@code lexicalXSDQname} is not bound to a URI in NamespaceContext {@code nsc}.
293 */
294 public static javax.xml.namespace.QName parseQName( String lexicalXSDQName,
295 NamespaceContext nsc) {
296 if (theConverter == null) initConverter();
297 return theConverter.parseQName( lexicalXSDQName, nsc );
298 }
299
300 /**
301 * <p>
302 * Converts the string argument into a Calendar value.
303 * @param lexicalXSDDateTime
304 * A string containing lexical representation of
305 * xsd:datetime.
306 * @return
307 * A Calendar object represented by the string argument.
308 * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:dateTime.
309 */
310 public static java.util.Calendar parseDateTime( String lexicalXSDDateTime ) {
311 if (theConverter == null) initConverter();
312 return theConverter.parseDateTime( lexicalXSDDateTime );
313 }
314
315 /**
316 * <p>
317 * Converts the string argument into an array of bytes.
318 * @param lexicalXSDBase64Binary
319 * A string containing lexical representation
320 * of xsd:base64Binary.
321 * @return
322 * An array of bytes represented by the string argument.
323 * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:base64Binary
324 */
325 public static byte[] parseBase64Binary( String lexicalXSDBase64Binary ) {
326 if (theConverter == null) initConverter();
327 return theConverter.parseBase64Binary( lexicalXSDBase64Binary );
328 }
329
330 /**
331 * <p>
332 * Converts the string argument into an array of bytes.
333 * @param lexicalXSDHexBinary
334 * A string containing lexical representation of
335 * xsd:hexBinary.
336 * @return
337 * An array of bytes represented by the string argument.
338 * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:hexBinary.
339 */
340 public static byte[] parseHexBinary( String lexicalXSDHexBinary ) {
341 if (theConverter == null) initConverter();
342 return theConverter.parseHexBinary( lexicalXSDHexBinary );
343 }
344
345 /**
346 * <p>
347 * Converts the string argument into a long value.
348 * @param lexicalXSDUnsignedInt
349 * A string containing lexical representation
350 * of xsd:unsignedInt.
351 * @return
352 * A long value represented by the string argument.
353 * @throws NumberFormatException if string parameter can not be parsed into a {@code long} value.
354 */
355 public static long parseUnsignedInt( String lexicalXSDUnsignedInt ) {
356 if (theConverter == null) initConverter();
357 return theConverter.parseUnsignedInt( lexicalXSDUnsignedInt );
358 }
359
360 /**
361 * <p>
362 * Converts the string argument into an int value.
363 * @param lexicalXSDUnsignedShort
364 * A string containing lexical
365 * representation of xsd:unsignedShort.
366 * @return
367 * An int value represented by the string argument.
368 * @throws NumberFormatException if string parameter can not be parsed into an {@code int} value.
369 */
370 public static int parseUnsignedShort( String lexicalXSDUnsignedShort ) {
371 if (theConverter == null) initConverter();
372 return theConverter.parseUnsignedShort( lexicalXSDUnsignedShort );
373 }
374
375 /**
376 * <p>
377 * Converts the string argument into a Calendar value.
378 * @param lexicalXSDTime
379 * A string containing lexical representation of
380 * xsd:time.
381 * @return
382 * A Calendar value represented by the string argument.
383 * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:Time.
384 */
385 public static java.util.Calendar parseTime( String lexicalXSDTime ) {
386 if (theConverter == null) initConverter();
387 return theConverter.parseTime( lexicalXSDTime );
388 }
389 /**
390 * <p>
391 * Converts the string argument into a Calendar value.
392 * @param lexicalXSDDate
393 * A string containing lexical representation of
394 * xsd:Date.
395 * @return
396 * A Calendar value represented by the string argument.
397 * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:Date.
398 */
399 public static java.util.Calendar parseDate( String lexicalXSDDate ) {
400 if (theConverter == null) initConverter();
401 return theConverter.parseDate( lexicalXSDDate );
402 }
403
404 /**
405 * <p>
406 * Return a string containing the lexical representation of the
407 * simple type.
408 * @param lexicalXSDAnySimpleType
409 * A string containing lexical
410 * representation of the simple type.
411 * @return
412 * A string containing the lexical representation of the
413 * simple type.
414 */
415 public static String parseAnySimpleType( String lexicalXSDAnySimpleType ) {
416 if (theConverter == null) initConverter();
417 return theConverter.parseAnySimpleType( lexicalXSDAnySimpleType );
418 }
419 /**
420 * <p>
421 * Converts the string argument into a string.
422 * @param val
423 * A string value.
424 * @return
425 * A string containing a lexical representation of xsd:string.
426 */
427 // also indicate the print methods produce a lexical
428 // representation for given Java datatypes.
429
430 public static String printString( String val ) {
431 if (theConverter == null) initConverter();
432 return theConverter.printString( val );
433 }
434
435 /**
436 * <p>
437 * Converts a BigInteger value into a string.
438 * @param val
439 * A BigInteger value
440 * @return
441 * A string containing a lexical representation of xsd:integer
442 * @throws IllegalArgumentException {@code val} is null.
443 */
444 public static String printInteger( java.math.BigInteger val ) {
445 if (theConverter == null) initConverter();
446 return theConverter.printInteger( val );
447 }
448
449 /**
450 * <p>
451 * Converts an int value into a string.
452 * @param val
453 * An int value
454 * @return
455 * A string containing a lexical representation of xsd:int
456 */
457 public static String printInt( int val ) {
458 if (theConverter == null) initConverter();
459 return theConverter.printInt( val );
460 }
461
462 /**
463 * <p>
464 * Converts A long value into a string.
465 * @param val
466 * A long value
467 * @return
468 * A string containing a lexical representation of xsd:long
469 */
470 public static String printLong( long val ) {
471 if (theConverter == null) initConverter();
472 return theConverter.printLong( val );
473 }
474
475 /**
476 * <p>
477 * Converts a short value into a string.
478 * @param val
479 * A short value
480 * @return
481 * A string containing a lexical representation of xsd:short
482 */
483 public static String printShort( short val ) {
484 if (theConverter == null) initConverter();
485 return theConverter.printShort( val );
486 }
487
488 /**
489 * <p>
490 * Converts a BigDecimal value into a string.
491 * @param val
492 * A BigDecimal value
493 * @return
494 * A string containing a lexical representation of xsd:decimal
495 * @throws IllegalArgumentException {@code val} is null.
496 */
497 public static String printDecimal( java.math.BigDecimal val ) {
498 if (theConverter == null) initConverter();
499 return theConverter.printDecimal( val );
500 }
501
502 /**
503 * <p>
504 * Converts a float value into a string.
505 * @param val
506 * A float value
507 * @return
508 * A string containing a lexical representation of xsd:float
509 */
510 public static String printFloat( float val ) {
511 if (theConverter == null) initConverter();
512 return theConverter.printFloat( val );
513 }
514
515 /**
516 * <p>
517 * Converts a double value into a string.
518 * @param val
519 * A double value
520 * @return
521 * A string containing a lexical representation of xsd:double
522 */
523 public static String printDouble( double val ) {
524 if (theConverter == null) initConverter();
525 return theConverter.printDouble( val );
526 }
527
528 /**
529 * <p>
530 * Converts a boolean value into a string.
531 * @param val
532 * A boolean value
533 * @return
534 * A string containing a lexical representation of xsd:boolean
535 */
536 public static String printBoolean( boolean val ) {
537 if (theConverter == null) initConverter();
538 return theConverter.printBoolean( val );
539 }
540
541 /**
542 * <p>
543 * Converts a byte value into a string.
544 * @param val
545 * A byte value
546 * @return
547 * A string containing a lexical representation of xsd:byte
548 */
549 public static String printByte( byte val ) {
550 if (theConverter == null) initConverter();
551 return theConverter.printByte( val );
552 }
553
554 /**
555 * <p>
556 * Converts a QName instance into a string.
557 * @param val
558 * A QName value
559 * @param nsc
560 * A namespace context for interpreting a prefix within a QName.
561 * @return
562 * A string containing a lexical representation of QName
563 * @throws IllegalArgumentException if {@code val} is null or
564 * if {@code nsc} is non-null or {@code nsc.getPrefix(nsprefixFromVal)} is null.
565 */
566 public static String printQName( javax.xml.namespace.QName val,
567 NamespaceContext nsc ) {
568 if (theConverter == null) initConverter();
569 return theConverter.printQName( val, nsc );
570 }
571
572 /**
573 * <p>
574 * Converts a Calendar value into a string.
575 * @param val
576 * A Calendar value
577 * @return
578 * A string containing a lexical representation of xsd:dateTime
579 * @throws IllegalArgumentException if {@code val} is null.
580 */
581 public static String printDateTime( java.util.Calendar val ) {
582 if (theConverter == null) initConverter();
583 return theConverter.printDateTime( val );
584 }
585
586 /**
587 * <p>
588 * Converts an array of bytes into a string.
589 * @param val
590 * An array of bytes
591 * @return
592 * A string containing a lexical representation of xsd:base64Binary
593 * @throws IllegalArgumentException if {@code val} is null.
594 */
595 public static String printBase64Binary( byte[] val ) {
596 if (theConverter == null) initConverter();
597 return theConverter.printBase64Binary( val );
598 }
599
600 /**
601 * <p>
602 * Converts an array of bytes into a string.
603 * @param val
604 * An array of bytes
605 * @return
606 * A string containing a lexical representation of xsd:hexBinary
607 * @throws IllegalArgumentException if {@code val} is null.
608 */
609 public static String printHexBinary( byte[] val ) {
610 if (theConverter == null) initConverter();
611 return theConverter.printHexBinary( val );
612 }
613
614 /**
615 * <p>
616 * Converts a long value into a string.
617 * @param val
618 * A long value
619 * @return
620 * A string containing a lexical representation of xsd:unsignedInt
621 */
622 public static String printUnsignedInt( long val ) {
623 if (theConverter == null) initConverter();
624 return theConverter.printUnsignedInt( val );
625 }
626
627 /**
628 * <p>
629 * Converts an int value into a string.
630 * @param val
631 * An int value
632 * @return
633 * A string containing a lexical representation of xsd:unsignedShort
634 */
635 public static String printUnsignedShort( int val ) {
636 if (theConverter == null) initConverter();
637 return theConverter.printUnsignedShort( val );
638 }
639
640 /**
641 * <p>
642 * Converts a Calendar value into a string.
643 * @param val
644 * A Calendar value
645 * @return
646 * A string containing a lexical representation of xsd:time
647 * @throws IllegalArgumentException if {@code val} is null.
648 */
649 public static String printTime( java.util.Calendar val ) {
650 if (theConverter == null) initConverter();
651 return theConverter.printTime( val );
652 }
653
654 /**
655 * <p>
656 * Converts a Calendar value into a string.
657 * @param val
658 * A Calendar value
659 * @return
660 * A string containing a lexical representation of xsd:date
661 * @throws IllegalArgumentException if {@code val} is null.
662 */
663 public static String printDate( java.util.Calendar val ) {
664 if (theConverter == null) initConverter();
665 return theConverter.printDate( val );
666 }
667
668 /**
669 * <p>
670 * Converts a string value into a string.
671 * @param val
672 * A string value
673 * @return
674 * A string containing a lexical representation of xsd:AnySimpleType
675 */
676 public static String printAnySimpleType( String val ) {
677 if (theConverter == null) initConverter();
678 return theConverter.printAnySimpleType( val );
679 }
680 }
681