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