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