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 }