/*
 * $Header: /cvshome/build/info.dmtree/src/info/dmtree/DmtData.java,v 1.8 2006/07/10 21:37:07 hargrave Exp $
 *
 * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package info.dmtree;

import java.util.Arrays;
import java.util.Hashtable;

// Possible enhancements to this class:
// * new constructors and get/set methods for b64, to access the encoded value
// * new constructors and get/set methods for date/time, for more convenient 
//   Java access
/**
 * An immutable data structure representing the contents of a leaf or interior
 * node. This structure represents only the value and the format property of the
 * node, all other properties (like MIME type) can be set and read using the
 * <code>DmtSession</code> interface.
 * <p>
 * Different constructors are available to create nodes with different formats.
 * Nodes of <code>null</code> format can be created using the static
 * {@link #NULL_VALUE} constant instance of this class.
 * <p>
 * {@link #FORMAT_RAW_BINARY} and {@link #FORMAT_RAW_STRING} enable the support
 * of future data formats. When using these formats, the actual format name is
 * specified as a <code>String</code>. The application is responsible for the
 * proper encoding of the data according to the specified format.
 */
public final class DmtData {

    /**
     * The node holds an OMA DM <code>int</code> value.
     */
    public static final int FORMAT_INTEGER = 0x0001;

    /**
     * The node holds an OMA DM <code>float</code> value.
     */
    public static final int FORMAT_FLOAT = 0x0002;

    /**
     * The node holds an OMA DM <code>chr</code> value.
     */
    public static final int FORMAT_STRING = 0x0004;

    /**
     * The node holds an OMA DM <code>bool</code> value.
     */
    public static final int FORMAT_BOOLEAN = 0x0008;

    /**
     * The node holds an OMA DM <code>date</code> value.
     */
    public static final int FORMAT_DATE = 0x0010;

    /**
     * The node holds an OMA DM <code>time</code> value.
     */
    public static final int FORMAT_TIME = 0x0020;

    /**
     * The node holds an OMA DM <code>bin</code> value. The value of the node
     * corresponds to the Java <code>byte[]</code> type.
     */
    public static final int FORMAT_BINARY = 0x0040;

    /**
     * The node holds an OMA DM <code>b64</code> value. Like
     * {@link #FORMAT_BINARY}, this format is also represented by the Java
     * <code>byte[]</code> type, the difference is only in the corresponding
     * OMA DM format.
     */
    public static final int FORMAT_BASE64 = 0x0080;

    /**
     * The node holds an OMA DM <code>xml</code> value.
     */
    public static final int FORMAT_XML = 0x0100;

    /**
     * The node holds an OMA DM <code>null</code> value. This corresponds to
     * the Java <code>null</code> type.
     */
    public static final int FORMAT_NULL = 0x0200;

    /**
     * Format specifier of an internal node. An interior node can hold a Java
     * object as value (see {@link DmtData#DmtData(Object)} and
     * {@link DmtData#getNode()}). This value can be used by Java programs that
     * know a specific URI understands the associated Java type. This type is
     * further used as a return value of the {@link MetaNode#getFormat} method
     * for interior nodes.
     */
    public static final int FORMAT_NODE = 0x0400;
    
    /**
     * The node holds raw protocol data encoded as <code>String</code>. The
     * {@link #getFormatName()} method can be used to get the actual format
     * name.
     */
    public static final int FORMAT_RAW_STRING = 0x0800;

    /**
     * The node holds raw protocol data encoded in binary format. The
     * {@link #getFormatName()} method can be used to get the actual format
     * name.
     */
    public static final int FORMAT_RAW_BINARY = 0x1000;

    
    private static final Hashtable FORMAT_NAMES = new Hashtable();
    
    static {
        FORMAT_NAMES.put(new Integer(FORMAT_BASE64),    "b64");
        FORMAT_NAMES.put(new Integer(FORMAT_BINARY),    "bin");
        FORMAT_NAMES.put(new Integer(FORMAT_BOOLEAN),   "bool");
        FORMAT_NAMES.put(new Integer(FORMAT_DATE),      "date");
        FORMAT_NAMES.put(new Integer(FORMAT_FLOAT),     "float");
        FORMAT_NAMES.put(new Integer(FORMAT_INTEGER),   "int");
        FORMAT_NAMES.put(new Integer(FORMAT_NODE),      "node");
        FORMAT_NAMES.put(new Integer(FORMAT_NULL),      "null");
        FORMAT_NAMES.put(new Integer(FORMAT_STRING),    "chr");
        FORMAT_NAMES.put(new Integer(FORMAT_TIME),      "time");
        FORMAT_NAMES.put(new Integer(FORMAT_XML),       "xml");
    }

    /**
     * Constant instance representing a leaf node of <code>null</code> format.
     */
    public static final DmtData NULL_VALUE = new DmtData();
        // FORMAT_NAMES must be initialized by the time the constr. is called 
    
    private final String str;

    private final int integer;

    private final float flt;

    private final boolean bool;

    private final byte[] bytes;

    private final int format;
    
    private final String formatName;

    private final Object complex;

    /**
     * Create a <code>DmtData</code> instance of <code>null</code> format.
     * This constructor is private and used only to create the public
     * {@link #NULL_VALUE} constant.
     */
    private DmtData() {
        format = FORMAT_NULL;
        formatName = getFormatName(format);

        this.str = null;
        this.integer = 0;
        this.flt = 0;
        this.bool = false;
        this.bytes = null;
        this.complex = null;
    }

    /**
     * Create a <code>DmtData</code> instance of <code>chr</code> format
     * with the given string value. The <code>null</code> string argument is
     * valid.
     * 
     * @param str the string value to set
     */
    public DmtData(String str) {
        format = FORMAT_STRING;
        formatName = getFormatName(format);
        this.str = str;

        this.integer = 0;
        this.flt = 0;
        this.bool = false;
        this.bytes = null;
        this.complex = null;
    }

    /**
     * Create a <code>DmtData</code> instance of <code>node</code> format
     * with the given object value. The value represents complex data associated
     * with an interior node.
     * <p>
     * Certain interior nodes can support access to their subtrees through such
     * complex values, making it simpler to retrieve or update all leaf nodes in
     * a subtree.
     * <p>
     * The given value must be a non-<code>null</code> immutable object.
     * 
     * @param complex the complex data object to set
     */
    public DmtData(Object complex) {
        if(complex == null)
            throw new NullPointerException("Complex data argument is null.");

        format = FORMAT_NODE;
        formatName = getFormatName(format);
        this.complex = complex;

        this.str     = null;
        this.integer = 0;
        this.flt     = 0;
        this.bool    = false;
        this.bytes   = null;
    }

    /**
     * Create a <code>DmtData</code> instance of the specified format and set
     * its value based on the given string. Only the following string-based
     * formats can be created using this constructor:
     * <ul>
     * <li>{@link #FORMAT_STRING} - value can be any string
     * <li>{@link #FORMAT_XML} - value must contain an XML fragment (the
     *     validity is not checked by this constructor)
     * <li>{@link #FORMAT_DATE} - value must be parseable to an ISO 8601
     *     calendar date in complete representation, basic format (pattern
     * <tt>CCYYMMDD</tt>)
     * <li>{@link #FORMAT_TIME} - value must be parseable to an ISO 8601 time
     *     of day in either local time, complete representation, basic format
     *     (pattern <tt>hhmmss</tt>) or Coordinated Universal Time, basic format
     *     (pattern <tt>hhmmssZ</tt>)
     * </ul>
     * The <code>null</code> string argument is only valid if the format is
     * string or XML.
     * 
     * @param value the string, XML, date or time value to set
     * @param format the format of the <code>DmtData</code> instance to be
     *        created, must be one of the formats specified above
     * @throws IllegalArgumentException if <code>format</code> is not one of
     *         the allowed formats, or <code>value</code> is not a valid
     *         string for the given format
     * @throws NullPointerException if a date or time is constructed and
     *         <code>value</code> is <code>null</code>
     */
    public DmtData(String value, int format) {
        switch (format) {
        case FORMAT_DATE:
            checkDateFormat(value);
            break;
        case FORMAT_TIME:
            checkTimeFormat(value);
            break;
        case FORMAT_STRING:
        case FORMAT_XML:
            break; // nothing to do, all string values are accepted
        default:
            throw new IllegalArgumentException(
                    "Invalid format in string constructor: " + format);
        }
        this.format = format;
        this.formatName = getFormatName(format);
        this.str = value;

        this.integer = 0;
        this.flt = 0;
        this.bool = false;
        this.bytes = null;
        this.complex = null;
    }

    /**
     * Create a <code>DmtData</code> instance of <code>int</code> format and
     * set its value.
     * 
     * @param integer the integer value to set
     */
    public DmtData(int integer) {
        format = FORMAT_INTEGER;
        formatName = getFormatName(format);
        this.integer = integer;

        this.str = null;
        this.flt = 0;
        this.bool = false;
        this.bytes = null;
        this.complex = null;
    }

    /**
     * Create a <code>DmtData</code> instance of <code>float</code> format
     * and set its value.
     * 
     * @param flt the float value to set
     */
    public DmtData(float flt) {
        format = FORMAT_FLOAT;
        formatName = getFormatName(format);
        this.flt = flt;

        this.str = null;
        this.integer = 0;
        this.bool = false;
        this.bytes = null;
        this.complex = null;
    }

    /**
     * Create a <code>DmtData</code> instance of <code>bool</code> format
     * and set its value.
     * 
     * @param bool the boolean value to set
     */
    public DmtData(boolean bool) {
        format = FORMAT_BOOLEAN;
        formatName = getFormatName(format);
        this.bool = bool;

        this.str = null;
        this.integer = 0;
        this.flt = 0;
        this.bytes = null;
        this.complex = null;
    }

    /**
     * Create a <code>DmtData</code> instance of <code>bin</code> format and
     * set its value.
     * 
     * @param bytes the byte array to set, must not be <code>null</code>
     * @throws NullPointerException if <code>bytes</code> is <code>null</code>
     */
    public DmtData(byte[] bytes) {
        if (bytes == null)
            throw new NullPointerException("Binary data argument is null.");

        format = FORMAT_BINARY;
        formatName = getFormatName(format);
        this.bytes = bytes;

        this.str = null;
        this.integer = 0;
        this.flt = 0;
        this.bool = false;
        this.complex = null;
    }

    /**
     * Create a <code>DmtData</code> instance of <code>bin</code> or
     * <code>b64</code> format and set its value. The chosen format is
     * specified by the <code>base64</code> parameter.
     * 
     * @param bytes the byte array to set, must not be <code>null</code>
     * @param base64 if <code>true</code>, the new instance will have
     *        <code>b64</code> format, if <code>false</code>, it will have
     *        <code>bin</code> format
     * @throws NullPointerException if <code>bytes</code> is <code>null</code>
     */
    public DmtData(byte[] bytes, boolean base64) {
        if (bytes == null)
            throw new NullPointerException("Binary data argument is null.");

        format = base64 ? FORMAT_BASE64 : FORMAT_BINARY;
        formatName = getFormatName(format);
        this.bytes = bytes;

        this.str = null;
        this.integer = 0;
        this.flt = 0;
        this.bool = false;
        this.complex = null;
    }

    /**
     * Create a <code>DmtData</code> instance in {@link #FORMAT_RAW_STRING}
     * format. The data is provided encoded as a <code>String</code>. The
     * actual data format is specified in <code>formatName</code>. The
     * encoding used in <code>data</code> must conform to this format.
     * 
     * @param formatName the name of the format, must not be <code>null</code>
     * @param data the data encoded according to the specified format, must not
     *        be <code>null</code>
     * @throws NullPointerException if <code>formatName</code> or
     *         <code>data</code> is <code>null</code>
     */
    public DmtData(String formatName, String data) {
        if(formatName == null)
            throw new NullPointerException("Format name argument is null.");
        if(data == null)
            throw new NullPointerException("Data argument is null.");
        
        format = FORMAT_RAW_STRING;
        this.formatName = formatName;
        this.str = data;

        this.bytes = null;
        this.integer = 0;
        this.flt = 0;
        this.bool = false;
        this.complex = null;
    }
    
    /**
     * Create a <code>DmtData</code> instance in {@link #FORMAT_RAW_BINARY}
     * format. The data is provided encoded as binary. The actual data format is
     * specified in <code>formatName</code>. The encoding used in
     * <code>data</code> must conform to this format.
     * 
     * @param formatName the name of the format, must not be <code>null</code>
     * @param data the data encoded according to the specified format, must not
     *        be <code>null</code>
     * @throws NullPointerException if <code>formatName</code> or
     *         <code>data</code> is <code>null</code>
     */
    public DmtData(String formatName, byte[] data) {
        if(formatName == null)
            throw new NullPointerException("Format name argument is null.");
        if(data == null)
            throw new NullPointerException("Data argument is null.");

        format = FORMAT_RAW_BINARY;
        this.formatName = formatName;
        this.bytes = (byte[]) data.clone();

        this.str = null;
        this.integer = 0;
        this.flt = 0;
        this.bool = false;
        this.complex = null;
    }
    
    /**
     * Gets the value of a node with string (<code>chr</code>) format.
     * 
     * @return the string value
     * @throws DmtIllegalStateException if the format of the node is not string
     */
    public String getString() {
        if (format == FORMAT_STRING)
            return str;

        throw new DmtIllegalStateException("DmtData value is not string.");
    }

    /**
     * Gets the value of a node with date format. The returned date string is
     * formatted according to the ISO 8601 definition of a calendar date in
     * complete representation, basic format (pattern <tt>CCYYMMDD</tt>).
     * 
     * @return the date value
     * @throws DmtIllegalStateException if the format of the node is not date
     */
    public String getDate() {
        if (format == FORMAT_DATE)
            return str;

        throw new DmtIllegalStateException("DmtData value is not date.");
    }

    /**
     * Gets the value of a node with time format. The returned time string is
     * formatted according to the ISO 8601 definition of the time of day. The
     * exact format depends on the value the object was initialized with: either
     * local time, complete representation, basic format (pattern
     * <tt>hhmmss</tt>) or Coordinated Universal Time, basic format (pattern
     * <tt>hhmmssZ</tt>).
     * 
     * @return the time value
     * @throws DmtIllegalStateException if the format of the node is not time
     */
    public String getTime() {
        if (format == FORMAT_TIME)
            return str;

        throw new DmtIllegalStateException("DmtData value is not time.");
    }

    /**
     * Gets the value of a node with <code>xml</code> format.
     * 
     * @return the XML value
     * @throws DmtIllegalStateException if the format of the node is not
     *         <code>xml</code>
     */
    public String getXml() {
        if (format == FORMAT_XML)
            return str;

        throw new DmtIllegalStateException("DmtData value is not XML.");
    }

    /**
     * Gets the value of a node with integer (<code>int</code>) format.
     * 
     * @return the integer value
     * @throws DmtIllegalStateException if the format of the node is not integer
     */
    public int getInt() {
        if (format == FORMAT_INTEGER)
            return integer;

        throw new DmtIllegalStateException("DmtData value is not integer.");
    }

    /**
     * Gets the value of a node with <code>float</code> format.
     * 
     * @return the float value
     * @throws DmtIllegalStateException if the format of the node is not
     *         <code>float</code>
     */
    public float getFloat() {
        if (format == FORMAT_FLOAT)
            return flt;

        throw new DmtIllegalStateException("DmtData value is not float.");
    }

    /**
     * Gets the value of a node with boolean (<code>bool</code>) format.
     * 
     * @return the boolean value
     * @throws DmtIllegalStateException if the format of the node is not boolean
     */
    public boolean getBoolean() {
        if (format == FORMAT_BOOLEAN)
            return bool;

        throw new DmtIllegalStateException("DmtData value is not boolean.");
    }

    /**
     * Gets the value of a node with binary (<code>bin</code>) format.
     * 
     * @return the binary value
     * @throws DmtIllegalStateException if the format of the node is not binary
     */
    public byte[] getBinary() {
        if (format == FORMAT_BINARY) {
            byte[] bytesCopy = new byte[bytes.length];
            for (int i = 0; i < bytes.length; i++)
                bytesCopy[i] = bytes[i];

            return bytesCopy;
        }

        throw new DmtIllegalStateException("DmtData value is not a byte array.");
    }
    
    /**
     * Gets the value of a node in raw binary ({@link #FORMAT_RAW_BINARY})
     * format.
     * 
     * @return the data value in raw binary format
     * @throws DmtIllegalStateException if the format of the node is not raw binary
     */
    public byte[] getRawBinary() {
        if (format == FORMAT_RAW_BINARY)
            return (byte[]) bytes.clone();
        
        throw new DmtIllegalStateException(
                "DmtData value is not in raw binary format.");
    }

    /**
     * Gets the value of a node in raw <code>String</code>
     * ({@link #FORMAT_RAW_STRING}) format.
     * 
     * @return the data value in raw <code>String</code> format
     * @throws DmtIllegalStateException if the format of the node is not raw
     *     <code>String</code>
    */
    public String getRawString() {
        if (format == FORMAT_RAW_STRING)
            return str;
        
        throw new DmtIllegalStateException(
                "DmtData value is not in raw string format.");
    }

    /**
     * Gets the value of a node with base 64 (<code>b64</code>) format.
     * 
     * @return the binary value
     * @throws DmtIllegalStateException if the format of the node is not base 64.
     */
    public byte[] getBase64() {
        if (format == FORMAT_BASE64) {
            byte[] bytesCopy = new byte[bytes.length];
            for (int i = 0; i < bytes.length; i++)
                bytesCopy[i] = bytes[i];

            return bytesCopy;
        }

        throw new DmtIllegalStateException(
                "DmtData value is not in base 64 format.");
    }

    /**
     * Gets the complex data associated with an interior node (<code>node</code>
     * format).
     * <p>
     * Certain interior nodes can support access to their subtrees through
     * complex values, making it simpler to retrieve or update all leaf nodes in
     * the subtree.
     * 
     * @return the data object associated with an interior node
     * @throws DmtIllegalStateException if the format of the data is not 
     *         <code>node</code>
     */
    public Object getNode() {
        if(format == FORMAT_NODE)
            return complex;

        throw new DmtIllegalStateException(
                "DmtData does not contain interior node data.");
    }

    /**
     * Get the node's format, expressed in terms of type constants defined in
     * this class. Note that the 'format' term is a legacy from OMA DM, it is
     * more customary to think of this as 'type'.
     * 
     * @return the format of the node
     */
    public int getFormat() {
        return format;
    }

    /**
     * Returns the format of this <code>DmtData</code> as <code>String</code>.
     * For the predefined data formats this is the OMA DM defined name of the
     * format. For {@link #FORMAT_RAW_STRING} and {@link #FORMAT_RAW_BINARY}
     * this is the format specified when the object was created.
     * 
     * @return the format name as <code>String</code>
     */
    public String getFormatName() {
        return formatName;
    }

    /**
     * Get the size of the data. The returned value depends on the format of
     * data in the node:
     * <ul>
     * <li>{@link #FORMAT_STRING}, {@link #FORMAT_XML}, {@link #FORMAT_BINARY},
     *     {@link #FORMAT_BASE64}, {@link #FORMAT_RAW_STRING}, and
     *     {@link #FORMAT_RAW_BINARY}: the length of the stored data, or 0 if
     *     the data is <code>null</code>
     * <li>{@link #FORMAT_INTEGER} and {@link #FORMAT_FLOAT}: 4
     * <li>{@link #FORMAT_DATE} and {@link #FORMAT_TIME}: the length of the
     *     date or time in its string representation
     * <li>{@link #FORMAT_BOOLEAN}: 1
     * <li>{@link #FORMAT_NODE}: -1 (unknown)
     * <li>{@link #FORMAT_NULL}: 0
     * </ul>
     * 
     * @return the size of the data stored by this object
     */
    public int getSize() {
        switch (format) {
        case FORMAT_STRING:
        case FORMAT_XML:
        case FORMAT_DATE:
        case FORMAT_TIME:
        case FORMAT_RAW_STRING:
            return str == null ? 0 : str.length();
        case FORMAT_BINARY:
        case FORMAT_BASE64:
        case FORMAT_RAW_BINARY:
            return bytes.length;
        case FORMAT_INTEGER:
        case FORMAT_FLOAT:
            return 4;
        case FORMAT_BOOLEAN:
            return 1;
        case FORMAT_NODE:
            return -1;
        case FORMAT_NULL:
            return 0;
        }

        return 0; // never reached
    }

    /**
     * Gets the string representation of the <code>DmtData</code>. This
     * method works for all formats.
     * <p>
     * For string format data - including {@link #FORMAT_RAW_STRING} - the
     * string value itself is returned, while for XML, date, time, integer,
     * float, boolean and node formats the string form of the value is returned.
     * Binary - including {@link #FORMAT_RAW_BINARY} - and base64 data is
     * represented by two-digit hexadecimal numbers for each byte separated by
     * spaces. The {@link #NULL_VALUE} data has the string form of
     * "<code>null</code>". Data of string or XML format containing the Java
     * <code>null</code> value is represented by an empty string.
     * 
     * @return the string representation of this <code>DmtData</code> instance
     */
    public String toString() {
        switch (format) {
        case FORMAT_STRING:
        case FORMAT_XML:
        case FORMAT_DATE:
        case FORMAT_TIME:
        case FORMAT_RAW_STRING:
            return str == null ? "" : str;
        case FORMAT_INTEGER:
            return String.valueOf(integer);
        case FORMAT_FLOAT:
            return String.valueOf(flt);
        case FORMAT_BOOLEAN:
            return String.valueOf(bool);
        case FORMAT_BINARY:
        case FORMAT_BASE64:
        case FORMAT_RAW_BINARY:
            return getHexDump(bytes);
        case FORMAT_NODE:
            return complex.toString();
        case FORMAT_NULL:
            return "null";
        }

        return null; // never reached
    }

    /**
     * Compares the specified object with this <code>DmtData</code> instance.
     * Two <code>DmtData</code> objects are considered equal if their format
     * is the same, and their data (selected by the format) is equal.
     * <p>
     * In case of {@link #FORMAT_RAW_BINARY} and {@link #FORMAT_RAW_STRING}
     * the textual name of the data format - as returned by
     * {@link #getFormatName()} - must be equal as well.
     * 
     * @param obj the object to compare with this <code>DmtData</code>
     * @return true if the argument represents the same <code>DmtData</code>
     *         as this object
     */
    public boolean equals(Object obj) {
        if (!(obj instanceof DmtData))
            return false;

        DmtData other = (DmtData) obj;

        if (format != other.format)
            return false;

        switch (format) {
        case FORMAT_STRING:
        case FORMAT_XML:
        case FORMAT_DATE:
        case FORMAT_TIME:
            return str == null ? other.str == null : str.equals(other.str);
        case FORMAT_INTEGER:
            return integer == other.integer;
        case FORMAT_FLOAT:
            return flt == other.flt;
        case FORMAT_BOOLEAN:
            return bool == other.bool;
        case FORMAT_BINARY:
        case FORMAT_BASE64:
            return Arrays.equals(bytes, other.bytes);
        case FORMAT_NODE:
            return complex.equals(other.complex);
        case FORMAT_NULL:
            return true;
        case FORMAT_RAW_BINARY:
            return formatName.equals(other.formatName)
                    && Arrays.equals(bytes, other.bytes);
        case FORMAT_RAW_STRING:
            // in this case str cannot be null
            return formatName.equals(other.formatName) && str.equals(other.str);
        }

        return false; // never reached
    }

    /**
     * Returns the hash code value for this <code>DmtData</code> instance. The
     * hash code is calculated based on the data (selected by the format) of
     * this object.
     * 
     * @return the hash code value for this object
     */
    public int hashCode() {
        switch (format) {
        case FORMAT_STRING:
        case FORMAT_XML:
        case FORMAT_DATE:
        case FORMAT_TIME:
        case FORMAT_RAW_STRING:
            return str == null ? 0 : str.hashCode();
        case FORMAT_INTEGER:
            return new Integer(integer).hashCode();
        case FORMAT_FLOAT:
            return new Float(flt).hashCode();
        case FORMAT_BOOLEAN:
            return new Boolean(bool).hashCode();
        case FORMAT_BINARY:
        case FORMAT_BASE64:
        case FORMAT_RAW_BINARY:
            return new String(bytes).hashCode();
        case FORMAT_NODE:
            return complex.hashCode();
        case FORMAT_NULL:
            return 0;
        }

        return 0; // never reached
    }
    
    private static void checkDateFormat(String value) {
        if(value.length() != 8)
            throw new IllegalArgumentException("Date string '" + value +
                    "' does not follow the format 'CCYYMMDD'.");
        
        int year = checkNumber(value, "Date", 0, 4, 0, 9999);
        int month = checkNumber(value, "Date", 4, 2, 1, 12);
        int day = checkNumber(value, "Date", 6, 2, 1, 31);
        
        // Date checking is not prepared for all special rules (for example
        // historical leap years), production code could contain a full check.
        
        // Day 31 is invalid for April, June, September and November
        if((month == 4 || month == 6 || month == 9 || month == 11) && day == 31)
        	throw new IllegalArgumentException("Date string '" + value +
        			"' contains an invalid date.");
        
        // February 29 is invalid except for leap years, Feb. 30-31 are invalid
        if(month == 2 && day > 28 &&
        	!(day == 29 && year%4 == 0 && (year%100 != 0 || year%400 == 0)))
        	throw new IllegalArgumentException("Date string '" + value +
        			"' contains an invalid date.");
    }
    
    private static void checkTimeFormat(String value) {
        if(value.length() > 0 && value.charAt(value.length()-1) == 'Z')
            value = value.substring(0, value.length()-1);
        
        if(value.length() != 6)
            throw new IllegalArgumentException("Time string '" + value +
                    "' does not follow the format 'hhmmss' or 'hhmmssZ'.");
            
        // Time checking is not prepared for all special rules (for example
        // leap seconds), production code could contain a full check.
        
        // if hour is 24, only 240000 should be allowed
        checkNumber(value, "Time", 0, 2, 0, 24);
        checkNumber(value, "Time", 2, 2, 0, 59);
        checkNumber(value, "Time", 4, 2, 0, 59);
        
        if(value.startsWith("24") && !value.startsWith("240000"))
        	throw new IllegalArgumentException("Time string is out of range.");
    }
    
    private static int checkNumber(String value, String name, int from,
            int length, int min, int max) {
        String part = value.substring(from, from+length);
        int number;
        try {
            number = Integer.parseInt(part);
        } catch(NumberFormatException e) {
            throw new IllegalArgumentException(name + " string '" + value +
                    "' contains a non-numeric part.");
        }
        if(number < min || number > max)
            throw new IllegalArgumentException("A segment of the " + name +
                    " string '" + value + "' is out of range.");
        
        return number;
    }

    // character array of hexadecimal digits, used for printing binary data
    private static char[] hex = "0123456789ABCDEF".toCharArray();

    // generates a hexadecimal dump of the given binary data
    private static String getHexDump(byte[] bytes) {
        if (bytes.length == 0)
            return "";

        StringBuffer buf = new StringBuffer();
        appendHexByte(buf, bytes[0]);
        for (int i = 1; i < bytes.length; i++)
            appendHexByte(buf.append(' '), bytes[i]);

        return buf.toString();
    }

    private static void appendHexByte(StringBuffer buf, byte b) {
        buf.append(hex[(b & 0xF0) >> 4]).append(hex[b & 0x0F]);
    }
    
    private static String getFormatName(int format) {
        return (String) FORMAT_NAMES.get(new Integer(format));
    }
}
