/*
 * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package jakarta.xml.bind;

import javax.xml.namespace.NamespaceContext;

/**
 * <p>
 * The javaType binding declaration can be used to customize the binding of 
 * an XML schema datatype to a Java datatype. Customizations can involve 
 * writing a parse and print method for parsing and printing lexical 
 * representations of a XML schema datatype respectively. However, writing 
 * parse and print methods requires knowledge of the lexical representations ( 
 * <a href="http://www.w3.org/TR/xmlschema-2/"> XML Schema Part2: Datatypes 
 * specification </a>) and hence may be difficult to write. 
 * </p>
 * <p>
 * This class makes it easier to write parse and print methods. It defines
 * static parse and print methods that provide access to a Jakarta XML Binding provider's 
 * implementation of parse and print methods. These methods are invoked by 
 * custom parse and print methods. For example, the binding of xsd:dateTime 
 * to a long can be customized using parse and print methods as follows:
 * <blockquote>
 *    <pre>
 *    // Customized parse method 
 *    public long myParseCal( String dateTimeString ) {
 *        java.util.Calendar cal = DatatypeConverter.parseDateTime(dateTimeString);
 *        long longval = convert_calendar_to_long(cal); //application specific
 *        return longval;
 *    }
 *     
 *    // Customized print method
 *    public String myPrintCal( Long longval ) {
 *        java.util.Calendar cal = convert_long_to_calendar(longval) ; //application specific
 *        String dateTimeString = DatatypeConverter.printDateTime(cal);
 *        return dateTimeString;
 *    }
 *    </pre>
 * </blockquote>
 * <p>
 * There is a static parse and print method corresponding to each parse and 
 * print method respectively in the {@link DatatypeConverterInterface 
 * DatatypeConverterInterface}. 
 * <p>
 * The static methods defined in the class can also be used to specify
 * a parse or a print method in a javaType binding declaration.
 * </p>
 * <p>
 * Jakarta XML Binding Providers are required to call the 
 * {@link #setDatatypeConverter(DatatypeConverterInterface) 
 * setDatatypeConverter} api at some point before the first marshal or unmarshal 
 * operation (perhaps during the call to JAXBContext.newInstance).  This step is 
 * necessary to configure the converter that should be used to perform the 
 * print and parse functionality.  
 * </p>
 * 
 * <p>
 * A print method for a XML schema datatype can output any lexical 
 * representation that is valid with respect to the XML schema datatype.
 * If an error is encountered during conversion, then an IllegalArgumentException,
 * or a subclass of IllegalArgumentException must be thrown by the method.
 * </p>
 * 
 * @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>
 * @see DatatypeConverterInterface
 * @see ParseConversionEvent
 * @see PrintConversionEvent
 * @since 1.6, JAXB 1.0
 */

final public class DatatypeConverter {

    // delegate to this instance of DatatypeConverter
    private static volatile DatatypeConverterInterface theConverter = null;

    private final static JAXBPermission SET_DATATYPE_CONVERTER_PERMISSION =
                           new JAXBPermission("setDatatypeConverter");

    private DatatypeConverter() {
        // private constructor
    }
    
    /**
     * This method is for Jakarta XML Binding provider use only.
     * <p>
     * Jakarta XML Binding Providers are required to call this method at some point before
     * allowing any of the Jakarta XML Binding client marshal or unmarshal operations to
     * occur.  This is necessary to configure the datatype converter that 
     * should be used to perform the print and parse conversions.
     * 
     * <p>
     * Calling this api repeatedly will have no effect - the 
     * DatatypeConverterInterface instance passed into the first invocation is 
     * the one that will be used from then on.
     * 
     * @param converter an instance of a class that implements the 
     * DatatypeConverterInterface class - this parameter must not be null.
     * @throws IllegalArgumentException if the parameter is null
     * @throws SecurityException
     *      If the {@link SecurityManager} in charge denies the access to
     *      set the datatype converter. 
     * @see JAXBPermission
     */
    public static void setDatatypeConverter( DatatypeConverterInterface converter ) {
        if( converter == null ) {
            throw new IllegalArgumentException( 
                Messages.format( Messages.CONVERTER_MUST_NOT_BE_NULL ) );
        } else if( theConverter == null ) {
            SecurityManager sm = System.getSecurityManager();
            if (sm != null)
                sm.checkPermission(SET_DATATYPE_CONVERTER_PERMISSION);
            theConverter = converter;
        }
    }

    private static synchronized void initConverter() {
        theConverter = new DatatypeConverterImpl();
    }
    
    /**
     * <p>
     * Convert the lexical XSD string argument into a String value.
     * @param lexicalXSDString
     *     A string containing a lexical representation of
     *     xsd:string.
     * @return
     *     A String value represented by the string argument.
     */ 
    public static String parseString( String lexicalXSDString ) {
        if (theConverter == null) initConverter();
        return theConverter.parseString( lexicalXSDString );
    }

    /**
     * <p>
     * Convert the string argument into a BigInteger value.
     * @param lexicalXSDInteger
     *     A string containing a lexical representation of
     *     xsd:integer.
     * @return
     *     A BigInteger value represented by the string argument.
     * @throws NumberFormatException <code>lexicalXSDInteger</code> is not a valid string representation of a {@link java.math.BigInteger} value.
     */ 
    public static java.math.BigInteger parseInteger( String lexicalXSDInteger ) {
        if (theConverter == null) initConverter();
        return theConverter.parseInteger( lexicalXSDInteger );
    }

    /**
     * <p>
     * Convert the string argument into an int value.
     * @param lexicalXSDInt
     *     A string containing a lexical representation of
     *     xsd:int.
     * @return
     *     A int value represented by the string argument.
     * @throws NumberFormatException <code>lexicalXSDInt</code> is not a valid string representation of an <code>int</code> value.
     */ 
    public static int parseInt( String lexicalXSDInt ) {
        if (theConverter == null) initConverter();
        return theConverter.parseInt( lexicalXSDInt );
    }

    /**
     * <p>
     * Converts the string argument into a long value.
     * @param lexicalXSDLong
     *     A string containing lexical representation of
     *     xsd:long.
     * @return
     *     A long value represented by the string argument.
     * @throws NumberFormatException <code>lexicalXSDLong</code> is not a valid string representation of a <code>long</code> value.
     */ 
    public static long parseLong( String lexicalXSDLong ) {
        if (theConverter == null) initConverter();
        return theConverter.parseLong( lexicalXSDLong );
    }

    /**
     * <p>
     * Converts the string argument into a short value.
     * @param lexicalXSDShort
     *     A string containing lexical representation of
     *     xsd:short.
     * @return
     *     A short value represented by the string argument.
     * @throws NumberFormatException <code>lexicalXSDShort</code> is not a valid string representation of a <code>short</code> value.
     */ 
    public static short parseShort( String lexicalXSDShort ) { 
        if (theConverter == null) initConverter();
        return theConverter.parseShort( lexicalXSDShort );
    }

    /**
     * <p>
     * Converts the string argument into a BigDecimal value.
     * @param lexicalXSDDecimal
     *     A string containing lexical representation of
     *     xsd:decimal.
     * @return
     *     A BigDecimal value represented by the string argument.
     * @throws NumberFormatException <code>lexicalXSDDecimal</code> is not a valid string representation of {@link java.math.BigDecimal}.
     */ 
    public static java.math.BigDecimal parseDecimal( String lexicalXSDDecimal ) {
        if (theConverter == null) initConverter();
        return theConverter.parseDecimal( lexicalXSDDecimal );
    }

    /**
     * <p>
     * Converts the string argument into a float value.
     * @param lexicalXSDFloat
     *     A string containing lexical representation of
     *     xsd:float.
     * @return
     *     A float value represented by the string argument.
     * @throws NumberFormatException <code>lexicalXSDFloat</code> is not a valid string representation of a <code>float</code> value.
     */ 
    public static float parseFloat( String lexicalXSDFloat ) {
        if (theConverter == null) initConverter();
        return theConverter.parseFloat( lexicalXSDFloat );
    }

    /**
     * <p>
     * Converts the string argument into a double value.
     * @param lexicalXSDDouble
     *     A string containing lexical representation of
     *     xsd:double.
     * @return
     *     A double value represented by the string argument.
     * @throws NumberFormatException <code>lexicalXSDDouble</code> is not a valid string representation of a <code>double</code> value.
     */ 
    public static double parseDouble( String lexicalXSDDouble ) { 
        if (theConverter == null) initConverter();
        return theConverter.parseDouble( lexicalXSDDouble );
    }

    /**
     * <p>
     * Converts the string argument into a boolean value.
     * @param lexicalXSDBoolean
     *     A string containing lexical representation of
     *     xsd:boolean.
     * @return
     *     A boolean value represented by the string argument.
     * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:boolean.
     */ 
    public static boolean parseBoolean( String lexicalXSDBoolean ) {
        if (theConverter == null) initConverter();
        return theConverter.parseBoolean( lexicalXSDBoolean );
    }

    /**
     * <p>
     * Converts the string argument into a byte value.
     * @param lexicalXSDByte
     *     A string containing lexical representation of
     *     xsd:byte.
     * @return
     *     A byte value represented by the string argument.
     * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:byte.
     */ 
    public static byte parseByte( String lexicalXSDByte ) { 
        if (theConverter == null) initConverter();
        return theConverter.parseByte( lexicalXSDByte );
    }

    /**
     * <p>
     * Converts the string argument into a byte value.
     *
     * <p>
     * String parameter {@code lexicalXSDQname} must conform to lexical value space specifed at
     * <a href="http://www.w3.org/TR/xmlschema-2/#QName">XML Schema Part 2:Datatypes specification:QNames</a>
     * 
     * @param lexicalXSDQName
     *     A string containing lexical representation of xsd:QName.
     * @param nsc
     *     A namespace context for interpreting a prefix within a QName.
     * @return
     *     A QName value represented by the string argument.
     * @throws IllegalArgumentException  if string parameter does not conform to XML Schema Part 2 specification or 
     *      if namespace prefix of {@code lexicalXSDQname} is not bound to a URI in NamespaceContext {@code nsc}.
     */ 
    public static javax.xml.namespace.QName parseQName( String lexicalXSDQName,
    				                    NamespaceContext nsc) {
        if (theConverter == null) initConverter();
        return theConverter.parseQName( lexicalXSDQName, nsc );
    }

    /**
     * <p>
     * Converts the string argument into a Calendar value.
     * @param lexicalXSDDateTime
     *     A string containing lexical representation of
     *     xsd:datetime.
     * @return
     *     A Calendar object represented by the string argument.
     * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:dateTime.
     */ 
    public static java.util.Calendar parseDateTime( String lexicalXSDDateTime ) {
        if (theConverter == null) initConverter();
        return theConverter.parseDateTime( lexicalXSDDateTime );
    }

    /**
     * <p>
     * Converts the string argument into an array of bytes.
     * @param lexicalXSDBase64Binary
     *     A string containing lexical representation
     *     of xsd:base64Binary.
     * @return
     *     An array of bytes represented by the string argument.
     * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:base64Binary
     */ 
    public static byte[] parseBase64Binary( String lexicalXSDBase64Binary ) {
        if (theConverter == null) initConverter();
        return theConverter.parseBase64Binary( lexicalXSDBase64Binary );
    }

    /**
     * <p>
     * Converts the string argument into an array of bytes.
     * @param lexicalXSDHexBinary
     *     A string containing lexical representation of
     *     xsd:hexBinary.
     * @return
     *     An array of bytes represented by the string argument.
     * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:hexBinary.
     */ 
   public static byte[] parseHexBinary( String lexicalXSDHexBinary ) {
        if (theConverter == null) initConverter();
        return theConverter.parseHexBinary( lexicalXSDHexBinary );
    }

    /**
     * <p>
     * Converts the string argument into a long value.
     * @param lexicalXSDUnsignedInt
     *     A string containing lexical representation
     *     of xsd:unsignedInt.
     * @return
     *     A long value represented by the string argument.
     * @throws NumberFormatException if string parameter can not be parsed into a {@code long} value.
     */ 
    public static long parseUnsignedInt( String lexicalXSDUnsignedInt ) {
        if (theConverter == null) initConverter();
        return theConverter.parseUnsignedInt( lexicalXSDUnsignedInt );
    }

    /**
     * <p>
     * Converts the string argument into an int value.
     * @param lexicalXSDUnsignedShort
     *     A string containing lexical
     *     representation of xsd:unsignedShort.
     * @return
     *     An int value represented by the string argument.
     * @throws NumberFormatException if string parameter can not be parsed into an {@code int} value.
     */ 
    public static int	parseUnsignedShort( String lexicalXSDUnsignedShort ) {
        if (theConverter == null) initConverter();
        return theConverter.parseUnsignedShort( lexicalXSDUnsignedShort );
    }

    /**
     * <p>
     * Converts the string argument into a Calendar value.
     * @param lexicalXSDTime
     *     A string containing lexical representation of
     *     xsd:time.
     * @return
     *     A Calendar value represented by the string argument.
     * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:Time.
     */ 
    public static java.util.Calendar parseTime( String lexicalXSDTime ) {
        if (theConverter == null) initConverter();
        return theConverter.parseTime( lexicalXSDTime ); 
    }
    /**
     * <p>
     * Converts the string argument into a Calendar value.
     * @param lexicalXSDDate
     *      A string containing lexical representation of
     *     xsd:Date.
     * @return
     *     A Calendar value represented by the string argument.
     * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:Date.
     */ 
    public static java.util.Calendar parseDate( String lexicalXSDDate ) {
        if (theConverter == null) initConverter();
        return theConverter.parseDate( lexicalXSDDate );
    }

    /**
     * <p>
     * Return a string containing the lexical representation of the 
     * simple type.
     * @param lexicalXSDAnySimpleType
     *     A string containing lexical
     *     representation of the simple type.
     * @return
     *     A string containing the lexical representation of the 
     *     simple type.
     */ 
    public static String parseAnySimpleType( String lexicalXSDAnySimpleType ) {
        if (theConverter == null) initConverter();
        return theConverter.parseAnySimpleType( lexicalXSDAnySimpleType );
    }
    /**
     * <p>
     * Converts the string argument into a string.
     * @param val
     *     A string value.
     * @return
     *     A string containing a lexical representation of xsd:string.
     */ 
     // also indicate the print methods produce a lexical
     // representation for given Java datatypes.
	
    public static String printString( String val ) {
        if (theConverter == null) initConverter();
        return theConverter.printString( val );
    }

    /**
     * <p>
     * Converts a BigInteger value into a string.
     * @param val
     *     A BigInteger value
     * @return
     *     A string containing a lexical representation of xsd:integer
     * @throws IllegalArgumentException {@code val} is null.
     */ 
    public static String printInteger( java.math.BigInteger val ) {
        if (theConverter == null) initConverter();
        return theConverter.printInteger( val );
    }

    /**
     * <p>
     * Converts an int value into a string.
     * @param val
     *     An int value
     * @return
     *     A string containing a lexical representation of xsd:int
     */ 
    public static String printInt( int val ) {
        if (theConverter == null) initConverter();
        return theConverter.printInt( val );
    }

    /**
     * <p>
     * Converts A long value into a string.
     * @param val
     *     A long value
     * @return
     *     A string containing a lexical representation of xsd:long
     */ 
    public static String printLong( long val ) {
        if (theConverter == null) initConverter();
        return theConverter.printLong( val );
    }

    /**
     * <p>
     * Converts a short value into a string.
     * @param val
     *     A short value
     * @return
     *     A string containing a lexical representation of xsd:short
     */ 
    public static String printShort( short val ) {
        if (theConverter == null) initConverter();
        return theConverter.printShort( val );
    }

    /**
     * <p>
     * Converts a BigDecimal value into a string.
     * @param val
     *     A BigDecimal value
     * @return
     *     A string containing a lexical representation of xsd:decimal
     * @throws IllegalArgumentException {@code val} is null.
     */ 
    public static String printDecimal( java.math.BigDecimal val ) {
        if (theConverter == null) initConverter();
        return theConverter.printDecimal( val );
    }

    /**
     * <p>
     * Converts a float value into a string.
     * @param val
     *     A float value
     * @return
     *     A string containing a lexical representation of xsd:float
     */ 
    public static String printFloat( float val ) {
        if (theConverter == null) initConverter();
        return theConverter.printFloat( val );
    }

    /**
     * <p>
     * Converts a double value into a string.
     * @param val
     *     A double value
     * @return
     *     A string containing a lexical representation of xsd:double
     */ 
    public static String printDouble( double val ) {
        if (theConverter == null) initConverter();
        return theConverter.printDouble( val );
    }

    /**
     * <p>
     * Converts a boolean value into a string.
     * @param val
     *     A boolean value
     * @return
     *     A string containing a lexical representation of xsd:boolean
     */ 
    public static String printBoolean( boolean val ) {
        if (theConverter == null) initConverter();
        return theConverter.printBoolean( val );
    }

    /**
     * <p>
     * Converts a byte value into a string.
     * @param val
     *     A byte value
     * @return
     *     A string containing a lexical representation of xsd:byte
     */ 
    public static String printByte( byte val ) {
        if (theConverter == null) initConverter();
        return theConverter.printByte( val );
    }

    /**
     * <p>
     * Converts a QName instance into a string.
     * @param val
     *     A QName value
     * @param nsc
     *     A namespace context for interpreting a prefix within a QName.
     * @return
     *     A string containing a lexical representation of QName
     * @throws IllegalArgumentException if {@code val} is null or
     * if {@code nsc} is non-null or {@code nsc.getPrefix(nsprefixFromVal)} is null.
     */ 
    public static String printQName( javax.xml.namespace.QName val,
                                     NamespaceContext nsc ) {
        if (theConverter == null) initConverter();
        return theConverter.printQName( val, nsc );
    }

    /**
     * <p>
     * Converts a Calendar value into a string.
     * @param val
     *     A Calendar value
     * @return
     *     A string containing a lexical representation of xsd:dateTime
     * @throws IllegalArgumentException if {@code val} is null.
     */ 
    public static String printDateTime( java.util.Calendar val ) {
        if (theConverter == null) initConverter();
        return theConverter.printDateTime( val );
    }

    /**
     * <p>
     * Converts an array of bytes into a string.
     * @param val
     *     An array of bytes
     * @return
     *     A string containing a lexical representation of xsd:base64Binary
     * @throws IllegalArgumentException if {@code val} is null.
     */ 
    public static String printBase64Binary( byte[] val ) {
        if (theConverter == null) initConverter();
        return theConverter.printBase64Binary( val );
    }

    /**
     * <p>
     * Converts an array of bytes into a string.
     * @param val
     *     An array of bytes
     * @return
     *     A string containing a lexical representation of xsd:hexBinary
     * @throws IllegalArgumentException if {@code val} is null.
     */ 
    public static String printHexBinary( byte[] val ) {
        if (theConverter == null) initConverter();
        return theConverter.printHexBinary( val );
    }

    /**
     * <p>
     * Converts a long value into a string.
     * @param val
     *     A long value
     * @return
     *     A string containing a lexical representation of xsd:unsignedInt
     */ 
    public static String printUnsignedInt( long val ) {
        if (theConverter == null) initConverter();
        return theConverter.printUnsignedInt( val );
    }

    /**
     * <p>
     * Converts an int value into a string.
     * @param val
     *     An int value
     * @return
     *     A string containing a lexical representation of xsd:unsignedShort
     */ 
    public static String printUnsignedShort( int val ) {
        if (theConverter == null) initConverter();
        return theConverter.printUnsignedShort( val );
    }

    /**
     * <p>
     * Converts a Calendar value into a string.
     * @param val
     *     A Calendar value
     * @return
     *     A string containing a lexical representation of xsd:time
     * @throws IllegalArgumentException if {@code val} is null.
     */ 
    public static String printTime( java.util.Calendar val ) {
        if (theConverter == null) initConverter();
        return theConverter.printTime( val );
    }

    /**
     * <p>
     * Converts a Calendar value into a string.
     * @param val
     *     A Calendar value
     * @return
     *     A string containing a lexical representation of xsd:date
     * @throws IllegalArgumentException if {@code val} is null.
     */ 
    public static String printDate( java.util.Calendar val ) {
        if (theConverter == null) initConverter();
        return theConverter.printDate( val );
    }

    /**
     * <p>
     * Converts a string value into a string.
     * @param val
     *     A string value
     * @return
     *     A string containing a lexical representation of xsd:AnySimpleType
     */ 
    public static String printAnySimpleType( String val ) {
        if (theConverter == null) initConverter();
        return theConverter.printAnySimpleType( val );
    }
}
