poi-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bugzi...@apache.org
Subject DO NOT REPLY [Bug 22456] New: - Synchronization problem in HSSFDataFormat
Date Fri, 15 Aug 2003 13:18:23 GMT
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=22456>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=22456

Synchronization problem in HSSFDataFormat

           Summary: Synchronization problem in HSSFDataFormat
           Product: POI
           Version: 1.5.1
          Platform: PC
        OS/Version: Windows NT/2K
            Status: NEW
          Severity: Normal
          Priority: Other
         Component: HSSF
        AssignedTo: poi-dev@jakarta.apache.org
        ReportedBy: andreas.zielke@gmx.net


Hi *,

there's a synchronization problem in HSSFDataFormat.
The populating of the formats array list is static synchronized,
but not all accesses are synchronized.
Two concurrent threads may enter one of the methods; the first will be
stopped immedeately after entering the method. The second one will enter
a method and see the formats as null. It now enters the static populate 
method and will create a List and start to add formats to it. The scheduler
will then interrupt the thread. Now the bug happens: The first thread will
see the (not-fully) initialized List (which is not null!) and try to access
it. This'll lead to an IndexOutOfBoundsException.
I ran into this situation while unit-testing one of my classes.

The solution is simple. Do the populating of the formats list as static
initialization. This way the vm guarantees, that the list will be populated
before any methods of the class are called.

Below is the fixed (but untested) version of the class...

Regards and keep up the good work; I really enjoy using POI!!!

Andreas



package org.apache.poi.hssf.usermodel;

import java.util.ArrayList;
import java.util.List;

/**
 * Utility to identify builin formats.  The following is a list of the formats as
 * returned by this class.<P>
 *<P>
 *       0, "General"<P>
 *       1, "0"<P>
 *       2, "0.00"<P>
 *       3, "#,##0"<P>
 *       4, "#,##0.00"<P>
 *       5, "($#,##0_);($#,##0)"<P>
 *       6, "($#,##0_);[Red]($#,##0)"<P>
 *       7, "($#,##0.00);($#,##0.00)"<P>
 *       8, "($#,##0.00_);[Red]($#,##0.00)"<P>
 *       9, "0%"<P>
 *       0xa, "0.00%"<P>
 *       0xb, "0.00E+00"<P>
 *       0xc, "# ?/?"<P>
 *       0xd, "# ??/??"<P>
 *       0xe, "m/d/yy"<P>
 *       0xf, "d-mmm-yy"<P>
 *       0x10, "d-mmm"<P>
 *       0x11, "mmm-yy"<P>
 *       0x12, "h:mm AM/PM"<P>
 *       0x13, "h:mm:ss AM/PM"<P>
 *       0x14, "h:mm"<P>
 *       0x15, "h:mm:ss"<P>
 *       0x16, "m/d/yy h:mm"<P>
 *<P>
 *       // 0x17 - 0x24 reserved for international and undocumented
 *       0x25, "(#,##0_);(#,##0)"<P>
 *       0x26, "(#,##0_);[Red](#,##0)"<P>
 *       0x27, "(#,##0.00_);(#,##0.00)"<P>
 *       0x28, "(#,##0.00_);[Red](#,##0.00)"<P>
 *       0x29, "_(*#,##0_);_(*(#,##0);_(* \"-\"_);_(@_)"<P>
 *       0x2a, "_($*#,##0_);_($*(#,##0);_($* \"-\"_);_(@_)"<P>
 *       0x2b, "_(*#,##0.00_);_(*(#,##0.00);_(*\"-\"??_);_(@_)"<P>
 *       0x2c, "_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)"<P>
 *       0x2d, "mm:ss"<P>
 *       0x2e, "[h]:mm:ss"<P>
 *       0x2f, "mm:ss.0"<P>
 *       0x30, "##0.0E+0"<P>
 *       0x31, "@"<P>
 *
 *
 * @author  Andrew C. Oliver (acoliver at apache dot org)
 */

public class HSSFDataFormat
{
    private static ArrayList formats;

    static {
        formats = new ArrayList();
        formats.add(0, "General");
        formats.add(1, "0");
        formats.add(2, "0.00");
        formats.add(3, "#,##0");
        formats.add(4, "#,##0.00");
        formats.add(5, "($#,##0_);($#,##0)");
        formats.add(6, "($#,##0_);[Red]($#,##0)");
        formats.add(7, "($#,##0.00);($#,##0.00)");
        formats.add(8, "($#,##0.00_);[Red]($#,##0.00)");
        formats.add(9, "0%");
        formats.add(0xa, "0.00%");
        formats.add(0xb, "0.00E+00");
        formats.add(0xc, "# ?/?");
        formats.add(0xd, "# ??/??");
        formats.add(0xe, "m/d/yy");
        formats.add(0xf, "d-mmm-yy");
        formats.add(0x10, "d-mmm");
        formats.add(0x11, "mmm-yy");
        formats.add(0x12, "h:mm AM/PM");
        formats.add(0x13, "h:mm:ss AM/PM");
        formats.add(0x14, "h:mm");
        formats.add(0x15, "h:mm:ss");
        formats.add(0x16, "m/d/yy h:mm");

        // 0x17 - 0x24 reserved for international and undocumented
        formats.add(0x17, "0x17");
        formats.add(0x18, "0x18");
        formats.add(0x19, "0x19");
        formats.add(0x1a, "0x1a");
        formats.add(0x1b, "0x1b");
        formats.add(0x1c, "0x1c");
        formats.add(0x1d, "0x1d");
        formats.add(0x1e, "0x1e");
        formats.add(0x1f, "0x1f");
        formats.add(0x20, "0x20");
        formats.add(0x21, "0x21");
        formats.add(0x22, "0x22");
        formats.add(0x23, "0x23");
        formats.add(0x24, "0x24");

        // 0x17 - 0x24 reserved for international and undocumented
        formats.add(0x25, "(#,##0_);(#,##0)");
        formats.add(0x26, "(#,##0_);[Red](#,##0)");
        formats.add(0x27, "(#,##0.00_);(#,##0.00)");
        formats.add(0x28, "(#,##0.00_);[Red](#,##0.00)");
        formats.add(0x29, "_(*#,##0_);_(*(#,##0);_(* \"-\"_);_(@_)");
        formats.add(0x2a, "_($*#,##0_);_($*(#,##0);_($* \"-\"_);_(@_)");
        formats.add(0x2b, "_(*#,##0.00_);_(*(#,##0.00);_(*\"-\"??_);_(@_)");
        formats.add(0x2c,
                    "_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)");
        formats.add(0x2d, "mm:ss");
        formats.add(0x2e, "[h]:mm:ss");
        formats.add(0x2f, "mm:ss.0");
        formats.add(0x30, "##0.0E+0");
        formats.add(0x31, "@");
    }

    public static List getFormats()
    {
        return formats;
    }

    /**
     * get the format index that matches the given format string
     * @param format string matching a built in format
     * @return index of format or -1 if undefined.
     */

    public static short getFormat(String format)
    {
        short retval = -1;

        for (short k = 0; k < 0x31; k++)
        {
            String nformat = ( String ) formats.get(k);

            if ((nformat != null) && nformat.equals(format))
            {
                retval = k;
                break;
            }
        }
        return retval;
    }

    /**
     * get the format string that matches the given format index
     * @param index of a built in format
     * @return string represented at index of format or null if there is not a builtin format
at that index
     */

    public static String getFormat(short index)
    {
        return ( String ) formats.get(index);
    }

    /**
     * get the number of builtin and reserved formats
     * @return number of builtin and reserved formats
     */

    public static int getNumberOfBuiltinFormats()
    {
        return formats.size();
    }
}

---------------------------------------------------------------------
To unsubscribe, e-mail: poi-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: poi-dev-help@jakarta.apache.org


Mime
View raw message