From 2a9390d683e26b066c42ae1f91e9fbf4034284e1 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Wed, 27 Mar 2019 23:04:40 +0000 Subject: [PATCH] [bug-63291] support concurrent date formatting with same DataFormatter git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1856449 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/ss/usermodel/DataFormatter.java | 23 ++++++++------ .../poi/ss/usermodel/TestDataFormatter.java | 30 +++++++++---------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java index 9c5cb465a5..d80f2bc476 100644 --- a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java +++ b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java @@ -309,7 +309,7 @@ public class DataFormatter implements Observer { return getFormat(cell.getNumericCellValue(), formatIndex, formatStr); } - private Format getFormat(double cellValue, int formatIndex, String formatStrIn) { + private synchronized Format getFormat(double cellValue, int formatIndex, String formatStrIn) { localeChangedObservable.checkForLocaleChange(); // Might be better to separate out the n p and z formats, falling back to p when n and z are not set. @@ -794,7 +794,10 @@ public class DataFormatter implements Observer { * supplied Date and format */ private String performDateFormatting(Date d, Format dateFormat) { - return (dateFormat != null ? dateFormat : defaultDateformat).format(d); + Format df = dateFormat != null ? dateFormat : defaultDateformat; + synchronized (df) { + return df.format(d); + } } /** @@ -815,14 +818,16 @@ public class DataFormatter implements Observer { return null; } Format dateFormat = getFormat(cell, cfEvaluator); - if(dateFormat instanceof ExcelStyleDateFormatter) { - // Hint about the raw excel value - ((ExcelStyleDateFormatter)dateFormat).setDateToBeFormatted( - cell.getNumericCellValue() - ); + synchronized (dateFormat) { + if(dateFormat instanceof ExcelStyleDateFormatter) { + // Hint about the raw excel value + ((ExcelStyleDateFormatter)dateFormat).setDateToBeFormatted( + cell.getNumericCellValue() + ); + } + Date d = cell.getDateCellValue(); + return performDateFormatting(d, dateFormat); } - Date d = cell.getDateCellValue(); - return performDateFormatting(d, dateFormat); } /** diff --git a/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java b/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java index 8195a92c09..96cdf9ae0d 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java +++ b/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java @@ -939,31 +939,28 @@ public class TestDataFormatter { @Test public void testConcurrentCellFormat() throws Exception { - int formatIndex = 105; - String formatString = "[$-F400]m/d/yy h:mm:ss\\ AM/PM;[$-F400]m/d/yy h:mm:ss\\ AM/PM;_-* \"\"??_-;_-@_-"; - DataFormatter formatter = new DataFormatter(); - doFormatTestSequential(formatter, 43551.50990171296, "3/27/19 12:14:15 PM", formatIndex, formatString); - doFormatTestSequential(formatter, 36104.424780092595, "11/5/98 10:11:41 AM", formatIndex, formatString); - - doFormatTestConcurrent(formatter, 43551.50990171296, "3/27/19 12:14:15 PM", formatIndex, formatString); - doFormatTestConcurrent(formatter, 36104.424780092595, "11/5/98 10:11:41 AM", formatIndex, formatString); + doFormatTestSequential(formatter); + doFormatTestConcurrent(formatter); } - private void doFormatTestSequential(DataFormatter formatter, double n, String expected, int formatIndex, - String formatString) { + private void doFormatTestSequential(DataFormatter formatter) { for (int i = 0; i < 1_000; i++) { - assertTrue(doFormatTest(formatter, n, expected, formatIndex, formatString, i)); + assertTrue(doFormatTest(formatter, 43551.50990171296, "3/27/19 12:14:15 PM", i)); + assertTrue(doFormatTest(formatter, 36104.424780092595, "11/5/98 10:11:41 AM", i)); } } - private void doFormatTestConcurrent(DataFormatter formatter, double n, String expected, int formatIndex, - String formatString) throws Exception { + private void doFormatTestConcurrent(DataFormatter formatter) throws Exception { ArrayList> futures = new ArrayList<>(); for (int i = 0; i < 1_000; i++) { final int iteration = i; CompletableFuture future = CompletableFuture.supplyAsync( - () -> { return doFormatTest(formatter, n, expected, formatIndex, formatString, iteration); }); + () -> { + boolean r1 = doFormatTest(formatter, 43551.50990171296, "3/27/19 12:14:15 PM", iteration); + boolean r2 = doFormatTest(formatter, 36104.424780092595, "11/5/98 10:11:41 AM", iteration); + return r1 && r2; + }); futures.add(future); } for (CompletableFuture future : futures) { @@ -971,8 +968,9 @@ public class TestDataFormatter { } } - private static boolean doFormatTest(DataFormatter formatter, double n, String expected, int formatIndex, - String formatString, int iteration) { + private static boolean doFormatTest(DataFormatter formatter, double n, String expected, int iteration) { + int formatIndex = 105; + String formatString = "[$-F400]m/d/yy h:mm:ss\\ AM/PM;[$-F400]m/d/yy h:mm:ss\\ AM/PM;_-* \"\"??_-;_-@_-"; String actual = formatter.formatRawCellContents(n, formatIndex, formatString); assertEquals("Failed on iteration " + iteration, expected, actual); return true; -- 2.39.5