From aaafb0270d19c1befa53df9e39818c26ad205bf8 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Mon, 7 Sep 2015 20:19:50 +0000 Subject: [PATCH] Bug 58326 - Forbidden APIs patches - first set of changes for locale and timezone settings also includes fixes for - name shadowing - unused deprecated method "getClipRect" in classes extending Graphics2d - HexDump - replaced intermediate String.format calls with custom padding - convert testcases to junit4 - closing resources also tested with an arbitary timezone (PST) and locale (ru) supresses forbidden apis check for - LocaleUtil (the only place where Locale.getDefault() and TimeZone.getDefault() should be called) - Classes using FontMetrics - without the actual text it's difficult to return something sane Some usage of UTC and Locale.ROOT might be still wrong, e.g. in MapiMessage we don't access the extended mapi properties, which might contain the timezone DataFormatter has now a Observable property which need to be observed when custom formats are used and the Locale changes git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1701688 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 28 +- .../FormatTrackingHSSFListener.java | 3 +- .../poi/hssf/model/InternalWorkbook.java | 4 +- .../poi/hssf/usermodel/DVConstraint.java | 3 +- .../poi/hssf/usermodel/DummyGraphics2d.java | 12 +- .../poi/hssf/usermodel/EscherGraphics.java | 24 +- .../apache/poi/hssf/usermodel/HSSFCell.java | 3 +- .../poi/hssf/usermodel/HSSFDataFormatter.java | 3 +- .../poi/poifs/filesystem/POIFSFileSystem.java | 17 + .../poi/ss/format/CellDateFormatter.java | 12 +- .../apache/poi/ss/format/CellFormatPart.java | 4 + .../poi/ss/format/CellGeneralFormatter.java | 2 +- .../poi/ss/format/CellNumberFormatter.java | 16 +- .../apache/poi/ss/formula/atp/DateParser.java | 22 +- .../poi/ss/formula/atp/WorkdayCalculator.java | 15 +- .../ss/formula/atp/YearFracCalculator.java | 13 +- .../formula/function/FunctionDataBuilder.java | 16 +- .../poi/ss/formula/functions/DateFunc.java | 11 +- .../poi/ss/formula/functions/Days360.java | 13 +- .../poi/ss/formula/functions/Dec2Hex.java | 2 +- .../poi/ss/formula/functions/EDate.java | 9 +- .../poi/ss/formula/functions/EOMonth.java | 19 +- .../ss/formula/functions/TextFunction.java | 2 +- .../poi/ss/formula/functions/Today.java | 19 +- .../poi/ss/formula/functions/WeekNum.java | 24 +- .../poi/ss/usermodel/DataFormatter.java | 129 ++- .../org/apache/poi/ss/usermodel/DateUtil.java | 49 +- .../ss/usermodel/ExcelStyleDateFormatter.java | 10 +- .../apache/poi/util/FontMetricsDumper.java | 6 +- src/java/org/apache/poi/util/HexDump.java | 62 +- src/java/org/apache/poi/util/LocaleUtil.java | 136 ++++ .../apache/poi/util/SuppressForbidden.java | 32 + .../opc/internal/PackagePropertiesPart.java | 14 +- .../dsig/facets/OOXMLSignatureFacet.java | 3 +- .../dsig/facets/XAdESSignatureFacet.java | 4 +- .../dsig/facets/XAdESXLSignatureFacet.java | 6 +- .../org/apache/poi/xslf/util/PPTX2PNG.java | 3 +- .../poi/xssf/extractor/XSSFExportToXml.java | 3 +- .../apache/poi/xssf/streaming/SXSSFCell.java | 3 +- .../apache/poi/xssf/usermodel/XSSFCell.java | 3 +- .../org/apache/poi/TestPOIXMLProperties.java | 65 +- .../opc/TestPackageCoreProperties.java | 147 ++-- .../poi/ss/format/TestCellFormatPart.java | 48 +- .../poi/ss/usermodel/BaseTestXCell.java | 7 +- .../poi/xssf/streaming/TestSXSSFCell.java | 9 +- .../usermodel/TestFormulaEvaluatorOnXSSF.java | 372 ++++----- .../poi/xssf/usermodel/TestUnfixedBugs.java | 41 +- .../poi/xssf/usermodel/TestXSSFBugs.java | 740 ++++++++++-------- .../poi/xssf/usermodel/TestXSSFCell.java | 22 +- .../devtools/forbidden-signatures.txt | 25 + .../poi/hmef/attribute/TNEFDateAttribute.java | 6 +- .../apache/poi/hslf/model/PPGraphics2D.java | 2 + .../apache/poi/hslf/util/SystemTimeUtils.java | 10 +- .../src/org/apache/poi/hsmf/MAPIMessage.java | 12 +- .../datatypes/MessageSubmissionChunk.java | 5 +- .../poi/hsmf/datatypes/PropertyValue.java | 4 +- .../src/org/apache/poi/hsmf/dev/HSMFDump.java | 11 +- .../hsmf/extractor/OutlookTextExtactor.java | 24 +- .../poi/hsmf/parsers/POIFSChunkParser.java | 9 +- .../apache/poi/hwpf/model/PlexOfField.java | 12 +- .../poi/hwpf/usermodel/DateAndTime.java | 7 +- .../poi/hslf/record/TestComment2000.java | 45 +- .../poi/hslf/record/TestComment2000Atom.java | 37 +- .../poi/hslf/util/TestSystemTimeUtils.java | 23 +- .../org/apache/poi/hsmf/AllHSMFTests.java | 46 +- .../poi/hsmf/TestFixedSizedProperties.java | 86 +- .../extractor/TestOutlookTextExtractor.java | 112 +-- .../hsmf/parsers/TestPOIFSChunkParser.java | 130 ++- .../org/apache/poi/hpsf/basic/TestWrite.java | 41 +- .../poi/hpsf/basic/TestWriteWellKnown.java | 519 ++++++------ .../hssf/extractor/TestExcelExtractor.java | 336 ++++---- .../apache/poi/hssf/usermodel/TestBugs.java | 24 +- .../poi/hssf/usermodel/TestCellStyle.java | 6 +- .../usermodel/TestFormulaEvaluatorBugs.java | 86 +- .../poi/hssf/usermodel/TestHSSFCell.java | 105 ++- .../hssf/usermodel/TestHSSFDataFormatter.java | 50 +- .../poi/hssf/usermodel/TestHSSFDateUtil.java | 210 +++-- .../hssf/usermodel/TestReadWriteChart.java | 26 +- .../apache/poi/hssf/usermodel/TestText.java | 52 +- .../poi/ss/format/CellFormatTestBase.java | 44 +- .../apache/poi/ss/format/TestCellFormat.java | 134 +++- .../poi/ss/formula/atp/TestDateParser.java | 33 +- .../formula/atp/TestNetworkdaysFunction.java | 31 +- .../ss/formula/atp/TestWorkdayCalculator.java | 77 +- .../ss/formula/atp/TestWorkdayFunction.java | 169 ++-- .../formula/atp/TestYearFracCalculator.java | 16 +- ...TestYearFracCalculatorFromSpreadsheet.java | 119 +-- .../eval/TestFormulasFromSpreadsheet.java | 316 +++----- .../poi/ss/formula/functions/TestDays360.java | 8 +- .../poi/ss/formula/functions/TestEDate.java | 38 +- .../poi/ss/formula/functions/TestEOMonth.java | 100 ++- .../poi/ss/formula/functions/TestText.java | 92 ++- .../poi/ss/formula/functions/TestTime.java | 16 +- .../apache/poi/ss/usermodel/BaseTestCell.java | 57 +- .../BaseTestSheetAutosizeColumn.java | 53 +- .../poi/ss/usermodel/TestDataFormatter.java | 45 +- .../apache/poi/ss/usermodel/TestDateUtil.java | 31 +- .../poi/ss/util/TestDateFormatConverter.java | 2 +- .../org/apache/poi/util/TestHexDump.java | 2 +- .../org/apache/poi/util/TestStringUtil.java | 2 +- 100 files changed, 3149 insertions(+), 2507 deletions(-) create mode 100644 src/java/org/apache/poi/util/LocaleUtil.java create mode 100644 src/java/org/apache/poi/util/SuppressForbidden.java create mode 100644 src/resources/devtools/forbidden-signatures.txt diff --git a/build.xml b/build.xml index add72bbbd..7d64dd3a7 100644 --- a/build.xml +++ b/build.xml @@ -1105,6 +1105,7 @@ under the License. failureproperty="ooxml.test.failed"> + @@ -1126,6 +1127,7 @@ under the License. + @@ -1715,6 +1717,7 @@ under the License. + @@ -1733,23 +1736,22 @@ under the License. - - - - - - - - - - - + classpathref="javadoc.classpath" + suppressAnnotation="org.apache.poi.util.SuppressForbidden" + > + + + + + diff --git a/src/java/org/apache/poi/hssf/eventusermodel/FormatTrackingHSSFListener.java b/src/java/org/apache/poi/hssf/eventusermodel/FormatTrackingHSSFListener.java index 1ca3db366..074c294c5 100644 --- a/src/java/org/apache/poi/hssf/eventusermodel/FormatTrackingHSSFListener.java +++ b/src/java/org/apache/poi/hssf/eventusermodel/FormatTrackingHSSFListener.java @@ -31,6 +31,7 @@ import org.apache.poi.hssf.record.NumberRecord; import org.apache.poi.hssf.record.Record; import org.apache.poi.hssf.usermodel.HSSFDataFormat; import org.apache.poi.hssf.usermodel.HSSFDataFormatter; +import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; @@ -52,7 +53,7 @@ public class FormatTrackingHSSFListener implements HSSFListener { * the {@link Locale#getDefault() default locale} for the formats. */ public FormatTrackingHSSFListener(HSSFListener childListener) { - this(childListener, Locale.getDefault()); + this(childListener, LocaleUtil.getUserLocale()); } /** diff --git a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java index a2670978e..7994f2820 100644 --- a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java +++ b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java @@ -22,7 +22,6 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Map.Entry; @@ -96,6 +95,7 @@ import org.apache.poi.ss.formula.udf.UDFFinder; import org.apache.poi.ss.usermodel.BuiltinFormats; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.util.Internal; +import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; @@ -1774,7 +1774,7 @@ public final class InternalWorkbook { retval.setDefaultCountry(( short ) 1); // from Russia with love ;) - if ( Locale.getDefault().toString().equals( "ru_RU" ) ) { + if ( LocaleUtil.getUserLocale().toString().equals( "ru_RU" ) ) { retval.setCurrentCountry(( short ) 7); } else { diff --git a/src/java/org/apache/poi/hssf/usermodel/DVConstraint.java b/src/java/org/apache/poi/hssf/usermodel/DVConstraint.java index 4548486a4..41f90fbfc 100644 --- a/src/java/org/apache/poi/hssf/usermodel/DVConstraint.java +++ b/src/java/org/apache/poi/hssf/usermodel/DVConstraint.java @@ -17,7 +17,6 @@ package org.apache.poi.hssf.usermodel; -import java.text.MessageFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @@ -463,7 +462,7 @@ public class DVConstraint implements DataValidationConstraint { case ValidationType.FORMULA: return createCustomFormulaConstraint(toFormulaString(dvRecord.getFormula1(), book).string()); default: - throw new UnsupportedOperationException(MessageFormat.format("validationType={0}", dvRecord.getDataType())); + throw new UnsupportedOperationException("validationType="+dvRecord.getDataType()); } } diff --git a/src/java/org/apache/poi/hssf/usermodel/DummyGraphics2d.java b/src/java/org/apache/poi/hssf/usermodel/DummyGraphics2d.java index edb87c862..3baefb691 100644 --- a/src/java/org/apache/poi/hssf/usermodel/DummyGraphics2d.java +++ b/src/java/org/apache/poi/hssf/usermodel/DummyGraphics2d.java @@ -34,13 +34,13 @@ import java.util.Map; public class DummyGraphics2d extends Graphics2D { - BufferedImage img; + private BufferedImage bufimg; private Graphics2D g2D; public DummyGraphics2d() { - img = new BufferedImage(1000, 1000, 2); - g2D = (Graphics2D)img.getGraphics(); + bufimg = new BufferedImage(1000, 1000, 2); + g2D = (Graphics2D)bufimg.getGraphics(); } public void addRenderingHints(Map hints) @@ -710,12 +710,6 @@ public class DummyGraphics2d return g2D.getClipBounds( r ); } - @SuppressWarnings("deprecation") - public Rectangle getClipRect() { - System.out.println( "getClipRect():" ); - return g2D.getClipRect(); - } - public Color getColor() { System.out.println( "getColor():" ); diff --git a/src/java/org/apache/poi/hssf/usermodel/EscherGraphics.java b/src/java/org/apache/poi/hssf/usermodel/EscherGraphics.java index 1f31e80bd..3bae84894 100644 --- a/src/java/org/apache/poi/hssf/usermodel/EscherGraphics.java +++ b/src/java/org/apache/poi/hssf/usermodel/EscherGraphics.java @@ -20,6 +20,7 @@ package org.apache.poi.hssf.usermodel; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; +import org.apache.poi.util.SuppressForbidden; import java.awt.*; import java.awt.image.ImageObserver; @@ -57,8 +58,7 @@ import java.text.AttributedCharacterIterator; * HSSFClientAnchor.getAnchorHeightInPoints(). * */ -public class EscherGraphics - extends Graphics +public class EscherGraphics extends Graphics { private HSSFShapeGroup escherGroup; private HSSFWorkbook workbook; @@ -293,18 +293,18 @@ public class EscherGraphics textbox.setString( s ); } - private HSSFFont matchFont( Font font ) + private HSSFFont matchFont( Font matchFont ) { HSSFColor hssfColor = workbook.getCustomPalette() .findColor((byte)foreground.getRed(), (byte)foreground.getGreen(), (byte)foreground.getBlue()); if (hssfColor == null) hssfColor = workbook.getCustomPalette().findSimilarColor((byte)foreground.getRed(), (byte)foreground.getGreen(), (byte)foreground.getBlue()); - boolean bold = (font.getStyle() & Font.BOLD) != 0; - boolean italic = (font.getStyle() & Font.ITALIC) != 0; + boolean bold = (matchFont.getStyle() & Font.BOLD) != 0; + boolean italic = (matchFont.getStyle() & Font.ITALIC) != 0; HSSFFont hssfFont = workbook.findFont(bold ? HSSFFont.BOLDWEIGHT_BOLD : 0, hssfColor.getIndex(), - (short)(font.getSize() * 20), - font.getName(), + (short)(matchFont.getSize() * 20), + matchFont.getName(), italic, false, (short)0, @@ -314,8 +314,8 @@ public class EscherGraphics hssfFont = workbook.createFont(); hssfFont.setBoldweight(bold ? HSSFFont.BOLDWEIGHT_BOLD : 0); hssfFont.setColor(hssfColor.getIndex()); - hssfFont.setFontHeight((short)(font.getSize() * 20)); - hssfFont.setFontName(font.getName()); + hssfFont.setFontHeight((short)(matchFont.getSize() * 20)); + hssfFont.setFontName(matchFont.getName()); hssfFont.setItalic(italic); hssfFont.setStrikeout(false); hssfFont.setTypeOffset((short) 0); @@ -431,11 +431,6 @@ public class EscherGraphics return null; } - public Rectangle getClipRect() - { - return getClipBounds(); - } - public Color getColor() { return foreground; @@ -447,6 +442,7 @@ public class EscherGraphics } @SuppressWarnings("deprecation") + @SuppressForbidden public FontMetrics getFontMetrics(Font f) { return Toolkit.getDefaultToolkit().getFontMetrics(f); diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java index b1e8b7a00..8fbdd1276 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java @@ -52,6 +52,7 @@ import org.apache.poi.ss.usermodel.RichTextString; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellReference; import org.apache.poi.ss.util.NumberToTextConverter; +import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; @@ -989,7 +990,7 @@ public class HSSFCell implements Cell { case CELL_TYPE_NUMERIC: //TODO apply the dataformat for this cell if (HSSFDateUtil.isCellDateFormatted(this)) { - DateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy"); + DateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy", LocaleUtil.getUserLocale()); return sdf.format(getDateCellValue()); } return String.valueOf(getNumericCellValue()); diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFDataFormatter.java b/src/java/org/apache/poi/hssf/usermodel/HSSFDataFormatter.java index af1243eb0..13abd91e6 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFDataFormatter.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFDataFormatter.java @@ -23,6 +23,7 @@ import java.text.SimpleDateFormat; import java.util.Locale; import org.apache.poi.ss.usermodel.DataFormatter; +import org.apache.poi.util.LocaleUtil; /** * HSSFDataFormatter contains methods for formatting the value stored in an @@ -76,7 +77,7 @@ public final class HSSFDataFormatter extends DataFormatter { * Creates a formatter using the {@link Locale#getDefault() default locale}. */ public HSSFDataFormatter() { - this(Locale.getDefault()); + this(LocaleUtil.getUserLocale()); } } diff --git a/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java b/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java index 5afb4eb8f..48d75ab94 100644 --- a/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java +++ b/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java @@ -19,6 +19,7 @@ package org.apache.poi.poifs.filesystem; +import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -85,6 +86,22 @@ public class POIFSFileSystem super(stream); } + /** + *

Creates a POIFSFileSystem from a File. This uses less memory than + * creating from an InputStream. The File will be opened read-only

+ * + *

Note that with this constructor, you will need to call {@link #close()} + * when you're done to have the underlying file closed, as the file is + * kept open during normal operation to read the data out.

+ * + * @param file the File from which to read the data + * + * @exception IOException on errors reading, or on invalid data + */ + public POIFSFileSystem(File file) throws IOException { + super(file); + } + /** * Checks that the supplied InputStream (which MUST * support mark and reset, or be a PushbackInputStream) diff --git a/src/java/org/apache/poi/ss/format/CellDateFormatter.java b/src/java/org/apache/poi/ss/format/CellDateFormatter.java index 0e6cfa15b..dcf702c32 100644 --- a/src/java/org/apache/poi/ss/format/CellDateFormatter.java +++ b/src/java/org/apache/poi/ss/format/CellDateFormatter.java @@ -24,19 +24,14 @@ import java.util.Calendar; import java.util.Date; import java.util.Formatter; import java.util.Locale; -import java.util.TimeZone; import java.util.regex.Matcher; +import org.apache.poi.util.LocaleUtil; + /** * Formats a date value. */ public class CellDateFormatter extends CellFormatter { - /** - * Excel doesn't store TimeZone information in the file, so if in doubt, - * use UTC to perform calculations - */ - private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getTimeZone("UTC"); - private boolean amPmUpper; private boolean showM; private boolean showAmPm; @@ -50,8 +45,7 @@ public class CellDateFormatter extends CellFormatter { "mm/d/y"); static { - Calendar c = Calendar.getInstance(DEFAULT_TIMEZONE, Locale.ROOT); - c.set(1904, 0, 1, 0, 0, 0); + Calendar c = LocaleUtil.getLocaleCalendar(1904, 0, 1, 0, 0, 0); EXCEL_EPOCH_DATE = c.getTime(); EXCEL_EPOCH_TIME = c.getTimeInMillis(); } diff --git a/src/java/org/apache/poi/ss/format/CellFormatPart.java b/src/java/org/apache/poi/ss/format/CellFormatPart.java index 9a966e152..40d8c0849 100644 --- a/src/java/org/apache/poi/ss/format/CellFormatPart.java +++ b/src/java/org/apache/poi/ss/format/CellFormatPart.java @@ -524,4 +524,8 @@ public class CellFormatPart { String str = m.group(g); return (str == null ? "" : str); } + + public String toString() { + return format.format; + } } diff --git a/src/java/org/apache/poi/ss/format/CellGeneralFormatter.java b/src/java/org/apache/poi/ss/format/CellGeneralFormatter.java index cb5d4a1bb..cdee8cf01 100644 --- a/src/java/org/apache/poi/ss/format/CellGeneralFormatter.java +++ b/src/java/org/apache/poi/ss/format/CellGeneralFormatter.java @@ -57,7 +57,7 @@ public class CellGeneralFormatter extends CellFormatter { stripZeros = false; } - Formatter formatter = new Formatter(toAppendTo); + Formatter formatter = new Formatter(toAppendTo, LOCALE); try { formatter.format(LOCALE, fmt, value); } finally { diff --git a/src/java/org/apache/poi/ss/format/CellNumberFormatter.java b/src/java/org/apache/poi/ss/format/CellNumberFormatter.java index 2ea72cc69..3addf46fe 100644 --- a/src/java/org/apache/poi/ss/format/CellNumberFormatter.java +++ b/src/java/org/apache/poi/ss/format/CellNumberFormatter.java @@ -17,6 +17,7 @@ package org.apache.poi.ss.format; import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; import java.text.FieldPosition; import java.util.BitSet; import java.util.Collections; @@ -30,6 +31,7 @@ import java.util.TreeSet; import java.util.regex.Matcher; import org.apache.poi.ss.format.CellFormatPart.PartHandler; +import org.apache.poi.util.LocaleUtil; /** * This class implements printing out a value using a number format. @@ -182,8 +184,8 @@ public class CellNumberFormatter extends CellFormatter { private char insertSignForExponent; public String handlePart(Matcher m, String part, CellFormatType type, - StringBuffer desc) { - int pos = desc.length(); + StringBuffer descBuf) { + int pos = descBuf.length(); char firstCh = part.charAt(0); switch (firstCh) { case 'e': @@ -203,7 +205,7 @@ public class CellNumberFormatter extends CellFormatter { case '#': if (insertSignForExponent != '\0') { specials.add(new Special(insertSignForExponent, pos)); - desc.append(insertSignForExponent); + descBuf.append(insertSignForExponent); insertSignForExponent = '\0'; pos++; } @@ -354,7 +356,8 @@ public class CellNumberFormatter extends CellFormatter { fmtBuf.append('E'); placeZeros(fmtBuf, exponentSpecials.subList(2, exponentSpecials.size())); - decimalFmt = new DecimalFormat(fmtBuf.toString()); + DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(LocaleUtil.getUserLocale()); + decimalFmt = new DecimalFormat(fmtBuf.toString(), dfs); } if (exponent != null) @@ -594,7 +597,7 @@ public class CellNumberFormatter extends CellFormatter { writeFraction(value, null, fractional, output, mods); } else { StringBuffer result = new StringBuffer(); - Formatter f = new Formatter(result); + Formatter f = new Formatter(result, LOCALE); try { f.format(LOCALE, printfFmt, value); } finally { @@ -767,6 +770,7 @@ public class CellNumberFormatter extends CellFormatter { writeInteger(exponentNum, output, exponentDigitSpecials, mods, false); } + @SuppressWarnings("unchecked") private void writeFraction(double value, StringBuffer result, double fractional, StringBuffer output, Set mods) { @@ -869,7 +873,7 @@ public class CellNumberFormatter extends CellFormatter { List numSpecials, Set mods) { StringBuffer sb = new StringBuffer(); - Formatter formatter = new Formatter(sb); + Formatter formatter = new Formatter(sb, LOCALE); try { formatter.format(LOCALE, fmt, num); } finally { diff --git a/src/java/org/apache/poi/ss/formula/atp/DateParser.java b/src/java/org/apache/poi/ss/formula/atp/DateParser.java index 73b51a5fb..4ab15888f 100644 --- a/src/java/org/apache/poi/ss/formula/atp/DateParser.java +++ b/src/java/org/apache/poi/ss/formula/atp/DateParser.java @@ -18,24 +18,16 @@ package org.apache.poi.ss.formula.atp; import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.Locale; -import java.util.TimeZone; import java.util.regex.Pattern; import org.apache.poi.ss.formula.eval.ErrorEval; import org.apache.poi.ss.formula.eval.EvaluationException; +import org.apache.poi.util.LocaleUtil; /** * Parser for java dates. */ public class DateParser { - /** - * Excel doesn't store TimeZone information in the file, so if in doubt, - * use UTC to perform calculations - */ - private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getTimeZone("UTC"); - public DateParser instance = new DateParser(); private DateParser() { @@ -80,10 +72,10 @@ public class DateParser { return makeDate(f0, f1, f2); } // otherwise the format seems to depend on OS settings (default date format) - if (false) { - // MM/DD/YYYY is probably a good guess, if the in the US - return makeDate(f2, f0, f1); - } +// if (false) { +// // MM/DD/YYYY is probably a good guess, if the in the US +// return makeDate(f2, f0, f1); +// } // TODO - find a way to choose the correct date format throw new RuntimeException("Unable to determine date format for text '" + strVal + "'"); } @@ -95,9 +87,7 @@ public class DateParser { if (month < 1 || month > 12) { throw new EvaluationException(ErrorEval.VALUE_INVALID); } - Calendar cal = new GregorianCalendar(DEFAULT_TIMEZONE, Locale.ROOT); - cal.set(year, month - 1, 1, 0, 0, 0); - cal.set(Calendar.MILLISECOND, 0); + Calendar cal = LocaleUtil.getLocaleCalendar(year, month - 1, 1, 0, 0, 0); if (day < 1 || day > cal.getActualMaximum(Calendar.DAY_OF_MONTH)) { throw new EvaluationException(ErrorEval.VALUE_INVALID); } diff --git a/src/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java b/src/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java index ada303436..29b29feaa 100644 --- a/src/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java +++ b/src/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java @@ -19,21 +19,14 @@ package org.apache.poi.ss.formula.atp; import java.util.Calendar; import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.util.LocaleUtil; /** * A calculator for workdays, considering dates as excel representations. */ public class WorkdayCalculator { - /** - * Excel doesn't store TimeZone information in the file, so if in doubt, - * use UTC to perform calculations - */ - private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getTimeZone("UTC"); - public static final WorkdayCalculator instance = new WorkdayCalculator(); /** @@ -69,7 +62,7 @@ public class WorkdayCalculator { public Date calculateWorkdays(double start, int workdays, double[] holidays) { Date startDate = DateUtil.getJavaDate(start); int direction = workdays < 0 ? -1 : 1; - Calendar endDate = Calendar.getInstance(DEFAULT_TIMEZONE, Locale.ROOT); + Calendar endDate = LocaleUtil.getLocaleCalendar(); endDate.setTime(startDate); double excelEndDate = DateUtil.getExcelDate(endDate.getTime()); while (workdays != 0) { @@ -97,7 +90,7 @@ public class WorkdayCalculator { int startDay = (int) Math.floor(start < end ? start : end); int endDay = (int) Math.floor(end > start ? end : start); for (; startDay <= endDay; startDay++) { - Calendar today = Calendar.getInstance(DEFAULT_TIMEZONE, Locale.ROOT); + Calendar today = LocaleUtil.getLocaleCalendar(); today.setTime(DateUtil.getJavaDate(startDay)); if (today.get(Calendar.DAY_OF_WEEK) == dayOfWeek) { pastDaysOfWeek++; @@ -133,7 +126,7 @@ public class WorkdayCalculator { * @return true if date is weekend, false otherwise. */ protected boolean isWeekend(double aDate) { - Calendar date = Calendar.getInstance(DEFAULT_TIMEZONE, Locale.ROOT); + Calendar date = LocaleUtil.getLocaleCalendar(); date.setTime(DateUtil.getJavaDate(aDate)); return date.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || date.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY; } diff --git a/src/java/org/apache/poi/ss/formula/atp/YearFracCalculator.java b/src/java/org/apache/poi/ss/formula/atp/YearFracCalculator.java index d9dc068d4..42bd9aed1 100644 --- a/src/java/org/apache/poi/ss/formula/atp/YearFracCalculator.java +++ b/src/java/org/apache/poi/ss/formula/atp/YearFracCalculator.java @@ -18,13 +18,11 @@ package org.apache.poi.ss.formula.atp; import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.Locale; -import java.util.TimeZone; import org.apache.poi.ss.formula.eval.ErrorEval; import org.apache.poi.ss.formula.eval.EvaluationException; import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.util.LocaleUtil; /** @@ -35,8 +33,6 @@ import org.apache.poi.ss.usermodel.DateUtil; * @author Josh Micich */ final class YearFracCalculator { - /** use UTC time-zone to avoid daylight savings issues */ - private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone("UTC"); private static final int MS_PER_HOUR = 60 * 60 * 1000; private static final int MS_PER_DAY = 24 * MS_PER_HOUR; private static final int DAYS_PER_NORMAL_YEAR = 365; @@ -317,9 +313,10 @@ final class YearFracCalculator { } private static SimpleDate createDate(int dayCount) { - GregorianCalendar calendar = new GregorianCalendar(UTC_TIME_ZONE, Locale.ROOT); - DateUtil.setCalendar(calendar, dayCount, 0, false, false); - return new SimpleDate(calendar); + /** use UTC time-zone to avoid daylight savings issues */ + Calendar cal = LocaleUtil.getLocaleCalendar(LocaleUtil.TIMEZONE_UTC); + DateUtil.setCalendar(cal, dayCount, 0, false, false); + return new SimpleDate(cal); } private static final class SimpleDate { diff --git a/src/java/org/apache/poi/ss/formula/function/FunctionDataBuilder.java b/src/java/org/apache/poi/ss/formula/function/FunctionDataBuilder.java index 6109cb7b9..b44a03ef3 100644 --- a/src/java/org/apache/poi/ss/formula/function/FunctionDataBuilder.java +++ b/src/java/org/apache/poi/ss/formula/function/FunctionDataBuilder.java @@ -30,16 +30,16 @@ import java.util.Set; */ final class FunctionDataBuilder { private int _maxFunctionIndex; - private final Map _functionDataByName; - private final Map _functionDataByIndex; + private final Map _functionDataByName; + private final Map _functionDataByIndex; /** stores indexes of all functions with footnotes (i.e. whose definitions might change) */ - private final Set _mutatingFunctionIndexes; + private final Set _mutatingFunctionIndexes; public FunctionDataBuilder(int sizeEstimate) { _maxFunctionIndex = -1; - _functionDataByName = new HashMap(sizeEstimate * 3 / 2); - _functionDataByIndex = new HashMap(sizeEstimate * 3 / 2); - _mutatingFunctionIndexes = new HashSet(); + _functionDataByName = new HashMap(sizeEstimate * 3 / 2); + _functionDataByIndex = new HashMap(sizeEstimate * 3 / 2); + _mutatingFunctionIndexes = new HashSet(); } public void add(int functionIndex, String functionName, int minParams, int maxParams, @@ -55,14 +55,14 @@ final class FunctionDataBuilder { } // allow function definitions to change only if both previous and the new items have footnotes FunctionMetadata prevFM; - prevFM = (FunctionMetadata) _functionDataByName.get(functionName); + prevFM = _functionDataByName.get(functionName); if(prevFM != null) { if(!hasFootnote || !_mutatingFunctionIndexes.contains(indexKey)) { throw new RuntimeException("Multiple entries for function name '" + functionName + "'"); } _functionDataByIndex.remove(Integer.valueOf(prevFM.getIndex())); } - prevFM = (FunctionMetadata) _functionDataByIndex.get(indexKey); + prevFM = _functionDataByIndex.get(indexKey); if(prevFM != null) { if(!hasFootnote || !_mutatingFunctionIndexes.contains(indexKey)) { throw new RuntimeException("Multiple entries for function index (" + functionIndex + ")"); diff --git a/src/java/org/apache/poi/ss/formula/functions/DateFunc.java b/src/java/org/apache/poi/ss/formula/functions/DateFunc.java index f767d1574..8ab14dc6d 100644 --- a/src/java/org/apache/poi/ss/formula/functions/DateFunc.java +++ b/src/java/org/apache/poi/ss/formula/functions/DateFunc.java @@ -27,18 +27,13 @@ import org.apache.poi.ss.formula.eval.EvaluationException; import org.apache.poi.ss.formula.eval.NumberEval; import org.apache.poi.ss.formula.eval.ValueEval; import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.util.LocaleUtil; /** * Implementation for the Excel function DATE */ public final class DateFunc extends Fixed3ArgFunction { - /** - * Excel doesn't store TimeZone information in the file, so if in doubt, - * use UTC to perform calculations - */ - private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getTimeZone("UTC"); - public static final Function instance = new DateFunc(); private DateFunc() { @@ -91,9 +86,7 @@ public final class DateFunc extends Fixed3ArgFunction { } // Turn this into a Java date - Calendar c = new GregorianCalendar(DEFAULT_TIMEZONE, Locale.ROOT); - c.set(year, month, day, 0, 0, 0); - c.set(Calendar.MILLISECOND, 0); + Calendar c = LocaleUtil.getLocaleCalendar(year, month, day); // Handle negative days of the week, that pull us across // the 29th of Feb 1900 diff --git a/src/java/org/apache/poi/ss/formula/functions/Days360.java b/src/java/org/apache/poi/ss/formula/functions/Days360.java index 83b12dbbb..8dba97656 100644 --- a/src/java/org/apache/poi/ss/formula/functions/Days360.java +++ b/src/java/org/apache/poi/ss/formula/functions/Days360.java @@ -17,14 +17,13 @@ package org.apache.poi.ss.formula.functions; import java.util.Calendar; -import java.util.Locale; -import java.util.TimeZone; import org.apache.poi.ss.formula.eval.EvaluationException; import org.apache.poi.ss.formula.eval.NumberEval; import org.apache.poi.ss.formula.eval.OperandResolver; import org.apache.poi.ss.formula.eval.ValueEval; import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.util.LocaleUtil; /** *

Calculates the number of days between two dates based on a 360-day year @@ -67,12 +66,6 @@ import org.apache.poi.ss.usermodel.DateUtil; * @see DAYS360 Function Produces Different Values Depending on the Version of Excel */ public class Days360 extends Var2or3ArgFunction { - /** - * Excel doesn't store TimeZone information in the file, so if in doubt, - * use UTC to perform calculations - */ - private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getTimeZone("UTC"); - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { double result; try { @@ -112,8 +105,8 @@ public class Days360 extends Var2or3ArgFunction { } private static Calendar getDate(double date) { - Calendar processedDate = Calendar.getInstance(DEFAULT_TIMEZONE, Locale.ROOT); - processedDate.setTime(DateUtil.getJavaDate(date, false, DEFAULT_TIMEZONE)); + Calendar processedDate = LocaleUtil.getLocaleCalendar(); + processedDate.setTime(DateUtil.getJavaDate(date, false)); return processedDate; } diff --git a/src/java/org/apache/poi/ss/formula/functions/Dec2Hex.java b/src/java/org/apache/poi/ss/formula/functions/Dec2Hex.java index caf92bb33..54a624652 100644 --- a/src/java/org/apache/poi/ss/formula/functions/Dec2Hex.java +++ b/src/java/org/apache/poi/ss/formula/functions/Dec2Hex.java @@ -109,7 +109,7 @@ public final class Dec2Hex extends Var1or2ArgFunction implements FreeRefFunction String hex; if (placesNumber != 0) { - hex = String.format("%0"+placesNumber+"X", number1.intValue(), Locale.ROOT); + hex = String.format(Locale.ROOT, "%0"+placesNumber+"X", number1.intValue()); } else { hex = Integer.toHexString(number1.intValue()); diff --git a/src/java/org/apache/poi/ss/formula/functions/EDate.java b/src/java/org/apache/poi/ss/formula/functions/EDate.java index 205879fed..dcfd704f1 100644 --- a/src/java/org/apache/poi/ss/formula/functions/EDate.java +++ b/src/java/org/apache/poi/ss/formula/functions/EDate.java @@ -30,17 +30,12 @@ import org.apache.poi.ss.formula.eval.NumberEval; import org.apache.poi.ss.formula.eval.RefEval; import org.apache.poi.ss.formula.eval.ValueEval; import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.util.LocaleUtil; /** * Implementation for Excel EDATE () function. */ public class EDate implements FreeRefFunction { - /** - * Excel doesn't store TimeZone information in the file, so if in doubt, - * use UTC to perform calculations - */ - private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getTimeZone("UTC"); - public static final FreeRefFunction instance = new EDate(); public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { @@ -52,7 +47,7 @@ public class EDate implements FreeRefFunction { int offsetInMonthAsNumber = (int) getValue(args[1]); Date startDate = DateUtil.getJavaDate(startDateAsNumber); - Calendar calendar = Calendar.getInstance(DEFAULT_TIMEZONE, Locale.ROOT); + Calendar calendar = LocaleUtil.getLocaleCalendar(); calendar.setTime(startDate); calendar.add(Calendar.MONTH, offsetInMonthAsNumber); return new NumberEval(DateUtil.getExcelDate(calendar.getTime())); diff --git a/src/java/org/apache/poi/ss/formula/functions/EOMonth.java b/src/java/org/apache/poi/ss/formula/functions/EOMonth.java index 968b67eba..63836e591 100644 --- a/src/java/org/apache/poi/ss/formula/functions/EOMonth.java +++ b/src/java/org/apache/poi/ss/formula/functions/EOMonth.java @@ -19,9 +19,6 @@ package org.apache.poi.ss.formula.functions; import java.util.Calendar; import java.util.Date; -import java.util.GregorianCalendar; -import java.util.Locale; -import java.util.TimeZone; import org.apache.poi.ss.formula.OperationEvaluationContext; import org.apache.poi.ss.formula.eval.ErrorEval; @@ -29,6 +26,7 @@ import org.apache.poi.ss.formula.eval.EvaluationException; import org.apache.poi.ss.formula.eval.NumberEval; import org.apache.poi.ss.formula.eval.ValueEval; import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.util.LocaleUtil; /** * Implementation for the Excel EOMONTH() function.

@@ -45,12 +43,6 @@ import org.apache.poi.ss.usermodel.DateUtil; * zero or negative (in the past). */ public class EOMonth implements FreeRefFunction { - /** - * Excel doesn't store TimeZone information in the file, so if in doubt, - * use UTC to perform calculations - */ - private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getTimeZone("UTC"); - public static final FreeRefFunction instance = new EOMonth(); @Override @@ -70,10 +62,13 @@ public class EOMonth implements FreeRefFunction { Date startDate = DateUtil.getJavaDate(startDateAsNumber, false); - Calendar cal = new GregorianCalendar(DEFAULT_TIMEZONE, Locale.ROOT); + Calendar cal = LocaleUtil.getLocaleCalendar(); cal.setTime(startDate); - cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0); - cal.set(Calendar.MILLISECOND, 0); + cal.clear(Calendar.HOUR); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.clear(Calendar.MINUTE); + cal.clear(Calendar.SECOND); + cal.clear(Calendar.MILLISECOND); cal.add(Calendar.MONTH, months + 1); cal.set(Calendar.DAY_OF_MONTH, 1); diff --git a/src/java/org/apache/poi/ss/formula/functions/TextFunction.java b/src/java/org/apache/poi/ss/formula/functions/TextFunction.java index 76c5fa1ba..7cffa1b89 100644 --- a/src/java/org/apache/poi/ss/formula/functions/TextFunction.java +++ b/src/java/org/apache/poi/ss/formula/functions/TextFunction.java @@ -36,7 +36,7 @@ import org.apache.poi.ss.usermodel.DataFormatter; */ public abstract class TextFunction implements Function { protected static final DataFormatter formatter = new DataFormatter(); - protected static final String EMPTY_STRING = ""; + protected static final String EMPTY_STRING = ""; protected static final String evaluateStringArg(ValueEval eval, int srcRow, int srcCol) throws EvaluationException { ValueEval ve = OperandResolver.getSingleValue(eval, srcRow, srcCol); diff --git a/src/java/org/apache/poi/ss/formula/functions/Today.java b/src/java/org/apache/poi/ss/formula/functions/Today.java index 60cdedb1b..d86844aa2 100644 --- a/src/java/org/apache/poi/ss/formula/functions/Today.java +++ b/src/java/org/apache/poi/ss/formula/functions/Today.java @@ -18,28 +18,23 @@ package org.apache.poi.ss.formula.functions; import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.Locale; -import java.util.TimeZone; import org.apache.poi.ss.formula.eval.NumberEval; import org.apache.poi.ss.formula.eval.ValueEval; import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.util.LocaleUtil; /** * Implementation of Excel TODAY() Function
*/ public final class Today extends Fixed0ArgFunction { - /** - * Excel doesn't store TimeZone information in the file, so if in doubt, - * use UTC to perform calculations - */ - private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getTimeZone("UTC"); - public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) { - Calendar now = new GregorianCalendar(DEFAULT_TIMEZONE, Locale.ROOT); - now.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE),0,0,0); - now.set(Calendar.MILLISECOND, 0); + Calendar now = LocaleUtil.getLocaleCalendar(); + now.clear(Calendar.HOUR); + now.set(Calendar.HOUR_OF_DAY,0); + now.clear(Calendar.MINUTE); + now.clear(Calendar.SECOND); + now.clear(Calendar.MILLISECOND); return new NumberEval(DateUtil.getExcelDate(now.getTime())); } } diff --git a/src/java/org/apache/poi/ss/formula/functions/WeekNum.java b/src/java/org/apache/poi/ss/formula/functions/WeekNum.java index f27ee7e30..888ad11a0 100644 --- a/src/java/org/apache/poi/ss/formula/functions/WeekNum.java +++ b/src/java/org/apache/poi/ss/formula/functions/WeekNum.java @@ -17,14 +17,16 @@ package org.apache.poi.ss.formula.functions; -import org.apache.poi.ss.formula.OperationEvaluationContext; -import org.apache.poi.ss.formula.eval.*; -import org.apache.poi.ss.usermodel.DateUtil; - import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.Locale; -import java.util.TimeZone; + +import org.apache.poi.ss.formula.OperationEvaluationContext; +import org.apache.poi.ss.formula.eval.ErrorEval; +import org.apache.poi.ss.formula.eval.EvaluationException; +import org.apache.poi.ss.formula.eval.NumberEval; +import org.apache.poi.ss.formula.eval.OperandResolver; +import org.apache.poi.ss.formula.eval.ValueEval; +import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.util.LocaleUtil; /** * Implementation for Excel WeekNum() function.

@@ -42,12 +44,6 @@ import java.util.TimeZone; * 2 Week begins on Monday. Weekdays are numbered 1 through 7. */ public class WeekNum extends Fixed2ArgFunction implements FreeRefFunction { - /** - * Excel doesn't store TimeZone information in the file, so if in doubt, - * use UTC to perform calculations - */ - private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getTimeZone("UTC"); - public static final FreeRefFunction instance = new WeekNum(); public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval serialNumVE, ValueEval returnTypeVE) { @@ -57,7 +53,7 @@ public class WeekNum extends Fixed2ArgFunction implements FreeRefFunction { } catch (EvaluationException e) { return ErrorEval.VALUE_INVALID; } - Calendar serialNumCalendar = new GregorianCalendar(DEFAULT_TIMEZONE, Locale.ROOT); + Calendar serialNumCalendar = LocaleUtil.getLocaleCalendar(); serialNumCalendar.setTime(DateUtil.getJavaDate(serialNum, false)); int returnType = 0; diff --git a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java index 6cb9d4d71..cecfd1072 100644 --- a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java +++ b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java @@ -36,10 +36,13 @@ import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Observable; +import java.util.Observer; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.poi.ss.util.NumberToTextConverter; +import org.apache.poi.util.LocaleUtil; /** @@ -100,7 +103,7 @@ import org.apache.poi.ss.util.NumberToTextConverter; * Excel will output "", DataFormatter will output "0". * */ -public class DataFormatter { +public class DataFormatter implements Observer { private static final String defaultFractionWholePartFormat = "#"; private static final String defaultFractionFractionPartFormat = "#/##"; /** Pattern to find a number format: "0" or "#" */ @@ -153,18 +156,18 @@ public class DataFormatter { /** * The decimal symbols of the locale used for formatting values. */ - private final DecimalFormatSymbols decimalSymbols; + private DecimalFormatSymbols decimalSymbols; /** * The date symbols of the locale used for formatting values. */ - private final DateFormatSymbols dateSymbols; + private DateFormatSymbols dateSymbols; /** General format for whole numbers. */ - private final Format generalWholeNumFormat; + private Format generalWholeNumFormat; /** General format for decimal numbers. */ - private final Format generalDecimalNumFormat; + private Format generalDecimalNumFormat; /** A default format to use when a number pattern cannot be parsed. */ private Format defaultNumFormat; @@ -173,15 +176,37 @@ public class DataFormatter { * A map to cache formats. * Map formats */ - private final Map formats; + private final Map formats = new HashMap(); private boolean emulateCsv = false; + /** stores the locale valid it the last formatting call */ + private Locale locale; + + /** stores if the locale should change according to {@link LocaleUtil#getUserLocale()} */ + private boolean localeIsAdapting = true; + + private class LocaleChangeObservable extends Observable { + void checkForLocaleChange() { + checkForLocaleChange(LocaleUtil.getUserLocale()); + } + void checkForLocaleChange(Locale newLocale) { + if (!localeIsAdapting) return; + if (newLocale.equals(locale)) return; + super.setChanged(); + notifyObservers(newLocale); + } + } + + /** the Observable to notify, when the locale has been changed */ + private final LocaleChangeObservable localeChangedObervable = new LocaleChangeObservable(); + /** * Creates a formatter using the {@link Locale#getDefault() default locale}. */ public DataFormatter() { this(false); + this.localeIsAdapting = true; } /** @@ -190,8 +215,8 @@ public class DataFormatter { * @param emulateCsv whether to emulate CSV output. */ public DataFormatter(boolean emulateCsv) { - this(Locale.getDefault()); - this.emulateCsv = emulateCsv; + this(LocaleUtil.getUserLocale(), emulateCsv); + this.localeIsAdapting = true; } /** @@ -208,29 +233,9 @@ public class DataFormatter { * Creates a formatter using the given locale. */ public DataFormatter(Locale locale) { - dateSymbols = new DateFormatSymbols(locale); - decimalSymbols = new DecimalFormatSymbols(locale); - generalWholeNumFormat = new DecimalFormat("#", decimalSymbols); - generalDecimalNumFormat = new DecimalFormat("#.##########", decimalSymbols); - - formats = new HashMap(); - - // init built-in formats - - Format zipFormat = ZipPlusFourFormat.instance; - addFormat("00000\\-0000", zipFormat); - addFormat("00000-0000", zipFormat); - - Format phoneFormat = PhoneFormat.instance; - // allow for format string variations - addFormat("[<=9999999]###\\-####;\\(###\\)\\ ###\\-####", phoneFormat); - addFormat("[<=9999999]###-####;(###) ###-####", phoneFormat); - addFormat("###\\-####;\\(###\\)\\ ###\\-####", phoneFormat); - addFormat("###-####;(###) ###-####", phoneFormat); - - Format ssnFormat = SSNFormat.instance; - addFormat("000\\-00\\-0000", ssnFormat); - addFormat("000-00-0000", ssnFormat); + localeChangedObervable.addObserver(this); + localeChangedObervable.checkForLocaleChange(locale); + this.localeIsAdapting = false; } /** @@ -260,6 +265,8 @@ public class DataFormatter { } private Format getFormat(double cellValue, int formatIndex, String formatStrIn) { + localeChangedObervable.checkForLocaleChange(); + // // Might be better to separate out the n p and z formats, falling back to p when n and z are not set. // // That however would require other code to be re factored. // String[] formatBits = formatStrIn.split(";"); @@ -329,6 +336,8 @@ public class DataFormatter { } private Format createFormat(double cellValue, int formatIndex, String sFormat) { + localeChangedObervable.checkForLocaleChange(); + String formatStr = sFormat; // Remove colour formatting if present @@ -666,6 +675,8 @@ public class DataFormatter { return getDefaultFormat(cell.getNumericCellValue()); } private Format getDefaultFormat(double cellValue) { + localeChangedObervable.checkForLocaleChange(); + // for numeric cells try user supplied default if (defaultNumFormat != null) { return defaultNumFormat; @@ -742,6 +753,8 @@ public class DataFormatter { * @see #formatCellValue(Cell) */ public String formatRawCellContents(double value, int formatIndex, String formatString, boolean use1904Windowing) { + localeChangedObervable.checkForLocaleChange(); + // Is it a date? if(DateUtil.isADateFormat(formatIndex,formatString)) { if(DateUtil.isValidExcelDate(value)) { @@ -820,6 +833,7 @@ public class DataFormatter { * @return a string value of the cell */ public String formatCellValue(Cell cell, FormulaEvaluator evaluator) { + localeChangedObervable.checkForLocaleChange(); if (cell == null) { return ""; @@ -927,6 +941,59 @@ public class DataFormatter { format.setRoundingMode(roundingMode); } + /** + * If the Locale has been changed via {@link LocaleUtil#setUserLocale(Locale)} the stored + * formats need to be refreshed. All formats which aren't originated from DataFormatter + * itself, i.e. all Formats added via {@link DataFormatter#addFormat(String, Format)} and + * {@link DataFormatter#setDefaultNumberFormat(Format)}, need to be added again. + * To notify callers, the returned {@link Observable} should be used. + * The Object in {@link Observer#update(Observable, Object)} is the new Locale. + * + * @return the listener object, where callers can register themself + */ + public Observable getLocaleChangedObservable() { + return localeChangedObervable; + } + + /** + * Update formats when locale has been changed + * + * @param observable usually this is our own Observable instance + * @param localeObj only reacts on Locale objects + */ + public void update(Observable observable, Object localeObj) { + if (!(localeObj instanceof Locale)) return; + Locale newLocale = (Locale)localeObj; + if (!localeIsAdapting || newLocale.equals(locale)) return; + + locale = newLocale; + + dateSymbols = DateFormatSymbols.getInstance(locale); + decimalSymbols = DecimalFormatSymbols.getInstance(locale); + generalWholeNumFormat = new DecimalFormat("#", decimalSymbols); + generalDecimalNumFormat = new DecimalFormat("#.##########", decimalSymbols); + + // init built-in formats + + formats.clear(); + Format zipFormat = ZipPlusFourFormat.instance; + addFormat("00000\\-0000", zipFormat); + addFormat("00000-0000", zipFormat); + + Format phoneFormat = PhoneFormat.instance; + // allow for format string variations + addFormat("[<=9999999]###\\-####;\\(###\\)\\ ###\\-####", phoneFormat); + addFormat("[<=9999999]###-####;(###) ###-####", phoneFormat); + addFormat("###\\-####;\\(###\\)\\ ###\\-####", phoneFormat); + addFormat("###-####;(###) ###-####", phoneFormat); + + Format ssnFormat = SSNFormat.instance; + addFormat("000\\-00\\-0000", ssnFormat); + addFormat("000-00-0000", ssnFormat); + } + + + /** * Format class for Excel's SSN format. This class mimics Excel's built-in * SSN formatting. diff --git a/src/java/org/apache/poi/ss/usermodel/DateUtil.java b/src/java/org/apache/poi/ss/usermodel/DateUtil.java index 0c3c07283..1613a54f6 100644 --- a/src/java/org/apache/poi/ss/usermodel/DateUtil.java +++ b/src/java/org/apache/poi/ss/usermodel/DateUtil.java @@ -20,10 +20,11 @@ package org.apache.poi.ss.usermodel; import java.util.Calendar; import java.util.Date; -import java.util.Locale; import java.util.TimeZone; import java.util.regex.Pattern; +import org.apache.poi.util.LocaleUtil; + /** * Contains methods for dealing with Excel dates. */ @@ -52,13 +53,6 @@ public class DateUtil { // elapsed time patterns: [h],[m] and [s] private static final Pattern date_ptrn4 = Pattern.compile("^\\[([hH]+|[mM]+|[sS]+)\\]"); - /** - * Excel doesn't store TimeZone information in the file, so if in doubt, - * use UTC to perform calculations - */ - private static final TimeZone TIMEZONE_UTC = TimeZone.getTimeZone("UTC"); - - /** * Given a Date, converts it into a double representing its internal Excel representation, * which is the number of days since 1/1/1900. Fractional days represent hours, minutes, and seconds. @@ -78,7 +72,7 @@ public class DateUtil { * @param use1904windowing Should 1900 or 1904 date windowing be used? */ public static double getExcelDate(Date date, boolean use1904windowing) { - Calendar calStart = Calendar.getInstance(getUserTimeZone(), Locale.ROOT); + Calendar calStart = LocaleUtil.getLocaleCalendar(); calStart.setTime(date); // If date includes hours, minutes, and seconds, set them to 0 return internalGetExcelDate(calStart, use1904windowing); } @@ -242,6 +236,9 @@ public class DateUtil { } calendar.set(startYear,0, wholeDays + dayAdjust, 0, 0, 0); calendar.set(Calendar.MILLISECOND, millisecondsInDay); + if (calendar.get(Calendar.MILLISECOND) == 0) { + calendar.clear(Calendar.MILLISECOND); + } if (roundSeconds) { calendar.add(Calendar.MILLISECOND, 500); calendar.clear(Calendar.MILLISECOND); @@ -281,7 +278,7 @@ public class DateUtil { * @return Java representation of the date in UTC, or null if date is not a valid Excel date */ public static Calendar getJavaCalendarUTC(double date, boolean use1904windowing) { - return getJavaCalendar(date, use1904windowing, TIMEZONE_UTC, false); + return getJavaCalendar(date, use1904windowing, LocaleUtil.TIMEZONE_UTC, false); } @@ -314,9 +311,9 @@ public class DateUtil { int millisecondsInDay = (int)((date - wholeDays) * DAY_MILLISECONDS + 0.5); Calendar calendar; if (timeZone != null) { - calendar = Calendar.getInstance(timeZone, Locale.ROOT); + calendar = LocaleUtil.getLocaleCalendar(timeZone); } else { - calendar = Calendar.getInstance(getUserTimeZone(), Locale.ROOT); // using default time-zone + calendar = LocaleUtil.getLocaleCalendar(); // using default time-zone } setCalendar(calendar, wholeDays, millisecondsInDay, use1904windowing, roundSeconds); return calendar; @@ -334,13 +331,6 @@ public class DateUtil { private static ThreadLocal lastFormatString = new ThreadLocal(); private static ThreadLocal lastCachedResult = new ThreadLocal(); - private static ThreadLocal userTimeZone = new ThreadLocal() { - @Override - protected TimeZone initialValue() { - return TIMEZONE_UTC; - } - }; - private static boolean isCached(String formatString, int formatIndex) { String cachedFormatString = lastFormatString.get(); return cachedFormatString != null && formatIndex == lastFormatIndex.get() @@ -353,23 +343,6 @@ public class DateUtil { lastCachedResult.set(Boolean.valueOf(cached)); } - /** - * as timezone information is not stored in any format, it can be - * set before any date calculations take place - * - * @param timezone the timezone under which date calculations take place - */ - public static void setUserTimeZone(TimeZone timezone) { - userTimeZone.set(timezone); - } - - /** - * @return the time zone which is used for date calculations - */ - public static TimeZone getUserTimeZone() { - return userTimeZone.get(); - } - /** * Given a format ID and its format String, will check to see if the * format represents a date format or not. @@ -684,9 +657,7 @@ public class DateUtil { int month = parseInt(monthStr, "month", 1, 12); int day = parseInt(dayStr, "day", 1, 31); - Calendar cal = Calendar.getInstance(getUserTimeZone(), Locale.ROOT); - cal.set(year, month-1, day, 0, 0, 0); - cal.set(Calendar.MILLISECOND, 0); + Calendar cal = LocaleUtil.getLocaleCalendar(year, month-1, day); return cal.getTime(); } private static int parseInt(String strVal, String fieldName, int rangeMax) throws FormatException { diff --git a/src/java/org/apache/poi/ss/usermodel/ExcelStyleDateFormatter.java b/src/java/org/apache/poi/ss/usermodel/ExcelStyleDateFormatter.java index fd2b61da3..c075b55b2 100644 --- a/src/java/org/apache/poi/ss/usermodel/ExcelStyleDateFormatter.java +++ b/src/java/org/apache/poi/ss/usermodel/ExcelStyleDateFormatter.java @@ -17,6 +17,9 @@ package org.apache.poi.ss.usermodel; import java.util.*; + +import org.apache.poi.util.LocaleUtil; + import java.math.RoundingMode; import java.text.*; @@ -56,16 +59,15 @@ public class ExcelStyleDateFormatter extends SimpleDateFormat { DataFormatter.setExcelStyleRoundingMode(format2digits, RoundingMode.DOWN); DataFormatter.setExcelStyleRoundingMode(format3digit); DataFormatter.setExcelStyleRoundingMode(format4digits); + setTimeZone(LocaleUtil.getUserTimeZone()); } private double dateToBeFormatted = 0.0; - public ExcelStyleDateFormatter() { - super(); - } + // no-arg constructor is private because of undefined super call with locale public ExcelStyleDateFormatter(String pattern) { - super(processFormatPattern(pattern)); + super(processFormatPattern(pattern), LocaleUtil.getUserLocale()); } public ExcelStyleDateFormatter(String pattern, diff --git a/src/java/org/apache/poi/util/FontMetricsDumper.java b/src/java/org/apache/poi/util/FontMetricsDumper.java index c974c1e16..96676954a 100644 --- a/src/java/org/apache/poi/util/FontMetricsDumper.java +++ b/src/java/org/apache/poi/util/FontMetricsDumper.java @@ -18,7 +18,10 @@ package org.apache.poi.util; -import java.awt.*; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.GraphicsEnvironment; +import java.awt.Toolkit; import java.io.FileOutputStream; import java.io.IOException; import java.util.Properties; @@ -26,6 +29,7 @@ import java.util.Properties; @SuppressWarnings("deprecation") public class FontMetricsDumper { + @SuppressForbidden public static void main( String[] args ) throws IOException { diff --git a/src/java/org/apache/poi/util/HexDump.java b/src/java/org/apache/poi/util/HexDump.java index 3cf2758b6..1357b88f0 100644 --- a/src/java/org/apache/poi/util/HexDump.java +++ b/src/java/org/apache/poi/util/HexDump.java @@ -149,14 +149,15 @@ public class HexDump { chars_read = 16; } - buffer.append(String.format(Locale.ROOT, "%08X ", display_offset)); + buffer.append(xpad(display_offset, 8, "")); for (int k = 0; k < 16; k++) { if (k < chars_read) { - buffer.append(String.format(Locale.ROOT, "%02X ", data[ k + j ])); + buffer.append(xpad(data[ k + j ], 2, " ")); } else { buffer.append(" "); } } + buffer.append(' '); for (int k = 0; k < chars_read; k++) { buffer.append(toAscii(data[ k + j ])); } @@ -232,20 +233,19 @@ public class HexDump { * will be written to a new line * @return A String representing the array of bytes */ - public static String toHex(final byte[] value, final int bytesPerLine) - { - final int digits = - (int) Math.round(Math.log(value.length) / Math.log(10) + 0.5); - final String formatString = (digits == 0 ? ": %d" : "%0"+digits+"d: "); - StringBuffer retVal = new StringBuffer(); - retVal.append(String.format(Locale.ROOT, formatString, 0)); - int i = -1; - for(int x = 0; x < value.length; x++) - { - if (++i == bytesPerLine) - { + public static String toHex(final byte[] value, final int bytesPerLine) { + if (value.length == 0) { + return ": 0"; + } + final int digits = (int) Math.round(Math.log(value.length) / Math.log(10) + 0.5); + StringBuilder retVal = new StringBuilder(); + retVal.append(xpad(0, digits, "")); + retVal.append(": "); + for(int x=0, i=-1; x < value.length; x++) { + if (++i == bytesPerLine) { retVal.append('\n'); - retVal.append(String.format(Locale.ROOT, formatString, x)); + retVal.append(xpad(x, digits, "")); + retVal.append(": "); i = 0; } else if (x>0) { retVal.append(", "); @@ -262,7 +262,7 @@ public class HexDump { * @return The result right padded with 0 */ public static String toHex(final short value) { - return String.format(Locale.ROOT, "%04X", value); + return xpad(value & 0xFFFF, 4, ""); } /** @@ -272,7 +272,7 @@ public class HexDump { * @return The result right padded with 0 */ public static String toHex(final byte value) { - return String.format(Locale.ROOT, "%02X", value); + return xpad(value & 0xFF, 2, ""); } /** @@ -282,7 +282,7 @@ public class HexDump { * @return The result right padded with 0 */ public static String toHex(final int value) { - return String.format(Locale.ROOT, "%08X", value); + return xpad(value & 0xFFFFFFFF, 8, ""); } /** @@ -292,7 +292,7 @@ public class HexDump { * @return The result right padded with 0 */ public static String toHex(final long value) { - return String.format(Locale.ROOT, "%016X", value); + return xpad(value & 0xFFFFFFFF, 16, ""); } /** @@ -336,30 +336,46 @@ public class HexDump { * @return string of 16 (zero padded) uppercase hex chars and prefixed with '0x' */ public static String longToHex(long value) { - return String.format(Locale.ROOT, "0x%016X", value); + return xpad(value, 16, "0x"); } /** * @return string of 8 (zero padded) uppercase hex chars and prefixed with '0x' */ public static String intToHex(int value) { - return String.format(Locale.ROOT, "0x%08X", value & 0xFFFFFFFF); + return xpad(value & 0xFFFFFFFF, 8, "0x"); } /** * @return string of 4 (zero padded) uppercase hex chars and prefixed with '0x' */ public static String shortToHex(int value) { - return String.format(Locale.ROOT, "0x%04X", value & 0xFFFF); + return xpad(value & 0xFFFF, 4, "0x"); } /** * @return string of 2 (zero padded) uppercase hex chars and prefixed with '0x' */ public static String byteToHex(int value) { - return String.format(Locale.ROOT, "0x%02X", value & 0xFF); + return xpad(value & 0xFF, 2, "0x"); } + private static String xpad(long value, int pad, String prefix) { + String sv = Long.toHexString(value).toUpperCase(Locale.ROOT); + int len = sv.length(); + if ((pad == 0 || len == pad) && "".equals(prefix)) return sv; + StringBuilder sb = new StringBuilder(prefix); + if (len < pad) { + sb.append("0000000000000000", 0, pad-len); + sb.append(sv); + } else if (len > pad) { + sb.append(sv, len-pad, len); + } else { + sb.append(sv); + } + return sb.toString(); + } + public static void main(String[] args) throws Exception { File file = new File(args[0]); InputStream in = new BufferedInputStream(new FileInputStream(file)); diff --git a/src/java/org/apache/poi/util/LocaleUtil.java b/src/java/org/apache/poi/util/LocaleUtil.java new file mode 100644 index 000000000..4edd65d18 --- /dev/null +++ b/src/java/org/apache/poi/util/LocaleUtil.java @@ -0,0 +1,136 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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 org.apache.poi.util; + +import java.util.Calendar; +import java.util.Locale; +import java.util.TimeZone; + +/** + * This utility class is used to set locale and time zone settings beside + * of the JDK internal {@link java.util.Locale#setDefault(Locale)} and + * {@link java.util.TimeZone#setDefault(TimeZone)} methods, because + * the locale/time zone specific handling of certain office documents - + * maybe for different time zones / locales ... - shouldn't affect + * other java components. + * + * The settings are saved in a {@link java.lang.ThreadLocal}, + * so they only apply to the current thread and can't be set globally. + */ +public class LocaleUtil { + /** + * Excel doesn't store TimeZone information in the file, so if in doubt, + * use UTC to perform calculations + */ + public static final TimeZone TIMEZONE_UTC = TimeZone.getTimeZone("UTC"); + + private static final ThreadLocal userTimeZone = new ThreadLocal() { + @Override + @SuppressForbidden + protected TimeZone initialValue() { + return TimeZone.getDefault(); + } + }; + + private static final ThreadLocal userLocale = new ThreadLocal() { + @Override + @SuppressForbidden + protected Locale initialValue() { + return Locale.getDefault(); + } + }; + + /** + * As time zone information is not stored in any format, it can be + * set before any date calculations take place. + * This setting is specific to the current thread. + * + * @param timezone the timezone under which date calculations take place + */ + public static void setUserTimeZone(TimeZone timezone) { + userTimeZone.set(timezone); + } + + /** + * @return the time zone which is used for date calculations, defaults to UTC + */ + public static TimeZone getUserTimeZone() { + return userTimeZone.get(); + } + + /** + * Sets default user locale. + * This setting is specific to the current thread. + */ + public static void setUserLocale(Locale locale) { + userLocale.set(locale); + } + + /** + * @return the default user locale, defaults to {@link Locale#ROOT} + */ + public static Locale getUserLocale() { + return userLocale.get(); + } + + /** + * @return a calendar for the user locale and time zone + */ + public static Calendar getLocaleCalendar() { + return getLocaleCalendar(getUserTimeZone()); + } + + /** + * Convenience method - month is 0-based as in java.util.Calendar + * + * @param year + * @param month + * @param day + * @return a calendar for the user locale and time zone, and the given date + */ + public static Calendar getLocaleCalendar(int year, int month, int day) { + return getLocaleCalendar(year, month, day, 0, 0, 0); + } + + /** + * Convenience method - month is 0-based as in java.util.Calendar + * + * @param year + * @param month + * @param day + * @param hour + * @param minute + * @param second + * @return a calendar for the user locale and time zone, and the given date + */ + public static Calendar getLocaleCalendar(int year, int month, int day, int hour, int minute, int second) { + Calendar cal = getLocaleCalendar(); + cal.set(year, month, day, hour, minute, second); + cal.clear(Calendar.MILLISECOND); + return cal; + } + + /** + * @return a calendar for the user locale and time zone + */ + public static Calendar getLocaleCalendar(TimeZone timeZone) { + return Calendar.getInstance(timeZone, getUserLocale()); + } +} + diff --git a/src/java/org/apache/poi/util/SuppressForbidden.java b/src/java/org/apache/poi/util/SuppressForbidden.java new file mode 100644 index 000000000..81891e0c6 --- /dev/null +++ b/src/java/org/apache/poi/util/SuppressForbidden.java @@ -0,0 +1,32 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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 org.apache.poi.util; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/* + * Marking class for elements to be ignored by the forbidden apis check + */ +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.METHOD, ElementType.TYPE}) +public @interface SuppressForbidden { + +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PackagePropertiesPart.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PackagePropertiesPart.java index 523cdeca6..3b917a6fb 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PackagePropertiesPart.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PackagePropertiesPart.java @@ -22,8 +22,7 @@ import java.io.OutputStream; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Date; - -import java.util.TimeZone; +import java.util.Locale; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidOperationException; @@ -33,6 +32,7 @@ import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePartName; import org.apache.poi.openxml4j.opc.PackageProperties; import org.apache.poi.openxml4j.util.Nullable; +import org.apache.poi.util.LocaleUtil; /** * Represents the core properties part of a package. @@ -559,9 +559,8 @@ public final class PackagePropertiesPart extends PackagePart implements if (s == null || s.equals("")) { return new Nullable(); } - SimpleDateFormat df = new SimpleDateFormat( - "yyyy-MM-dd'T'HH:mm:ss'Z'"); - df.setTimeZone(TimeZone.getTimeZone("UTC")); + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ROOT); + df.setTimeZone(LocaleUtil.TIMEZONE_UTC); Date d = df.parse(s, new ParsePosition(0)); if (d == null) { throw new InvalidFormatException("Date not well formated"); @@ -586,9 +585,8 @@ public final class PackagePropertiesPart extends PackagePart implements return ""; } - SimpleDateFormat df = new SimpleDateFormat( - "yyyy-MM-dd'T'HH:mm:ss'Z'"); - df.setTimeZone(TimeZone.getTimeZone("UTC")); + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ROOT); + df.setTimeZone(LocaleUtil.TIMEZONE_UTC); return df.format(date); } diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/OOXMLSignatureFacet.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/OOXMLSignatureFacet.java index 59ae52a20..ab3aa070e 100644 --- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/OOXMLSignatureFacet.java +++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/OOXMLSignatureFacet.java @@ -31,6 +31,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Set; import java.util.TimeZone; @@ -196,7 +197,7 @@ public class OOXMLSignatureFacet extends SignatureFacet { /* * SignatureTime */ - DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ROOT); fmt.setTimeZone(TimeZone.getTimeZone("UTC")); String nowStr = fmt.format(signatureConfig.getExecutionTime()); LOG.log(POILogger.DEBUG, "now: " + nowStr); diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESSignatureFacet.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESSignatureFacet.java index c14fb3834..5441d58bb 100644 --- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESSignatureFacet.java +++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESSignatureFacet.java @@ -31,6 +31,7 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.TimeZone; @@ -115,8 +116,7 @@ public class XAdESSignatureFacet extends SignatureFacet { SignedSignaturePropertiesType signedSignatureProperties = signedProperties.addNewSignedSignatureProperties(); // SigningTime - Calendar xmlGregorianCalendar = Calendar.getInstance(); - xmlGregorianCalendar.setTimeZone(TimeZone.getTimeZone("Z")); + Calendar xmlGregorianCalendar = Calendar.getInstance(TimeZone.getTimeZone("Z"), Locale.ROOT); xmlGregorianCalendar.setTime(signatureConfig.getExecutionTime()); xmlGregorianCalendar.clear(Calendar.MILLISECOND); signedSignatureProperties.setSigningTime(xmlGregorianCalendar); diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESXLSignatureFacet.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESXLSignatureFacet.java index 1a1ac1839..136f3e0eb 100644 --- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESXLSignatureFacet.java +++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESXLSignatureFacet.java @@ -39,6 +39,8 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.List; +import java.util.Locale; +import java.util.TimeZone; import java.util.UUID; import javax.xml.crypto.MarshalException; @@ -214,7 +216,7 @@ public class XAdESXLSignatureFacet extends SignatureFacet { CRLIdentifierType crlIdentifier = crlRef.addNewCRLIdentifier(); String issuerName = crl.getIssuerDN().getName().replace(",", ", "); crlIdentifier.setIssuer(issuerName); - Calendar cal = Calendar.getInstance(); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("Z"), Locale.ROOT); cal.setTime(crl.getThisUpdate()); crlIdentifier.setIssueTime(cal); crlIdentifier.setNumber(getCrlNumber(crl)); @@ -238,7 +240,7 @@ public class XAdESXLSignatureFacet extends SignatureFacet { BasicOCSPResp basicOcspResp = (BasicOCSPResp)ocspResp.getResponseObject(); - Calendar cal = Calendar.getInstance(); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("Z"), Locale.ROOT); cal.setTime(basicOcspResp.getProducedAt()); ocspIdentifier.setProducedAt(cal); diff --git a/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java b/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java index cc59f04fd..9318a0894 100644 --- a/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java +++ b/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java @@ -26,6 +26,7 @@ import java.awt.image.BufferedImage; import java.io.File; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import javax.imageio.ImageIO; @@ -155,7 +156,7 @@ public class PPTX2PNG { // save the result if (!"null".equals(format)) { String outname = file.getName().replaceFirst(".pptx?", ""); - outname = String.format("%1$s-%2$04d.%3$s", outname, slideNo, format); + outname = String.format(Locale.ROOT, "%1$s-%2$04d.%3$s", outname, slideNo, format); File outfile = new File(outdir, outname); ImageIO.write(img, format, outfile); } diff --git a/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java b/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java index d608f9615..b55360200 100644 --- a/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java +++ b/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java @@ -25,6 +25,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Vector; @@ -314,7 +315,7 @@ public class XSSFExportToXml implements Comparator{ } private String getFormattedDate(XSSFCell cell) { - DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.ROOT); return sdf.format(cell.getDateCellValue()); } diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java index c95430bfc..e88667f47 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java @@ -35,6 +35,7 @@ import org.apache.poi.ss.usermodel.RichTextString; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellReference; +import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; import org.apache.poi.xssf.usermodel.XSSFHyperlink; @@ -653,7 +654,7 @@ public class SXSSFCell implements Cell { return getCellFormula(); case CELL_TYPE_NUMERIC: if (DateUtil.isCellDateFormatted(this)) { - DateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy"); + DateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy", LocaleUtil.getUserLocale()); return sdf.format(getDateCellValue()); } return getNumericCellValue() + ""; diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java index bb57f65c6..0e2c9c549 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java @@ -21,6 +21,7 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; +import java.util.Locale; import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.formula.FormulaParser; @@ -840,7 +841,7 @@ public final class XSSFCell implements Cell { return getCellFormula(); case CELL_TYPE_NUMERIC: if (DateUtil.isCellDateFormatted(this)) { - DateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy"); + DateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy", Locale.ROOT); return sdf.format(getDateCellValue()); } return Double.toString(getNumericCellValue()); diff --git a/src/ooxml/testcases/org/apache/poi/TestPOIXMLProperties.java b/src/ooxml/testcases/org/apache/poi/TestPOIXMLProperties.java index e18554302..61e57362c 100644 --- a/src/ooxml/testcases/org/apache/poi/TestPOIXMLProperties.java +++ b/src/ooxml/testcases/org/apache/poi/TestPOIXMLProperties.java @@ -17,37 +17,49 @@ package org.apache.poi; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import java.io.IOException; import java.util.Calendar; import java.util.Date; -import java.util.GregorianCalendar; -import java.util.Locale; -import java.util.TimeZone; - -import junit.framework.TestCase; import org.apache.poi.POIXMLProperties.CoreProperties; import org.apache.poi.openxml4j.util.Nullable; +import org.apache.poi.util.LocaleUtil; import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xwpf.XWPFTestDataSamples; import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; /** * Test setting extended and custom OOXML properties */ -public final class TestPOIXMLProperties extends TestCase { +public final class TestPOIXMLProperties { + private XWPFDocument sampleDoc; private POIXMLProperties _props; private CoreProperties _coreProperties; + @Before public void setUp() throws IOException { - XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("documentProperties.docx"); + sampleDoc = XWPFTestDataSamples.openSampleDocument("documentProperties.docx"); _props = sampleDoc.getProperties(); _coreProperties = _props.getCoreProperties(); assertNotNull(_props); } + + @After + public void closeResources() throws Exception { + sampleDoc.close(); + } - public void testWorkbookExtendedProperties() { + @Test + public void testWorkbookExtendedProperties() throws Exception { XSSFWorkbook workbook = new XSSFWorkbook(); POIXMLProperties props = workbook.getProperties(); assertNotNull(props); @@ -71,7 +83,7 @@ public final class TestPOIXMLProperties extends TestCase { XSSFWorkbook newWorkbook = XSSFTestDataSamples.writeOutAndReadBack(workbook); - + workbook.close(); assertTrue(workbook != newWorkbook); @@ -88,16 +100,19 @@ public final class TestPOIXMLProperties extends TestCase { assertEquals(application, newCtProps.getApplication()); assertEquals(appVersion, newCtProps.getAppVersion()); + + newWorkbook.close(); } /** * Test usermodel API for setting custom properties */ - public void testCustomProperties() { - POIXMLDocument wb = new XSSFWorkbook(); + @Test + public void testCustomProperties() throws Exception { + POIXMLDocument wb1 = new XSSFWorkbook(); - POIXMLProperties.CustomProperties customProps = wb.getProperties().getCustomProperties(); + POIXMLProperties.CustomProperties customProps = wb1.getProperties().getCustomProperties(); customProps.addProperty("test-1", "string val"); customProps.addProperty("test-2", 1974); customProps.addProperty("test-3", 36.6); @@ -110,9 +125,10 @@ public final class TestPOIXMLProperties extends TestCase { } customProps.addProperty("test-4", true); - wb = XSSFTestDataSamples.writeOutAndReadBack((XSSFWorkbook)wb); + POIXMLDocument wb2 = XSSFTestDataSamples.writeOutAndReadBack((XSSFWorkbook)wb1); + wb1.close(); org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperties ctProps = - wb.getProperties().getCustomProperties().getUnderlyingProperties(); + wb2.getProperties().getCustomProperties().getUnderlyingProperties(); assertEquals(4, ctProps.sizeOfPropertyArray()); org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty p; @@ -131,7 +147,7 @@ public final class TestPOIXMLProperties extends TestCase { p = ctProps.getPropertyArray(2); assertEquals("{D5CDD505-2E9C-101B-9397-08002B2CF9AE}", p.getFmtid()); assertEquals("test-3", p.getName()); - assertEquals(36.6, p.getR8()); + assertEquals(36.6, p.getR8(), 0); assertEquals(4, p.getPid()); p = ctProps.getPropertyArray(3); @@ -139,9 +155,12 @@ public final class TestPOIXMLProperties extends TestCase { assertEquals("test-4", p.getName()); assertEquals(true, p.getBool()); assertEquals(5, p.getPid()); + + wb2.close(); } - public void testDocumentProperties() { + @Test + public void testDocumentProperties() { String category = _coreProperties.getCategory(); assertEquals("test", category); String contentStatus = "Draft"; @@ -158,21 +177,25 @@ public final class TestPOIXMLProperties extends TestCase { assertEquals("Hello World", title); } - public void testTransitiveSetters() throws IOException { + @Test + public void testTransitiveSetters() throws IOException { XWPFDocument doc = new XWPFDocument(); CoreProperties cp = doc.getProperties().getCoreProperties(); - Date dateCreated = new GregorianCalendar(2010, 6, 15, 10, 0, 0).getTime(); + + Date dateCreated = LocaleUtil.getLocaleCalendar(2010, 6, 15, 10, 0, 0).getTime(); cp.setCreated(new Nullable(dateCreated)); assertEquals(dateCreated.toString(), cp.getCreated().toString()); - doc = XWPFTestDataSamples.writeOutAndReadBack(doc); + XWPFDocument doc2 = XWPFTestDataSamples.writeOutAndReadBack(doc); + doc.close(); cp = doc.getProperties().getCoreProperties(); Date dt3 = cp.getCreated(); assertEquals(dateCreated.toString(), dt3.toString()); - + doc2.close(); } + @Test public void testGetSetRevision() { String revision = _coreProperties.getRevision(); assertTrue("Revision number is 1", Integer.parseInt(revision) > 1); @@ -183,7 +206,7 @@ public final class TestPOIXMLProperties extends TestCase { } public static boolean dateTimeEqualToUTCString(Date dateTime, String utcString) { - Calendar utcCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.UK); + Calendar utcCalendar = LocaleUtil.getLocaleCalendar(LocaleUtil.TIMEZONE_UTC); utcCalendar.setTimeInMillis(dateTime.getTime()); String dateTimeUtcString = utcCalendar.get(Calendar.YEAR) + "-" + zeroPad((utcCalendar.get(Calendar.MONTH)+1)) + "-" + diff --git a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackageCoreProperties.java b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackageCoreProperties.java index ddc36af0b..bbc53d6b9 100644 --- a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackageCoreProperties.java +++ b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackageCoreProperties.java @@ -17,111 +17,97 @@ package org.apache.poi.openxml4j.opc; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.IOException; import java.io.InputStream; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.TimeZone; - -import junit.framework.TestCase; +import java.util.Locale; import org.apache.poi.POIDataSamples; import org.apache.poi.openxml4j.OpenXML4JTestDataSamples; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart; import org.apache.poi.openxml4j.util.Nullable; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; +import org.apache.poi.util.LocaleUtil; import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.junit.Test; import org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty; -public final class TestPackageCoreProperties extends TestCase { - private static final POILogger logger = POILogFactory.getLogger(TestPackageCoreProperties.class); - +public final class TestPackageCoreProperties { /** * Test package core properties getters. */ - public void testGetProperties() { - try { - // Open the package - OPCPackage p = OPCPackage.open(OpenXML4JTestDataSamples.openSampleStream("TestPackageCoreProperiesGetters.docx")); - compareProperties(p); - p.revert(); - } catch (OpenXML4JException e) { - logger.log(POILogger.DEBUG, e.getMessage()); - throw new RuntimeException(e); - } catch (IOException e) { - throw new RuntimeException(e); - } + @Test + public void testGetProperties() throws Exception { + // Open the package + @SuppressWarnings("resource") + OPCPackage p = OPCPackage.open(OpenXML4JTestDataSamples.openSampleStream("TestPackageCoreProperiesGetters.docx")); + compareProperties(p); + p.revert(); } /** * Test package core properties setters. */ - public void testSetProperties() throws Exception { + @Test + public void testSetProperties() throws Exception { String inputPath = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCoreProperiesSetters.docx"); File outputFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageCoreProperiesSettersOUTPUT.docx"); // Open package - OPCPackage p = OPCPackage.open(inputPath, PackageAccess.READ_WRITE); - try { - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - df.setTimeZone(TimeZone.getTimeZone("UTC")); - Date dateToInsert = df.parse("2007-05-12T08:00:00Z", new ParsePosition( - 0)); - - PackageProperties props = p.getPackageProperties(); - props.setCategoryProperty("MyCategory"); - props.setContentStatusProperty("MyContentStatus"); - props.setContentTypeProperty("MyContentType"); - props.setCreatedProperty(new Nullable(dateToInsert)); - props.setCreatorProperty("MyCreator"); - props.setDescriptionProperty("MyDescription"); - props.setIdentifierProperty("MyIdentifier"); - props.setKeywordsProperty("MyKeywords"); - props.setLanguageProperty("MyLanguage"); - props.setLastModifiedByProperty("Julien Chable"); - props.setLastPrintedProperty(new Nullable(dateToInsert)); - props.setModifiedProperty(new Nullable(dateToInsert)); - props.setRevisionProperty("2"); - props.setTitleProperty("MyTitle"); - props.setSubjectProperty("MySubject"); - props.setVersionProperty("2"); - // Save the package in the output directory - p.save(outputFile); - - // Open the newly created file to check core properties saved values. - OPCPackage p2 = OPCPackage.open(outputFile.getAbsolutePath(), PackageAccess.READ); - try { - compareProperties(p2); - p2.revert(); - } finally { - p2.close(); - } - outputFile.delete(); - } finally { - // use revert to not re-write the input file - p.revert(); - } + @SuppressWarnings("resource") + OPCPackage p = OPCPackage.open(inputPath, PackageAccess.READ_WRITE); + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ROOT); + df.setTimeZone(LocaleUtil.TIMEZONE_UTC); + Date dateToInsert = df.parse("2007-05-12T08:00:00Z", new ParsePosition(0)); + + PackageProperties props = p.getPackageProperties(); + props.setCategoryProperty("MyCategory"); + props.setContentStatusProperty("MyContentStatus"); + props.setContentTypeProperty("MyContentType"); + props.setCreatedProperty(new Nullable(dateToInsert)); + props.setCreatorProperty("MyCreator"); + props.setDescriptionProperty("MyDescription"); + props.setIdentifierProperty("MyIdentifier"); + props.setKeywordsProperty("MyKeywords"); + props.setLanguageProperty("MyLanguage"); + props.setLastModifiedByProperty("Julien Chable"); + props.setLastPrintedProperty(new Nullable(dateToInsert)); + props.setModifiedProperty(new Nullable(dateToInsert)); + props.setRevisionProperty("2"); + props.setTitleProperty("MyTitle"); + props.setSubjectProperty("MySubject"); + props.setVersionProperty("2"); + // Save the package in the output directory + p.save(outputFile); + p.revert(); + + // Open the newly created file to check core properties saved values. + @SuppressWarnings("resource") + OPCPackage p2 = OPCPackage.open(outputFile.getAbsolutePath(), PackageAccess.READ); + compareProperties(p2); + p2.revert(); + outputFile.delete(); } private void compareProperties(OPCPackage p) throws InvalidFormatException { - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - df.setTimeZone(TimeZone.getTimeZone("UTC")); - Date expectedDate = df.parse("2007-05-12T08:00:00Z", new ParsePosition( - 0)); + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ROOT); + df.setTimeZone(LocaleUtil.TIMEZONE_UTC); + Date expectedDate = df.parse("2007-05-12T08:00:00Z", new ParsePosition(0)); // Gets the core properties PackageProperties props = p.getPackageProperties(); assertEquals("MyCategory", props.getCategoryProperty().getValue()); - assertEquals("MyContentStatus", props.getContentStatusProperty() - .getValue()); + assertEquals("MyContentStatus", props.getContentStatusProperty().getValue()); assertEquals("MyContentType", props.getContentTypeProperty().getValue()); assertEquals(expectedDate, props.getCreatedProperty().getValue()); assertEquals("MyCreator", props.getCreatorProperty().getValue()); @@ -129,8 +115,7 @@ public final class TestPackageCoreProperties extends TestCase { assertEquals("MyIdentifier", props.getIdentifierProperty().getValue()); assertEquals("MyKeywords", props.getKeywordsProperty().getValue()); assertEquals("MyLanguage", props.getLanguageProperty().getValue()); - assertEquals("Julien Chable", props.getLastModifiedByProperty() - .getValue()); + assertEquals("Julien Chable", props.getLastModifiedByProperty().getValue()); assertEquals(expectedDate, props.getLastPrintedProperty().getValue()); assertEquals(expectedDate, props.getModifiedProperty().getValue()); assertEquals("2", props.getRevisionProperty().getValue()); @@ -139,9 +124,10 @@ public final class TestPackageCoreProperties extends TestCase { assertEquals("2", props.getVersionProperty().getValue()); } - public void testCoreProperties_bug51374() throws Exception { - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - df.setTimeZone(TimeZone.getTimeZone("UTC")); + @Test + public void testCoreProperties_bug51374() throws Exception { + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ROOT); + df.setTimeZone(LocaleUtil.TIMEZONE_UTC); String strDate = "2007-05-12T08:00:00Z"; Date date = df.parse(strDate); @@ -197,7 +183,8 @@ public final class TestPackageCoreProperties extends TestCase { pkg.close(); } - public void testGetPropertiesLO() throws Exception { + @Test + public void testGetPropertiesLO() throws Exception { // Open the package OPCPackage pkg1 = OPCPackage.open(OpenXML4JTestDataSamples.openSampleStream("51444.xlsx")); PackageProperties props1 = pkg1.getPackageProperties(); @@ -206,13 +193,16 @@ public final class TestPackageCoreProperties extends TestCase { ByteArrayOutputStream out = new ByteArrayOutputStream(); pkg1.save(out); out.close(); + pkg1.close(); OPCPackage pkg2 = OPCPackage.open(new ByteArrayInputStream(out.toByteArray())); PackageProperties props2 = pkg2.getPackageProperties(); props2.setTitleProperty("Bug 51444 fixed"); + pkg2.close(); } - public void testEntitiesInCoreProps_56164() throws Exception { + @Test + public void testEntitiesInCoreProps_56164() throws Exception { InputStream is = OpenXML4JTestDataSamples.openSampleStream("CorePropertiesHasEntities.ooxml"); OPCPackage p = OPCPackage.open(is); is.close(); @@ -236,9 +226,12 @@ public final class TestPackageCoreProperties extends TestCase { // Check assertEquals("Stefan Kopf", props.getCreatorProperty().getValue()); + + p.close(); } - public void testListOfCustomProperties() throws Exception { + @Test + public void testListOfCustomProperties() throws Exception { File inp = POIDataSamples.getSpreadSheetInstance().getFile("ExcelWithAttachments.xlsm"); OPCPackage pkg = OPCPackage.open(inp, PackageAccess.READ); XSSFWorkbook wb = new XSSFWorkbook(pkg); diff --git a/src/ooxml/testcases/org/apache/poi/ss/format/TestCellFormatPart.java b/src/ooxml/testcases/org/apache/poi/ss/format/TestCellFormatPart.java index 9fd6664ad..7d1952577 100644 --- a/src/ooxml/testcases/org/apache/poi/ss/format/TestCellFormatPart.java +++ b/src/ooxml/testcases/org/apache/poi/ss/format/TestCellFormatPart.java @@ -16,14 +16,36 @@ ==================================================================== */ package org.apache.poi.ss.format; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.xssf.XSSFITestDataProvider; +import static org.junit.Assert.assertEquals; +import java.util.Locale; +import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.util.LocaleUtil; +import org.apache.poi.xssf.XSSFITestDataProvider; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + /** Test the individual CellFormatPart types. */ public class TestCellFormatPart extends CellFormatTestBase { + + private static Locale userLocale; + + @BeforeClass + public static void setLocale() { + userLocale = LocaleUtil.getUserLocale(); + LocaleUtil.setUserLocale(Locale.ROOT); + } + + @AfterClass + public static void unsetLocale() { + LocaleUtil.setUserLocale(userLocale); + } + private static final Pattern NUMBER_EXTRACT_FMT = Pattern.compile( "([-+]?[0-9]+)(\\.[0-9]+)?.*(?:(e).*?([+-]?[0-9]+))", Pattern.CASE_INSENSITIVE); @@ -32,6 +54,7 @@ public class TestCellFormatPart extends CellFormatTestBase { super(XSSFITestDataProvider.instance); } + @Test public void testGeneralFormat() throws Exception { runFormatTests("GeneralFormatTests.xlsx", new CellValue() { public Object getValue(Cell cell) { @@ -54,6 +77,7 @@ public class TestCellFormatPart extends CellFormatTestBase { }); } + @Test public void testNumberApproxFormat() throws Exception { runFormatTests("NumberFormatApproxTests.xlsx", new CellValue() { public Object getValue(Cell cell) { @@ -73,14 +97,22 @@ public class TestCellFormatPart extends CellFormatTestBase { }); } + @Test public void testDateFormat() throws Exception { - runFormatTests("DateFormatTests.xlsx", new CellValue() { - public Object getValue(Cell cell) { - return cell.getDateCellValue(); - } - }); + TimeZone tz = LocaleUtil.getUserTimeZone(); + LocaleUtil.setUserTimeZone(TimeZone.getTimeZone("CET")); + try { + runFormatTests("DateFormatTests.xlsx", new CellValue() { + public Object getValue(Cell cell) { + return cell.getDateCellValue(); + } + }); + } finally { + LocaleUtil.setUserTimeZone(tz); + } } + @Test public void testElapsedFormat() throws Exception { runFormatTests("ElapsedFormatTests.xlsx", new CellValue() { public Object getValue(Cell cell) { @@ -89,6 +121,7 @@ public class TestCellFormatPart extends CellFormatTestBase { }); } + @Test public void testTextFormat() throws Exception { runFormatTests("TextFormatTests.xlsx", new CellValue() { public Object getValue(Cell cell) { @@ -100,6 +133,7 @@ public class TestCellFormatPart extends CellFormatTestBase { }); } + @Test public void testConditions() throws Exception { runFormatTests("FormatConditionTests.xlsx", new CellValue() { Object getValue(Cell cell) { diff --git a/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXCell.java b/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXCell.java index f78819ca3..947ab212d 100644 --- a/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXCell.java +++ b/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXCell.java @@ -17,13 +17,13 @@ package org.apache.poi.ss.usermodel; +import static org.junit.Assert.assertEquals; + import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.ss.ITestDataProvider; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.xssf.SXSSFITestDataProvider; -import org.apache.poi.xssf.XSSFITestDataProvider; import org.apache.poi.xssf.streaming.SXSSFCell; import org.apache.poi.xssf.usermodel.XSSFCell; +import org.junit.Test; /** * Class for combined testing of XML-specific functionality of @@ -37,6 +37,7 @@ public abstract class BaseTestXCell extends BaseTestCell { super(testDataProvider); } + @Test public void testXmlEncoding(){ Workbook wb = _testDataProvider.createWorkbook(); Sheet sh = wb.createSheet(); diff --git a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFCell.java b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFCell.java index 25f1d1917..9daf0ccb1 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFCell.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFCell.java @@ -19,6 +19,8 @@ package org.apache.poi.xssf.streaming; +import static org.junit.Assert.assertEquals; + import java.io.IOException; import javax.xml.namespace.QName; @@ -30,6 +32,8 @@ import org.apache.poi.xssf.SXSSFITestDataProvider; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.xmlbeans.XmlCursor; +import org.junit.AfterClass; +import org.junit.Test; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst; /** @@ -42,11 +46,12 @@ public class TestSXSSFCell extends BaseTestXCell { super(SXSSFITestDataProvider.instance); } - @Override - public void tearDown(){ + @AfterClass + public static void tearDown(){ SXSSFITestDataProvider.instance.cleanup(); } + @Test public void testPreserveSpaces() throws IOException { String[] samplesWithSpaces = { " POI", diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestFormulaEvaluatorOnXSSF.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestFormulaEvaluatorOnXSSF.java index 1b680d24e..dd966bddc 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestFormulaEvaluatorOnXSSF.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestFormulaEvaluatorOnXSSF.java @@ -17,14 +17,18 @@ package org.apache.poi.xssf.usermodel; -import java.io.InputStream; -import java.io.PrintStream; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; -import junit.framework.Assert; -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Locale; import org.apache.poi.hssf.HSSFTestDataSamples; +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.openxml4j.opc.PackageAccess; import org.apache.poi.ss.formula.eval.TestFormulasFromSpreadsheet; import org.apache.poi.ss.formula.functions.TestMathX; import org.apache.poi.ss.usermodel.Cell; @@ -32,7 +36,13 @@ import org.apache.poi.ss.usermodel.CellValue; import org.apache.poi.ss.usermodel.FormulaEvaluator; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.util.LocaleUtil; +import org.junit.AfterClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; /** * Performs much the same role as {@link TestFormulasFromSpreadsheet}, @@ -44,206 +54,127 @@ import org.apache.poi.openxml4j.opc.OPCPackage; * Excel 2007, and re-save it as FormulaEvalTestData_Copy.xlsx * */ -public final class TestFormulaEvaluatorOnXSSF extends TestCase { - - private static final class Result { - public static final int SOME_EVALUATIONS_FAILED = -1; - public static final int ALL_EVALUATIONS_SUCCEEDED = +1; - public static final int NO_EVALUATIONS_FOUND = 0; - } +@RunWith(Parameterized.class) +public final class TestFormulaEvaluatorOnXSSF { + private static XSSFWorkbook workbook; + private static Sheet sheet; + private static FormulaEvaluator evaluator; + private static Locale userLocale; + /** * This class defines constants for navigating around the test data spreadsheet used for these tests. */ - private static final class SS { + private static interface SS { /** * Name of the test spreadsheet (found in the standard test data folder) */ - public final static String FILENAME = "FormulaEvalTestData_Copy.xlsx"; + String FILENAME = "FormulaEvalTestData_Copy.xlsx"; /** * Row (zero-based) in the test spreadsheet where the operator examples start. */ - public static final int START_OPERATORS_ROW_INDEX = 22; // Row '23' + int START_OPERATORS_ROW_INDEX = 22; // Row '23' /** * Row (zero-based) in the test spreadsheet where the function examples start. */ - public static final int START_FUNCTIONS_ROW_INDEX = 95; // Row '96' + int START_FUNCTIONS_ROW_INDEX = 95; // Row '96' /** * Index of the column that contains the function names */ - public static final int COLUMN_INDEX_FUNCTION_NAME = 1; // Column 'B' + int COLUMN_INDEX_FUNCTION_NAME = 1; // Column 'B' /** * Used to indicate when there are no more functions left */ - public static final String FUNCTION_NAMES_END_SENTINEL = ""; + String FUNCTION_NAMES_END_SENTINEL = ""; /** * Index of the column where the test values start (for each function) */ - public static final short COLUMN_INDEX_FIRST_TEST_VALUE = 3; // Column 'D' + short COLUMN_INDEX_FIRST_TEST_VALUE = 3; // Column 'D' /** * Each function takes 4 rows in the test spreadsheet */ - public static final int NUMBER_OF_ROWS_PER_FUNCTION = 4; + int NUMBER_OF_ROWS_PER_FUNCTION = 4; } - private XSSFWorkbook workbook; - private Sheet sheet; - // Note - multiple failures are aggregated before ending. - // If one or more functions fail, a single AssertionFailedError is thrown at the end - private int _functionFailureCount; - private int _functionSuccessCount; - private int _evaluationFailureCount; - private int _evaluationSuccessCount; + @Parameter(value = 0) + public String targetFunctionName; + @Parameter(value = 1) + public int formulasRowIdx; + @Parameter(value = 2) + public int expectedValuesRowIdx; - private static final Cell getExpectedValueCell(Row row, short columnIndex) { - if (row == null) { - return null; - } - return row.getCell(columnIndex); - } + @AfterClass + public static void closeResource() throws Exception { + LocaleUtil.setUserLocale(userLocale); + workbook.close(); + } + + @Parameters(name="{0}") + public static Collection data() throws Exception { + // Function "Text" uses custom-formats which are locale specific + // can't set the locale on a per-testrun execution, as some settings have been + // already set, when we would try to change the locale by then + userLocale = LocaleUtil.getUserLocale(); + LocaleUtil.setUserLocale(Locale.ROOT); + + workbook = new XSSFWorkbook( OPCPackage.open(HSSFTestDataSamples.getSampleFile(SS.FILENAME), PackageAccess.READ) ); + sheet = workbook.getSheetAt( 0 ); + evaluator = new XSSFFormulaEvaluator(workbook); + + List data = new ArrayList(); + + processFunctionGroup(data, SS.START_OPERATORS_ROW_INDEX, null); + processFunctionGroup(data, SS.START_FUNCTIONS_ROW_INDEX, null); + // example for debugging individual functions/operators: + // processFunctionGroup(data, SS.START_OPERATORS_ROW_INDEX, "ConcatEval"); + // processFunctionGroup(data, SS.START_FUNCTIONS_ROW_INDEX, "Text"); + + return data; + } + + /** + * @param startRowIndex row index in the spreadsheet where the first function/operator is found + * @param testFocusFunctionName name of a single function/operator to test alone. + * Typically pass null to test all functions + */ + private static void processFunctionGroup(List data, int startRowIndex, String testFocusFunctionName) { + for (int rowIndex = startRowIndex; true; rowIndex += SS.NUMBER_OF_ROWS_PER_FUNCTION) { + Row r = sheet.getRow(rowIndex); + String targetFunctionName = getTargetFunctionName(r); + if(targetFunctionName == null) { + fail("Test spreadsheet cell empty on row (" + + (rowIndex+1) + "). Expected function name or '" + + SS.FUNCTION_NAMES_END_SENTINEL + "'"); + } + if(targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) { + // found end of functions list + break; + } + if(testFocusFunctionName == null || targetFunctionName.equalsIgnoreCase(testFocusFunctionName)) { + + // expected results are on the row below + Row expectedValuesRow = sheet.getRow(rowIndex + 1); + if(expectedValuesRow == null) { + int missingRowNum = rowIndex + 2; //+1 for 1-based, +1 for next row + fail("Missing expected values row for function '" + + targetFunctionName + " (row " + missingRowNum + ")"); + } + + data.add(new Object[]{targetFunctionName, rowIndex, rowIndex + 1}); + } + } + } - private static void confirmExpectedResult(String msg, Cell expected, CellValue actual) { - if (expected == null) { - throw new AssertionFailedError(msg + " - Bad setup data expected value is null"); - } - if(actual == null) { - throw new AssertionFailedError(msg + " - actual value was null"); - } - - switch (expected.getCellType()) { - case Cell.CELL_TYPE_BLANK: - assertEquals(msg, Cell.CELL_TYPE_BLANK, actual.getCellType()); - break; - case Cell.CELL_TYPE_BOOLEAN: - assertEquals(msg, Cell.CELL_TYPE_BOOLEAN, actual.getCellType()); - assertEquals(msg, expected.getBooleanCellValue(), actual.getBooleanValue()); - break; - case Cell.CELL_TYPE_ERROR: - assertEquals(msg, Cell.CELL_TYPE_ERROR, actual.getCellType()); - if(false) { // TODO: fix ~45 functions which are currently returning incorrect error values - assertEquals(msg, expected.getErrorCellValue(), actual.getErrorValue()); - } - break; - case Cell.CELL_TYPE_FORMULA: // will never be used, since we will call method after formula evaluation - throw new AssertionFailedError("Cannot expect formula as result of formula evaluation: " + msg); - case Cell.CELL_TYPE_NUMERIC: - assertEquals(msg, Cell.CELL_TYPE_NUMERIC, actual.getCellType()); - TestMathX.assertEquals(msg, expected.getNumericCellValue(), actual.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR); -// double delta = Math.abs(expected.getNumericCellValue()-actual.getNumberValue()); -// double pctExpected = Math.abs(0.00001*expected.getNumericCellValue()); -// assertTrue(msg, delta <= pctExpected); - break; - case Cell.CELL_TYPE_STRING: - assertEquals(msg, Cell.CELL_TYPE_STRING, actual.getCellType()); - assertEquals(msg, expected.getRichStringCellValue().getString(), actual.getStringValue()); - break; - } - } - - - protected void setUp() throws Exception { - if (workbook == null) { - InputStream is = HSSFTestDataSamples.openSampleFileStream(SS.FILENAME); - OPCPackage pkg = OPCPackage.open(is); - workbook = new XSSFWorkbook( pkg ); - sheet = workbook.getSheetAt( 0 ); - } - _functionFailureCount = 0; - _functionSuccessCount = 0; - _evaluationFailureCount = 0; - _evaluationSuccessCount = 0; - } - - /** - * Checks that we can actually open the file - */ - public void testOpen() { - assertNotNull(workbook); - } - - /** - * Disabled for now, as many things seem to break - * for XSSF, which is a shame - */ - public void testFunctionsFromTestSpreadsheet() { - - processFunctionGroup(SS.START_OPERATORS_ROW_INDEX, null); - processFunctionGroup(SS.START_FUNCTIONS_ROW_INDEX, null); - // example for debugging individual functions/operators: -// processFunctionGroup(SS.START_OPERATORS_ROW_INDEX, "ConcatEval"); -// processFunctionGroup(SS.START_FUNCTIONS_ROW_INDEX, "AVERAGE"); - - // confirm results - String successMsg = "There were " - + _evaluationSuccessCount + " successful evaluation(s) and " - + _functionSuccessCount + " function(s) without error"; - if(_functionFailureCount > 0) { - String msg = _functionFailureCount + " function(s) failed in " - + _evaluationFailureCount + " evaluation(s). " + successMsg; - throw new AssertionFailedError(msg); - } - if(false) { // normally no output for successful tests - System.out.println(getClass().getName() + ": " + successMsg); - } - } - - /** - * @param startRowIndex row index in the spreadsheet where the first function/operator is found - * @param testFocusFunctionName name of a single function/operator to test alone. - * Typically pass null to test all functions - */ - private void processFunctionGroup(int startRowIndex, String testFocusFunctionName) { - - FormulaEvaluator evaluator = new XSSFFormulaEvaluator(workbook); - - int rowIndex = startRowIndex; - while (true) { - Row r = sheet.getRow(rowIndex); - String targetFunctionName = getTargetFunctionName(r); - if(targetFunctionName == null) { - throw new AssertionFailedError("Test spreadsheet cell empty on row (" - + (rowIndex+1) + "). Expected function name or '" - + SS.FUNCTION_NAMES_END_SENTINEL + "'"); - } - if(targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) { - // found end of functions list - break; - } - if(testFocusFunctionName == null || targetFunctionName.equalsIgnoreCase(testFocusFunctionName)) { - - // expected results are on the row below - Row expectedValuesRow = sheet.getRow(rowIndex + 1); - if(expectedValuesRow == null) { - int missingRowNum = rowIndex + 2; //+1 for 1-based, +1 for next row - throw new AssertionFailedError("Missing expected values row for function '" - + targetFunctionName + " (row " + missingRowNum + ")"); - } - switch(processFunctionRow(evaluator, targetFunctionName, r, expectedValuesRow)) { - case Result.ALL_EVALUATIONS_SUCCEEDED: _functionSuccessCount++; break; - case Result.SOME_EVALUATIONS_FAILED: _functionFailureCount++; break; - default: - throw new RuntimeException("unexpected result"); - case Result.NO_EVALUATIONS_FOUND: // do nothing - } - } - rowIndex += SS.NUMBER_OF_ROWS_PER_FUNCTION; - } - } - - /** - * - * @return a constant from the local Result class denoting whether there were any evaluation - * cases, and whether they all succeeded. - */ - private int processFunctionRow(FormulaEvaluator evaluator, String targetFunctionName, - Row formulasRow, Row expectedValuesRow) { - - int result = Result.NO_EVALUATIONS_FOUND; // so far + @Test + public void processFunctionRow() { + Row formulasRow = sheet.getRow(formulasRowIdx); + Row expectedValuesRow = sheet.getRow(expectedValuesRowIdx); + short endcolnum = formulasRow.getLastCellNum(); // iterate across the row for all the evaluation cases @@ -256,31 +187,44 @@ public final class TestFormulaEvaluatorOnXSSF extends TestCase { continue; } - CellValue actualValue; - try { - actualValue = evaluator.evaluate(c); - } catch (RuntimeException e) { - _evaluationFailureCount ++; - printShortStackTrace(System.err, e); - result = Result.SOME_EVALUATIONS_FAILED; - continue; - } + CellValue actValue = evaluator.evaluate(c); + Cell expValue = (expectedValuesRow == null) ? null : expectedValuesRow.getCell(colnum); - Cell expectedValueCell = getExpectedValueCell(expectedValuesRow, colnum); - try { - confirmExpectedResult("Function '" + targetFunctionName + "': Formula: " + c.getCellFormula() + " @ " + formulasRow.getRowNum() + ":" + colnum, - expectedValueCell, actualValue); - _evaluationSuccessCount ++; - if(result != Result.SOME_EVALUATIONS_FAILED) { - result = Result.ALL_EVALUATIONS_SUCCEEDED; - } - } catch (AssertionFailedError e) { - _evaluationFailureCount ++; - printShortStackTrace(System.err, e); - result = Result.SOME_EVALUATIONS_FAILED; - } + String msg = String.format(Locale.ROOT, "Function '%s': Formula: %s @ %d:%d" + , targetFunctionName, c.getCellFormula(), formulasRow.getRowNum(), colnum); + + assertNotNull(msg + " - Bad setup data expected value is null", expValue); + assertNotNull(msg + " - actual value was null", actValue); + + switch (expValue.getCellType()) { + case Cell.CELL_TYPE_BLANK: + assertEquals(msg, Cell.CELL_TYPE_BLANK, actValue.getCellType()); + break; + case Cell.CELL_TYPE_BOOLEAN: + assertEquals(msg, Cell.CELL_TYPE_BOOLEAN, actValue.getCellType()); + assertEquals(msg, expValue.getBooleanCellValue(), actValue.getBooleanValue()); + break; + case Cell.CELL_TYPE_ERROR: + assertEquals(msg, Cell.CELL_TYPE_ERROR, actValue.getCellType()); +// if(false) { // TODO: fix ~45 functions which are currently returning incorrect error values +// assertEquals(msg, expValue.getErrorCellValue(), actValue.getErrorValue()); +// } + break; + case Cell.CELL_TYPE_FORMULA: // will never be used, since we will call method after formula evaluation + fail("Cannot expect formula as result of formula evaluation: " + msg); + case Cell.CELL_TYPE_NUMERIC: + assertEquals(msg, Cell.CELL_TYPE_NUMERIC, actValue.getCellType()); + TestMathX.assertEquals(msg, expValue.getNumericCellValue(), actValue.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR); +// double delta = Math.abs(expValue.getNumericCellValue()-actValue.getNumberValue()); +// double pctExpValue = Math.abs(0.00001*expValue.getNumericCellValue()); +// assertTrue(msg, delta <= pctExpValue); + break; + case Cell.CELL_TYPE_STRING: + assertEquals(msg, Cell.CELL_TYPE_STRING, actValue.getCellType()); + assertEquals(msg, expValue.getRichStringCellValue().getString(), actValue.getStringValue()); + break; + } } - return result; } /* @@ -301,40 +245,6 @@ public final class TestFormulaEvaluatorOnXSSF extends TestCase { return false; } - - /** - * Useful to keep output concise when expecting many failures to be reported by this test case - */ - private static void printShortStackTrace(PrintStream ps, Throwable e) { - StackTraceElement[] stes = e.getStackTrace(); - - int startIx = 0; - // skip any top frames inside junit.framework.Assert - while(startIx= endIx) { - // something went wrong. just print the whole stack trace - e.printStackTrace(ps); - } - endIx -= 4; // skip 4 frames of reflection invocation - ps.println(e.toString()); - for(int i=startIx; inull if cell is missing, empty or blank */ @@ -355,7 +265,7 @@ public final class TestFormulaEvaluatorOnXSSF extends TestCase { return cell.getRichStringCellValue().getString(); } - throw new AssertionFailedError("Bad cell type for 'function name' column: (" - + cell.getCellType() + ") row (" + (r.getRowNum() +1) + ")"); + fail("Bad cell type for 'function name' column: ("+cell.getColumnIndex()+") row ("+(r.getRowNum()+1)+")"); + return null; } } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestUnfixedBugs.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestUnfixedBugs.java index bea8e7129..c9bcdc025 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestUnfixedBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestUnfixedBugs.java @@ -17,6 +17,12 @@ package org.apache.poi.xssf.usermodel; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; @@ -25,10 +31,6 @@ import java.io.OutputStream; import java.nio.charset.Charset; import java.util.Calendar; import java.util.Date; -import java.util.GregorianCalendar; -import java.util.Locale; - -import junit.framework.TestCase; import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.ss.usermodel.Cell; @@ -42,6 +44,7 @@ import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellUtil; import org.apache.poi.ss.util.RegionUtil; +import org.apache.poi.util.LocaleUtil; import org.apache.poi.xssf.SXSSFITestDataProvider; import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.streaming.SXSSFWorkbook; @@ -57,7 +60,8 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow; * Bugzilla id's PLEASE MOVE tests from this class to TestBugs once the bugs are * fixed, so that they are then run automatically. */ -public final class TestUnfixedBugs extends TestCase { +public final class TestUnfixedBugs { + @Test public void testBug54084Unicode() throws IOException { // sample XLSX with the same text-contents as the text-file above XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("54084 - Greek - beyond BMP.xlsx"); @@ -76,8 +80,14 @@ public final class TestUnfixedBugs extends TestCase { verifyBug54084Unicode(wbWritten); // finally also write it out via the streaming interface and verify that we still can read it back in - Workbook wbStreamingWritten = SXSSFITestDataProvider.instance.writeOutAndReadBack(new SXSSFWorkbook(wb)); + SXSSFWorkbook swb = new SXSSFWorkbook(wb); + Workbook wbStreamingWritten = SXSSFITestDataProvider.instance.writeOutAndReadBack(swb); verifyBug54084Unicode(wbStreamingWritten); + + wbWritten.close(); + swb.close(); + wbStreamingWritten.close(); + wb.close(); } private void verifyBug54084Unicode(Workbook wb) { @@ -95,7 +105,8 @@ public final class TestUnfixedBugs extends TestCase { assertEquals("The data in the text-file should exactly match the data that we read from the workbook", testData, value); } - public void test54071() { + @Test + public void test54071() throws Exception { Workbook workbook = XSSFTestDataSamples.openSampleWorkbook("54071.xlsx"); Sheet sheet = workbook.getSheetAt(0); int rows = sheet.getPhysicalNumberOfRows(); @@ -120,8 +131,11 @@ public final class TestUnfixedBugs extends TestCase { } } } + + workbook.close(); } + @Test public void test54071Simple() { double value1 = 41224.999988425923; double value2 = 41224.999988368058; @@ -143,15 +157,13 @@ public final class TestUnfixedBugs extends TestCase { // second to be different here! int startYear = 1900; int dayAdjust = -1; // Excel thinks 2/29/1900 is a valid date, which it isn't - Calendar calendar1 = new GregorianCalendar(Locale.ROOT); - calendar1.set(startYear,0, wholeDays1 + dayAdjust, 0, 0, 0); + Calendar calendar1 = LocaleUtil.getLocaleCalendar(startYear,0, wholeDays1 + dayAdjust); calendar1.set(Calendar.MILLISECOND, millisecondsInDay1); // this is the rounding part: calendar1.add(Calendar.MILLISECOND, 500); calendar1.clear(Calendar.MILLISECOND); - Calendar calendar2 = new GregorianCalendar(Locale.ROOT); - calendar2.set(startYear,0, wholeDays2 + dayAdjust, 0, 0, 0); + Calendar calendar2 = LocaleUtil.getLocaleCalendar(startYear,0, wholeDays2 + dayAdjust); calendar2.set(Calendar.MILLISECOND, millisecondsInDay2); // this is the rounding part: calendar2.add(Calendar.MILLISECOND, 500); @@ -163,7 +175,8 @@ public final class TestUnfixedBugs extends TestCase { assertEquals(DateUtil.getJavaDate(value1, false), DateUtil.getJavaDate(value2, false)); } - public void test57236() { + @Test + public void test57236() throws Exception { // Having very small numbers leads to different formatting, Excel uses the scientific notation, but POI leads to "0" /* @@ -189,10 +202,12 @@ public final class TestUnfixedBugs extends TestCase { } } } + wb.close(); } // When this is fixed, the test case should go to BaseTestXCell with // adjustments to use _testDataProvider to also verify this for XSSF + @Test public void testBug57294() throws IOException { Workbook wb = SXSSFITestDataProvider.instance.createWorkbook(); @@ -217,6 +232,8 @@ public final class TestUnfixedBugs extends TestCase { assertEquals(0, strBack.getIndexOfFormattingRun(0)); assertEquals(2, strBack.getIndexOfFormattingRun(1)); assertEquals(4, strBack.getIndexOfFormattingRun(2)); + + wbBack.close(); } @Test diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java index f487726c9..d6f573c1c 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java @@ -38,6 +38,7 @@ import java.util.Calendar; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TimeZone; import java.util.TreeMap; import org.apache.poi.EncryptedDocumentException; @@ -85,6 +86,7 @@ import org.apache.poi.ss.usermodel.WorkbookFactory; import org.apache.poi.ss.util.AreaReference; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellReference; +import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.TempFile; import org.apache.poi.xssf.XLSBUnsupportedException; import org.apache.poi.xssf.XSSFITestDataProvider; @@ -120,7 +122,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { * the wrong sheet name */ @Test - public void bug45430() { + public void bug45430() throws Exception { XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("45430.xlsx"); assertFalse(wb.isMacroEnabled()); assertEquals(3, wb.getNumberOfNames()); @@ -144,6 +146,9 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { XSSFWorkbook nwb = XSSFTestDataSamples.writeOutAndReadBack(wb); assertEquals(3, nwb.getNumberOfNames()); assertEquals("SheetA!$A$1", nwb.getNameAt(0).getRefersToFormula()); + + nwb.close(); + wb.close(); } /** @@ -151,69 +156,79 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { */ @Test public void bug45431() throws Exception { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("45431.xlsm"); - OPCPackage pkg = wb.getPackage(); - assertTrue(wb.isMacroEnabled()); + XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("45431.xlsm"); + OPCPackage pkg1 = wb1.getPackage(); + assertTrue(wb1.isMacroEnabled()); // Check the various macro related bits can be found - PackagePart vba = pkg.getPart( + PackagePart vba = pkg1.getPart( PackagingURIHelper.createPartName("/xl/vbaProject.bin") ); assertNotNull(vba); // And the drawing bit - PackagePart drw = pkg.getPart( + PackagePart drw = pkg1.getPart( PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml") ); assertNotNull(drw); // Save and re-open, both still there - XSSFWorkbook nwb = XSSFTestDataSamples.writeOutAndReadBack(wb); - OPCPackage nPkg = nwb.getPackage(); - assertTrue(nwb.isMacroEnabled()); + XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); + pkg1.close(); + wb1.close(); - vba = nPkg.getPart( + OPCPackage pkg2 = wb2.getPackage(); + assertTrue(wb2.isMacroEnabled()); + + vba = pkg2.getPart( PackagingURIHelper.createPartName("/xl/vbaProject.bin") ); assertNotNull(vba); - drw = nPkg.getPart( + drw = pkg2.getPart( PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml") ); assertNotNull(drw); // And again, just to be sure - nwb = XSSFTestDataSamples.writeOutAndReadBack(nwb); - nPkg = nwb.getPackage(); - assertTrue(nwb.isMacroEnabled()); + XSSFWorkbook wb3 = XSSFTestDataSamples.writeOutAndReadBack(wb2); + pkg2.close(); + wb2.close(); + OPCPackage pkg3 = wb3.getPackage(); + assertTrue(wb3.isMacroEnabled()); - vba = nPkg.getPart( + vba = pkg3.getPart( PackagingURIHelper.createPartName("/xl/vbaProject.bin") ); assertNotNull(vba); - drw = nPkg.getPart( + drw = pkg3.getPart( PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml") ); assertNotNull(drw); + + pkg3.close(); + wb3.close(); } @Test - public void bug47504() { - XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("47504.xlsx"); - assertEquals(1, wb.getNumberOfSheets()); - XSSFSheet sh = wb.getSheetAt(0); + public void bug47504() throws Exception { + XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("47504.xlsx"); + assertEquals(1, wb1.getNumberOfSheets()); + XSSFSheet sh = wb1.getSheetAt(0); XSSFDrawing drawing = sh.createDrawingPatriarch(); List rels = drawing.getRelations(); assertEquals(1, rels.size()); assertEquals("Sheet1!A1", rels.get(0).getPackageRelationship().getTargetURI().getFragment()); // And again, just to be sure - wb = XSSFTestDataSamples.writeOutAndReadBack(wb); - assertEquals(1, wb.getNumberOfSheets()); - sh = wb.getSheetAt(0); + XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); + wb1.close(); + assertEquals(1, wb2.getNumberOfSheets()); + sh = wb2.getSheetAt(0); drawing = sh.createDrawingPatriarch(); rels = drawing.getRelations(); assertEquals(1, rels.size()); assertEquals("Sheet1!A1", rels.get(0).getPackageRelationship().getTargetURI().getFragment()); + wb2.close(); } /** @@ -224,7 +239,8 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { */ @Test public void bug49020() throws Exception { - /*XSSFWorkbook wb =*/ XSSFTestDataSamples.openSampleWorkbook("BrNotClosed.xlsx"); + XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("BrNotClosed.xlsx"); + wb.close(); } /** @@ -235,11 +251,12 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("49325.xlsx"); CTWorksheet sh = wb.getSheetAt(0).getCTWorksheet(); assertNotNull(sh.getPhoneticPr()); + wb.close(); } /** * Names which are defined with a Sheet - * should return that sheet index properly + * should return that sheet index properly */ @Test public void bug48923() throws Exception { @@ -270,6 +287,8 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertEquals("Test", test.getNameName()); assertEquals("Sheet1", test.getSheetName()); assertEquals(-1, test.getSheetIndex()); + + wb.close(); } /** @@ -277,49 +296,53 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { * NameXPtgs. * Blows up on: * IF(B6= (ROUNDUP(B6,0) + ROUNDDOWN(B6,0))/2, MROUND(B6,2),ROUND(B6,0)) - * + * * TODO: delete this test case when MROUND and VAR are implemented */ @Test public void bug48539() throws Exception { XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48539.xlsx"); - assertEquals(3, wb.getNumberOfSheets()); - assertEquals(0, wb.getNumberOfNames()); + try { + assertEquals(3, wb.getNumberOfSheets()); + assertEquals(0, wb.getNumberOfNames()); - // Try each cell individually - XSSFFormulaEvaluator eval = new XSSFFormulaEvaluator(wb); - for(int i=0; i assertEquals(0.0, cell.getNumericCellValue(), 0.001); - + // Try to format DataFormatter formatter = new DataFormatter(); formatter.formatCellValue(cell); - + // Check the formatting assertEquals("0", formatter.formatCellValue(cell)); + wb.close(); } - + /** * Formulas which reference named ranges, either in other * sheets, or workbook scoped but in other workbooks. * Used to fail with with errors like * org.apache.poi.ss.formula.FormulaParseException: Cell reference expected after sheet name at index 9 - * org.apache.poi.ss.formula.FormulaParseException: Parse error near char 0 '[' in specified formula '[0]!NR_Global_B2'. Expected number, string, or defined name + * org.apache.poi.ss.formula.FormulaParseException: Parse error near char 0 '[' in specified formula '[0]!NR_Global_B2'. Expected number, string, or defined name */ @Test public void bug56737() throws IOException { Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56737.xlsx"); - + // Check the named range definitions Name nSheetScope = wb.getName("NR_To_A1"); Name nWBScope = wb.getName("NR_Global_B2"); assertNotNull(nSheetScope); assertNotNull(nWBScope); - + assertEquals("Defines!$A$1", nSheetScope.getRefersToFormula()); assertEquals("Defines!$B$2", nWBScope.getRefersToFormula()); - + // Check the different kinds of formulas Sheet s = wb.getSheetAt(0); Cell cRefSName = s.getRow(1).getCell(3); Cell cRefWName = s.getRow(2).getCell(3); - + assertEquals("Defines!NR_To_A1", cRefSName.getCellFormula()); // Note the formula, as stored in the file, has the external name index not filename // TODO Provide a way to get the one with the filename assertEquals("[0]!NR_Global_B2", cRefWName.getCellFormula()); - + // Try to evaluate them FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator(); assertEquals("Test A1", eval.evaluate(cRefSName).getStringValue()); assertEquals(142, (int)eval.evaluate(cRefWName).getNumberValue()); - + // Try to evaluate everything eval.evaluateAll(); + wb.close(); } private void saveAndReloadReport(Workbook wb, File outFile) throws IOException { @@ -1704,40 +1799,45 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { is.close(); } } - + @Test - public void testBug56688_1() { + public void testBug56688_1() throws Exception { XSSFWorkbook excel = XSSFTestDataSamples.openSampleWorkbook("56688_1.xlsx"); checkValue(excel, "-1.0"); /* Not 0.0 because POI sees date "0" minus one month as invalid date, which is -1! */ + excel.close(); } - + @Test - public void testBug56688_2() { + public void testBug56688_2() throws Exception { XSSFWorkbook excel = XSSFTestDataSamples.openSampleWorkbook("56688_2.xlsx"); checkValue(excel, "#VALUE!"); + excel.close(); } - + @Test - public void testBug56688_3() { + public void testBug56688_3() throws Exception { XSSFWorkbook excel = XSSFTestDataSamples.openSampleWorkbook("56688_3.xlsx"); checkValue(excel, "#VALUE!"); + excel.close(); } - + @Test - public void testBug56688_4() { + public void testBug56688_4() throws Exception { XSSFWorkbook excel = XSSFTestDataSamples.openSampleWorkbook("56688_4.xlsx"); - - Calendar calendar = Calendar.getInstance(); + + Calendar calendar = LocaleUtil.getLocaleCalendar(); calendar.add(Calendar.MONTH, 2); double excelDate = DateUtil.getExcelDate(calendar.getTime()); NumberEval eval = new NumberEval(Math.floor(excelDate)); checkValue(excel, eval.getStringValue() + ".0"); + + excel.close(); } - + /** * New hyperlink with no initial cell reference, still need * to be able to change it - * @throws IOException + * @throws IOException */ @Test public void testBug56527() throws IOException { @@ -1745,7 +1845,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { XSSFSheet sheet = wb.createSheet(); XSSFCreationHelper creationHelper = wb.getCreationHelper(); XSSFHyperlink hyperlink; - + // Try with a cell reference hyperlink = creationHelper.createHyperlink(Hyperlink.LINK_URL); sheet.addHyperlink(hyperlink); @@ -1755,56 +1855,57 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertEquals(1, hyperlink.getFirstColumn()); assertEquals(3, hyperlink.getLastRow()); assertEquals(1, hyperlink.getLastColumn()); - + // Try with explicit rows / columns hyperlink = creationHelper.createHyperlink(Hyperlink.LINK_URL); sheet.addHyperlink(hyperlink); hyperlink.setAddress("http://myurl"); hyperlink.setFirstRow(5); hyperlink.setFirstColumn(3); - + assertEquals(5, hyperlink.getFirstRow()); assertEquals(3, hyperlink.getFirstColumn()); assertEquals(5, hyperlink.getLastRow()); assertEquals(3, hyperlink.getLastColumn()); wb.close(); } - + /** - * Shifting rows with a formula that references a + * Shifting rows with a formula that references a * function in another file */ @Test public void bug56502() throws Exception { Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56502.xlsx"); Sheet sheet = wb.getSheetAt(0); - + Cell cFunc = sheet.getRow(3).getCell(0); assertEquals("[1]!LUCANET(\"Ist\")", cFunc.getCellFormula()); Cell cRef = sheet.getRow(3).createCell(1); cRef.setCellFormula("A3"); - + // Shift it down one row sheet.shiftRows(1, sheet.getLastRowNum(), 1); - + // Check the new formulas: Function won't change, Reference will cFunc = sheet.getRow(4).getCell(0); assertEquals("[1]!LUCANET(\"Ist\")", cFunc.getCellFormula()); cRef = sheet.getRow(4).getCell(1); assertEquals("A4", cRef.getCellFormula()); + wb.close(); } - + @Test public void bug54764() throws Exception { OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("54764.xlsx"); - + // Check the core properties - will be found but empty, due // to the expansion being too much to be considered valid POIXMLProperties props = new POIXMLProperties(pkg); assertEquals(null, props.getCoreProperties().getTitle()); assertEquals(null, props.getCoreProperties().getSubject()); assertEquals(null, props.getCoreProperties().getDescription()); - + // Now check the spreadsheet itself try { new XSSFWorkbook(pkg).close(); @@ -1812,20 +1913,22 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { } catch(POIXMLException e) { // Expected } - + pkg.close(); + // Try with one with the entities in the Content Types try { - XSSFTestDataSamples.openSamplePackage("54764-2.xlsx"); + XSSFTestDataSamples.openSamplePackage("54764-2.xlsx").close(); fail("Should fail as too much expansion occurs"); } catch(Exception e) { // Expected } - + // Check we can still parse valid files after all that Workbook wb = XSSFTestDataSamples.openSampleWorkbook("sample.xlsx"); assertEquals(3, wb.getNumberOfSheets()); + wb.close(); } - + /** * CTDefinedNamesImpl should be included in the smaller * poi-ooxml-schemas jar @@ -1840,8 +1943,9 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertNotNull(defName.getStringValue()); } assertEquals("TestDefinedName", definedNameList.get(0).getName()); + wb.close(); } - + /** * .xlsb files are not supported, but we should generate a helpful * error message if given one @@ -1850,7 +1954,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { public void bug56800_xlsb() throws Exception { // Can be opened at the OPC level OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("Simple.xlsb"); - + // XSSF Workbook gives helpful error try { new XSSFWorkbook(pkg).close(); @@ -1858,35 +1962,37 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { } catch (XLSBUnsupportedException e) { // Good, detected and warned } - + // Workbook Factory gives helpful error on package try { - WorkbookFactory.create(pkg); + WorkbookFactory.create(pkg).close(); fail(".xlsb files not supported"); } catch (XLSBUnsupportedException e) { // Good, detected and warned } - + // Workbook Factory gives helpful error on file File xlsbFile = HSSFTestDataSamples.getSampleFile("Simple.xlsb"); try { - WorkbookFactory.create(xlsbFile); + WorkbookFactory.create(xlsbFile).close(); fail(".xlsb files not supported"); } catch (XLSBUnsupportedException e) { // Good, detected and warned } + + pkg.close(); } private void checkValue(XSSFWorkbook excel, String expect) { XSSFFormulaEvaluator evaluator = new XSSFFormulaEvaluator(excel); evaluator.evaluateAll(); - + XSSFCell cell = excel.getSheetAt(0).getRow(1).getCell(1); CellValue value = evaluator.evaluate(cell); - + assertEquals(expect, value.formatAsString()); } - + @Test public void testBug57196() throws IOException { Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57196.xlsx"); @@ -1899,9 +2005,9 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { // fileOutput.close(); wb.close(); } - + @Test - public void test57196_Detail() { + public void test57196_Detail() throws Exception { XSSFWorkbook wb = new XSSFWorkbook(); XSSFSheet sheet = wb.createSheet("Sheet1"); XSSFRow row = sheet.createRow(0); @@ -1911,10 +2017,11 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { CellValue cv = fe.evaluate(cell); assertNotNull(cv); - } - + wb.close(); + } + @Test - public void test57196_Detail2() { + public void test57196_Detail2() throws Exception { XSSFWorkbook wb = new XSSFWorkbook(); XSSFSheet sheet = wb.createSheet("Sheet1"); XSSFRow row = sheet.createRow(0); @@ -1924,10 +2031,11 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { CellValue cv = fe.evaluate(cell); assertNotNull(cv); - } + wb.close(); + } @Test - public void test57196_WorkbookEvaluator() { + public void test57196_WorkbookEvaluator() throws Exception { String previousLogger = System.getProperty("org.apache.poi.util.POILogger"); //System.setProperty("org.apache.poi.util.POILogger", "org.apache.poi.util.SystemOutLogger"); //System.setProperty("poi.log.level", "3"); @@ -1944,15 +2052,15 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { // simple formula worked cell.setCellFormula("DEC2HEX(O2+D2)"); - + WorkbookEvaluator workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null); workbookEvaluator.setDebugEvaluationOutputForNextEval(true); workbookEvaluator.evaluate(new XSSFEvaluationCell(cell)); - + // this already failed! Hex2Dec did not correctly handle RefEval cell.setCellFormula("HEX2DEC(O8)"); workbookEvaluator.clearAllCachedResultValues(); - + workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null); workbookEvaluator.setDebugEvaluationOutputForNextEval(true); workbookEvaluator.evaluate(new XSSFEvaluationCell(cell)); @@ -1960,7 +2068,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { // slightly more complex one failed cell.setCellFormula("HEX2DEC(O8)-O2+D2"); workbookEvaluator.clearAllCachedResultValues(); - + workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null); workbookEvaluator.setDebugEvaluationOutputForNextEval(true); workbookEvaluator.evaluate(new XSSFEvaluationCell(cell)); @@ -1975,7 +2083,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { // what other similar functions cell.setCellFormula("DEC2BIN(O8)-O2+D2"); workbookEvaluator.clearAllCachedResultValues(); - + workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null); workbookEvaluator.setDebugEvaluationOutputForNextEval(true); workbookEvaluator.evaluate(new XSSFEvaluationCell(cell)); @@ -1983,7 +2091,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { // what other similar functions cell.setCellFormula("DEC2BIN(A1)"); workbookEvaluator.clearAllCachedResultValues(); - + workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null); workbookEvaluator.setDebugEvaluationOutputForNextEval(true); workbookEvaluator.evaluate(new XSSFEvaluationCell(cell)); @@ -1991,10 +2099,12 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { // what other similar functions cell.setCellFormula("BIN2DEC(B1)"); workbookEvaluator.clearAllCachedResultValues(); - + workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null); workbookEvaluator.setDebugEvaluationOutputForNextEval(true); workbookEvaluator.evaluate(new XSSFEvaluationCell(cell)); + + wb.close(); } finally { if(previousLogger == null) { System.clearProperty("org.apache.poi.util.POILogger"); @@ -2004,7 +2114,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { System.clearProperty("poi.log.level"); } } - + /** * A .xlsx file with no Shared Strings table should open fine * in read-only mode @@ -2022,17 +2132,17 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { XSSFWorkbook wb = new XSSFWorkbook(pkg); assertNotNull(wb.getSharedStringSource()); assertEquals(0, wb.getSharedStringSource().getCount()); - + DataFormatter fmt = new DataFormatter(); XSSFSheet s = wb.getSheetAt(0); assertEquals("1", fmt.formatCellValue(s.getRow(0).getCell(0))); assertEquals("11", fmt.formatCellValue(s.getRow(0).getCell(1))); assertEquals("5", fmt.formatCellValue(s.getRow(4).getCell(0))); - + // Add a text cell s.getRow(0).createCell(3).setCellValue("Testing"); assertEquals("Testing", fmt.formatCellValue(s.getRow(0).getCell(3))); - + // Try to write-out and read again, should only work // in read-write mode, not read-only mode try { @@ -2047,7 +2157,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { throw e; } } - + // Check again s = wb.getSheetAt(0); assertEquals("1", fmt.formatCellValue(s.getRow(0).getCell(0))); @@ -2059,7 +2169,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { } } } - + /** * "Unknown error type: -60" fetching formula error value */ @@ -2068,20 +2178,22 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57535.xlsx"); FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); evaluator.clearAllCachedResultValues(); - + Sheet sheet = wb.getSheet("Sheet1"); Cell cell = sheet.getRow(5).getCell(4); assertEquals(Cell.CELL_TYPE_FORMULA, cell.getCellType()); assertEquals("E4+E5", cell.getCellFormula()); - + CellValue value = evaluator.evaluate(cell); assertEquals(Cell.CELL_TYPE_ERROR, value.getCellType()); assertEquals(-60, value.getErrorValue()); assertEquals("~CIRCULAR~REF~", FormulaError.forInt(value.getErrorValue()).getString()); assertEquals("CIRCULAR_REF", FormulaError.forInt(value.getErrorValue()).toString()); + + wb.close(); } - + @Test public void test57165() throws IOException { XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57171_57163_57165.xlsx"); @@ -2090,10 +2202,10 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { wb.cloneSheet(0); // Throws exception here wb.setSheetName(1, "New Sheet"); //saveWorkbook(wb, fileName); - + XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb); try { - + } finally { wbBack.close(); } @@ -2110,10 +2222,10 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { wb.createSheet("newsheet"); // Throws exception here wb.setSheetName(1, "New Sheet"); //saveWorkbook(wb, fileName); - + XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb); try { - + } finally { wbBack.close(); } @@ -2208,14 +2320,14 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { wb.close(); } } - + @Test public void test56467() throws IOException { Workbook wb = XSSFTestDataSamples.openSampleWorkbook("picture.xlsx"); try { Sheet orig = wb.getSheetAt(0); assertNotNull(orig); - + Sheet sheet = wb.cloneSheet(0); Drawing drawing = sheet.createDrawingPatriarch(); for (XSSFShape shape : ((XSSFDrawing) drawing).getShapes()) { @@ -2224,7 +2336,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertNotNull(pictureData); } } - + // OutputStream out = new FileOutputStream("/tmp/56467.xls"); // try { // wb.write(out); @@ -2235,7 +2347,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { wb.close(); } } - + /** * OOXML-Strict files * Not currently working - namespace mis-match from XMLBeans @@ -2247,11 +2359,14 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertEquals(3, wb.getNumberOfSheets()); // TODO Check sheet contents // TODO Check formula evaluation - + XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb); assertEquals(3, wbBack.getNumberOfSheets()); // TODO Re-check sheet contents // TODO Re-check formula evaluation + + wb.close(); + wbBack.close(); } @Test @@ -2261,16 +2376,17 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { XSSFRow srcRow = sheet.getRow(0); XSSFCell oldCell = srcRow.getCell(0); XSSFCellStyle cellStyle = oldCell.getCellStyle(); - + checkStyle(cellStyle); - + // StylesTable table = xlsToAppendWorkbook.getStylesSource(); // List fills = table.getFills(); // System.out.println("Having " + fills.size() + " fills"); // for(XSSFCellFill fill : fills) { // System.out.println("Fill: " + fill.getFillBackgroundColor() + "/" + fill.getFillForegroundColor()); -// } - +// } + xlsToAppendWorkbook.close(); + XSSFWorkbook targetWorkbook = new XSSFWorkbook(); XSSFSheet newSheet = targetWorkbook.createSheet(sheet.getSheetName()); XSSFRow destRow = newSheet.createRow(0); @@ -2289,19 +2405,22 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { // } finally { // os.close(); // } - + XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(targetWorkbook); XSSFCellStyle styleBack = wbBack.getSheetAt(0).getRow(0).getCell(0).getCellStyle(); checkStyle(styleBack); + + targetWorkbook.close(); + wbBack.close(); } /** - * Paragraph with property BuFont but none of the properties + * Paragraph with property BuFont but none of the properties * BuNone, BuChar, and BuAutoNum, used to trigger a NPE * Excel treats this as not-bulleted, so now do we */ @Test - public void testBug57826() { + public void testBug57826() throws Exception { XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("57826.xlsx"); assertTrue("no sheets in workbook", workbook.getNumberOfSheets() >= 1); @@ -2321,6 +2440,8 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { // No bulleting info included assertEquals("test ok", text); + + workbook.close(); } private void checkStyle(XSSFCellStyle cellStyle) { @@ -2352,7 +2473,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertEquals("ISERROR(CSN!A1)", c.getCellFormula()); c = s.getRow(1).getCell(1); assertEquals("ISERROR(B2)", c.getCellFormula()); - + wb.close(); } @@ -2383,15 +2504,15 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { File tmp = TempFile.createTempFile("poi-test", ".bug57880"); OutputStream fos = new FileOutputStream(tmp); try { - wb.write(fos); + wb.write(fos); } finally { - fos.close(); + fos.close(); } - + wb.close(); fmt = null; /*s = null;*/ wb = null; // System.gc(); - + wb = new XSSFWorkbook(tmp); fmt = wb.getCreationHelper().createDataFormat(); // s = wb.getSheetAt(0); @@ -2427,7 +2548,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { data.put("3", new Object[] {1, "Lokesh", "Gupta"}); data.put("4", new Object[] {4, "John", "Adwards"}); data.put("5", new Object[] {2, "Brian", "Schultz"}); - + Set keyset = data.keySet(); int rownum = 1; for (String key : keyset) @@ -2475,14 +2596,14 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertFalse(calc.getR().equals("A5")); assertFalse(calc.getR().equals("A6")); } - + /*FileOutputStream out = new FileOutputStream(new File("C:\\temp\\56574.xlsx")); try { wb.write(out); } finally { out.close(); }*/ - + Workbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb); Sheet sheetBack = wbBack.getSheet("Func"); assertNotNull(sheetBack); @@ -2497,10 +2618,11 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertFalse(calc.getR().equals("A5")); assertFalse(calc.getR().equals("A6")); } - + + wbBack.close(); wb.close(); } - + /** * Excel 2007 generated Macro-Enabled .xlsm file */ @@ -2508,8 +2630,9 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { public void bug57181() throws Exception { XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57181.xlsm"); assertEquals(9, wb.getNumberOfSheets()); + wb.close(); } - + @Test public void bug52111() throws Exception { Workbook wb = XSSFTestDataSamples.openSampleWorkbook("Intersection-52111-xssf.xlsx"); @@ -2517,8 +2640,9 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertFormula(wb, s.getRow(2).getCell(0), "(C2:D3 D3:E4)", "4.0"); assertFormula(wb, s.getRow(6).getCell(0), "Tabelle2!E:E Tabelle2!11:11", "5.0"); assertFormula(wb, s.getRow(8).getCell(0), "Tabelle2!E:F Tabelle2!11:12", null); + wb.close(); } - + private void assertFormula(Workbook wb, Cell intF, String expectedFormula, String expectedResultOrNull) { assertEquals(Cell.CELL_TYPE_FORMULA, intF.getCellType()); if (null == expectedResultOrNull) { @@ -2528,7 +2652,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { else { assertEquals(Cell.CELL_TYPE_NUMERIC, intF.getCachedFormulaResultType()); } - + assertEquals(expectedFormula, intF.getCellFormula()); // Check we can evaluate it correctly @@ -2537,31 +2661,32 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { } @Test - public void test48962() { + public void test48962() throws Exception { Workbook wb = XSSFTestDataSamples.openSampleWorkbook("48962.xlsx"); Sheet sh = wb.getSheetAt(0); Row row = sh.getRow(1); Cell cell = row.getCell(0); - + CellStyle style = cell.getCellStyle(); assertNotNull(style); - + // color index assertEquals(64, style.getFillBackgroundColor()); XSSFColor color = ((XSSFCellStyle)style).getFillBackgroundXSSFColor(); assertNotNull(color); - + // indexed color assertEquals(64, color.getIndexed()); assertEquals(64, color.getIndex()); - + // not an RGB color assertFalse(color.isRGB()); - assertNull(color.getRGB()); + assertNull(color.getRGB()); + wb.close(); } - + @Test - public void test50755_workday_formula_example() { + public void test50755_workday_formula_example() throws Exception { Workbook wb = XSSFTestDataSamples.openSampleWorkbook("50755_workday_formula_example.xlsx"); Sheet sheet = wb.getSheet("Sheet1"); for(Row aRow : sheet) { @@ -2575,6 +2700,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertNotNull(cell.toString()); } } + wb.close(); } @Test @@ -2582,31 +2708,31 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { Workbook wb = XSSFTestDataSamples.openSampleWorkbook("51626.xlsx"); assertNotNull(wb); wb.close(); - + InputStream stream = HSSFTestDataSamples.openSampleFileStream("51626.xlsx"); wb = WorkbookFactory.create(stream); stream.close(); wb.close(); - + wb = XSSFTestDataSamples.openSampleWorkbook("51626_contact.xlsx"); assertNotNull(wb); wb.close(); - + stream = HSSFTestDataSamples.openSampleFileStream("51626_contact.xlsx"); wb = WorkbookFactory.create(stream); stream.close(); wb.close(); } - + @Test public void test51451() throws IOException { Workbook wb = new XSSFWorkbook(); Sheet sh = wb.createSheet(); - + Row row = sh.createRow(0); Cell cell = row.createCell(0); cell.setCellValue(239827342); - + CellStyle style = wb.createCellStyle(); //style.setHidden(false); DataFormat excelFormat = wb.createDataFormat(); @@ -2616,7 +2742,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { // FileOutputStream out = new FileOutputStream("/tmp/51451.xlsx"); // wb.write(out); // out.close(); - + wb.close(); } @@ -2624,7 +2750,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { public void test53105() throws IOException { Workbook wb = XSSFTestDataSamples.openSampleWorkbook("53105.xlsx"); assertNotNull(wb); - + // Act // evaluate SUM('Skye Lookup Input'!A4:XFD4), cells in range each contain "1" @@ -2633,7 +2759,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { // Assert assertEquals(16384.0, numericValue, 0.0); - + wb.close(); } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java index 1d020e9a3..c8a237d51 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java @@ -17,6 +17,11 @@ package org.apache.poi.xssf.usermodel; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + import java.io.IOException; import org.apache.poi.hssf.HSSFITestDataProvider; @@ -34,6 +39,7 @@ import org.apache.poi.xssf.SXSSFITestDataProvider; import org.apache.poi.xssf.XSSFITestDataProvider; import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.model.SharedStringsTable; +import org.junit.Test; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell; import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellType; @@ -50,6 +56,7 @@ public final class TestXSSFCell extends BaseTestXCell { * Bug 47026: trouble changing cell type when workbook doesn't contain * Shared String Table */ + @Test public void test47026_1() { Workbook source = _testDataProvider.openSampleWorkbook("47026.xlsm"); Sheet sheet = source.getSheetAt(0); @@ -59,6 +66,7 @@ public final class TestXSSFCell extends BaseTestXCell { cell.setCellValue("456"); } + @Test public void test47026_2() { Workbook source = _testDataProvider.openSampleWorkbook("47026.xlsm"); Sheet sheet = source.getSheetAt(0); @@ -75,6 +83,7 @@ public final class TestXSSFCell extends BaseTestXCell { * Some programs, for example, Microsoft Excel Driver for .xlsx insert inline string * instead of using the shared string table. See bug 47206 */ + @Test public void testInlineString() { XSSFWorkbook wb = (XSSFWorkbook)_testDataProvider.openSampleWorkbook("xlsx-jdbc.xlsx"); XSSFSheet sheet = wb.getSheetAt(0); @@ -99,6 +108,7 @@ public final class TestXSSFCell extends BaseTestXCell { /** * Bug 47278 - xsi:nil attribute for tag caused Excel 2007 to fail to open workbook */ + @Test public void test47278() { XSSFWorkbook wb = (XSSFWorkbook)_testDataProvider.createWorkbook(); Sheet sheet = wb.createSheet(); @@ -121,6 +131,7 @@ public final class TestXSSFCell extends BaseTestXCell { assertEquals(Cell.CELL_TYPE_BLANK, cell_1.getCellType()); } + @Test public void testFormulaString() throws IOException { XSSFWorkbook wb = (XSSFWorkbook)_testDataProvider.createWorkbook(); try { @@ -162,6 +173,7 @@ public final class TestXSSFCell extends BaseTestXCell { /** * Bug 47889: problems when calling XSSFCell.getStringCellValue() on a workbook created in Gnumeric */ + @Test public void test47889() { XSSFWorkbook wb = (XSSFWorkbook)_testDataProvider.openSampleWorkbook("47889.xlsx"); XSSFSheet sh = wb.getSheetAt(0); @@ -180,13 +192,14 @@ public final class TestXSSFCell extends BaseTestXCell { //try a numeric cell cell = sh.getRow(1).getCell(0); assertEquals(XSSFCell.CELL_TYPE_NUMERIC, cell.getCellType()); - assertEquals(1.0, cell.getNumericCellValue()); + assertEquals(1.0, cell.getNumericCellValue(), 0); assertEquals("1.0", cell.toString()); //Gnumeric produces spreadsheets without styles //make sure we return null for that instead of throwing OutOfBounds assertEquals(null, cell.getCellStyle()); } + @Test public void testMissingRAttribute() { XSSFWorkbook wb = new XSSFWorkbook(); XSSFSheet sheet = wb.createSheet(); @@ -238,6 +251,7 @@ public final class TestXSSFCell extends BaseTestXCell { assertEquals("F1", a6.getReference()); } + @Test public void testMissingRAttributeBug54288() { // workbook with cells missing the R attribute XSSFWorkbook wb = (XSSFWorkbook)_testDataProvider.openSampleWorkbook("54288.xlsx"); @@ -278,6 +292,7 @@ public final class TestXSSFCell extends BaseTestXCell { } } + @Test public void test56170() throws IOException { final Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56170.xlsx"); final XSSFSheet sheet = (XSSFSheet) wb.getSheetAt(0); @@ -326,6 +341,7 @@ public final class TestXSSFCell extends BaseTestXCell { stream.close();*/ } + @Test public void test56170Reproduce() throws IOException { final Workbook wb = new XSSFWorkbook(); try { @@ -370,6 +386,7 @@ public final class TestXSSFCell extends BaseTestXCell { } } + @Test public void testBug56644ReturnNull() throws IOException { Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56644.xlsx"); try { @@ -382,6 +399,7 @@ public final class TestXSSFCell extends BaseTestXCell { } } + @Test public void testBug56644ReturnBlank() throws IOException { Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56644.xlsx"); try { @@ -394,6 +412,7 @@ public final class TestXSSFCell extends BaseTestXCell { } } + @Test public void testBug56644CreateBlank() throws IOException { Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56644.xlsx"); try { @@ -406,6 +425,7 @@ public final class TestXSSFCell extends BaseTestXCell { } } + @Test public void testEncodingbeloAscii(){ StringBuffer sb = new StringBuffer(); // test all possible characters diff --git a/src/resources/devtools/forbidden-signatures.txt b/src/resources/devtools/forbidden-signatures.txt new file mode 100644 index 000000000..de6afc337 --- /dev/null +++ b/src/resources/devtools/forbidden-signatures.txt @@ -0,0 +1,25 @@ +# (C) Copyright Uwe Schindler (Generics Policeman) and others. +# Parts of this work are licensed to the Apache Software Foundation (ASF) +# under one or more contributor license agreements. +# +# 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. +# +# This file contains API signatures which are specific to POI. +# The goal is to minimize implicit defaults + +@ignoreUnresolvable +@defaultMessage POI forbidden APIs + +java.util.Locale#getDefault() +java.util.Locale#setDefault(java.util.Locale) +java.util.TimeZone#getDefault() \ No newline at end of file diff --git a/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFDateAttribute.java b/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFDateAttribute.java index 890845229..4616b46d7 100644 --- a/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFDateAttribute.java +++ b/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFDateAttribute.java @@ -21,12 +21,12 @@ import java.io.IOException; import java.io.InputStream; import java.util.Calendar; import java.util.Date; -import java.util.TimeZone; import org.apache.poi.hmef.Attachment; import org.apache.poi.hmef.HMEFMessage; import org.apache.poi.hpsf.Util; import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; @@ -53,7 +53,7 @@ public final class TNEFDateAttribute extends TNEFAttribute { ); } else if(data.length == 14) { // It's the 7 date fields. We think it's in UTC... - Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + Calendar c = LocaleUtil.getLocaleCalendar(LocaleUtil.TIMEZONE_UTC); c.set(Calendar.YEAR, LittleEndian.getUShort(data, 0)); c.set(Calendar.MONTH, LittleEndian.getUShort(data, 2) - 1); // Java months are 0 based! c.set(Calendar.DAY_OF_MONTH, LittleEndian.getUShort(data, 4)); @@ -61,7 +61,7 @@ public final class TNEFDateAttribute extends TNEFAttribute { c.set(Calendar.MINUTE, LittleEndian.getUShort(data, 8)); c.set(Calendar.SECOND, LittleEndian.getUShort(data, 10)); // The 7th field is day of week, which we don't require - c.set(Calendar.MILLISECOND, 0); // Not set in the file + c.clear(Calendar.MILLISECOND); // Not set in the file this.data = c.getTime(); } else { throw new IllegalArgumentException("Invalid date, found " + data.length + " bytes"); diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java b/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java index 02cb9154f..7ba654c02 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java @@ -63,6 +63,7 @@ import org.apache.poi.sl.usermodel.StrokeStyle; import org.apache.poi.sl.usermodel.VerticalAlignment; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; +import org.apache.poi.util.SuppressForbidden; /** * Translates Graphics2D calls into PowerPoint. @@ -1716,6 +1717,7 @@ public final class PPGraphics2D extends Graphics2D implements Cloneable { * @see java.awt.Graphics#getFontMetrics() */ @SuppressWarnings("deprecation") + @SuppressForbidden public FontMetrics getFontMetrics(Font f) { return Toolkit.getDefaultToolkit().getFontMetrics(f); } diff --git a/src/scratchpad/src/org/apache/poi/hslf/util/SystemTimeUtils.java b/src/scratchpad/src/org/apache/poi/hslf/util/SystemTimeUtils.java index a6ab1ba80..10b566a8b 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/util/SystemTimeUtils.java +++ b/src/scratchpad/src/org/apache/poi/hslf/util/SystemTimeUtils.java @@ -19,10 +19,9 @@ package org.apache.poi.hslf.util; import java.util.Calendar; import java.util.Date; -import java.util.GregorianCalendar; -import java.util.Locale; import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.LocaleUtil; /** * A helper class for dealing with SystemTime Structs, as defined at @@ -33,9 +32,6 @@ import org.apache.poi.util.LittleEndian; * - that the day of the week (0) starts on Sunday in SYSTEMTIME, and Monday in Calendar * It is also the case that this does not store the timezone, and no... it is not * stored as UTC either, but rather the local system time (yuck.) - * - * @author Daniel Noll - * @author Nick Burch */ public final class SystemTimeUtils { /** @@ -48,7 +44,7 @@ public final class SystemTimeUtils { * Get the date found in the byte array, as a java Data object */ public static Date getDate(byte[] data, int offset) { - Calendar cal = new GregorianCalendar(Locale.ROOT); + Calendar cal = LocaleUtil.getLocaleCalendar(); cal.set(Calendar.YEAR, LittleEndian.getShort(data,offset)); cal.set(Calendar.MONTH, LittleEndian.getShort(data,offset+2)-1); @@ -75,7 +71,7 @@ public final class SystemTimeUtils { * into the supplied byte array. */ public static void storeDate(Date date, byte[] dest, int offset) { - Calendar cal = new GregorianCalendar(); + Calendar cal = LocaleUtil.getLocaleCalendar(); cal.setTime(date); LittleEndian.putShort(dest, offset + 0, (short) cal.get(Calendar.YEAR)); diff --git a/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java b/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java index 6cc7b6fbb..e6d3e379d 100644 --- a/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java +++ b/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java @@ -81,7 +81,7 @@ public class MAPIMessage extends POIDocument { */ public MAPIMessage() { // TODO - make writing possible - super(new POIFSFileSystem()); + super(new NPOIFSFileSystem()); } @@ -91,7 +91,7 @@ public class MAPIMessage extends POIDocument { * @throws IOException */ public MAPIMessage(String filename) throws IOException { - this(new FileInputStream(new File(filename))); + this(new NPOIFSFileSystem(new File(filename))); } /** @@ -102,14 +102,6 @@ public class MAPIMessage extends POIDocument { public MAPIMessage(InputStream in) throws IOException { this(new NPOIFSFileSystem(in)); } - /** - * Constructor for reading MSG Files from a POIFS filesystem - * @param fs - * @throws IOException - */ - public MAPIMessage(POIFSFileSystem fs) throws IOException { - this(fs.getRoot()); - } /** * Constructor for reading MSG Files from a POIFS filesystem * @param fs diff --git a/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessageSubmissionChunk.java b/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessageSubmissionChunk.java index dd9ab9a5f..fa81d55f7 100644 --- a/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessageSubmissionChunk.java +++ b/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessageSubmissionChunk.java @@ -26,6 +26,7 @@ import java.util.regex.Pattern; import org.apache.poi.hsmf.datatypes.Types.MAPIType; import org.apache.poi.util.IOUtils; +import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; @@ -85,7 +86,7 @@ public class MessageSubmissionChunk extends Chunk { // Should be yymmddhhmmssZ Matcher m = datePatern.matcher(dateS); if(m.matches()) { - date = Calendar.getInstance(); + date = LocaleUtil.getLocaleCalendar(); // work around issues with dates like 1989, which appear as "89" here int year = Integer.parseInt(m.group(1)); @@ -96,7 +97,7 @@ public class MessageSubmissionChunk extends Chunk { date.set(Calendar.HOUR_OF_DAY, Integer.parseInt(m.group(4))); date.set(Calendar.MINUTE, Integer.parseInt(m.group(5))); date.set(Calendar.SECOND, Integer.parseInt(m.group(6))); - date.set(Calendar.MILLISECOND, 0); + date.clear(Calendar.MILLISECOND); } else { logger.log(POILogger.WARN, "Warning - unable to make sense of date " + dateS); } diff --git a/src/scratchpad/src/org/apache/poi/hsmf/datatypes/PropertyValue.java b/src/scratchpad/src/org/apache/poi/hsmf/datatypes/PropertyValue.java index e1f9ba3fc..a22927c7b 100644 --- a/src/scratchpad/src/org/apache/poi/hsmf/datatypes/PropertyValue.java +++ b/src/scratchpad/src/org/apache/poi/hsmf/datatypes/PropertyValue.java @@ -19,9 +19,9 @@ package org.apache.poi.hsmf.datatypes; import java.math.BigInteger; import java.util.Calendar; -import java.util.TimeZone; import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.LocaleUtil; /** * An instance of a {@link MAPIProperty} inside a {@link PropertiesChunk}. @@ -218,7 +218,7 @@ public class PropertyValue { long time = LittleEndian.getLong(data); time = (time / 10 / 1000) - OFFSET; - Calendar timeC = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + Calendar timeC = LocaleUtil.getLocaleCalendar(); timeC.setTimeInMillis(time); return timeC; diff --git a/src/scratchpad/src/org/apache/poi/hsmf/dev/HSMFDump.java b/src/scratchpad/src/org/apache/poi/hsmf/dev/HSMFDump.java index 5f72fabf2..056680176 100644 --- a/src/scratchpad/src/org/apache/poi/hsmf/dev/HSMFDump.java +++ b/src/scratchpad/src/org/apache/poi/hsmf/dev/HSMFDump.java @@ -17,7 +17,7 @@ package org.apache.poi.hsmf.dev; -import java.io.FileInputStream; +import java.io.File; import java.io.IOException; import java.io.PrintStream; @@ -27,14 +27,14 @@ import org.apache.poi.hsmf.datatypes.MAPIProperty; import org.apache.poi.hsmf.datatypes.PropertiesChunk; import org.apache.poi.hsmf.datatypes.PropertyValue; import org.apache.poi.hsmf.parsers.POIFSChunkParser; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; /** * Dumps out the chunk details, and where possible contents */ public class HSMFDump { - private POIFSFileSystem fs; - public HSMFDump(POIFSFileSystem fs) { + private NPOIFSFileSystem fs; + public HSMFDump(NPOIFSFileSystem fs) { this.fs = fs; } @@ -84,9 +84,10 @@ public class HSMFDump { public static void main(String[] args) throws Exception { for(String file : args) { - POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(file)); + NPOIFSFileSystem fs = new NPOIFSFileSystem(new File(file), true); HSMFDump dump = new HSMFDump(fs); dump.dump(); + fs.close(); } } } diff --git a/src/scratchpad/src/org/apache/poi/hsmf/extractor/OutlookTextExtactor.java b/src/scratchpad/src/org/apache/poi/hsmf/extractor/OutlookTextExtactor.java index 69e726f0f..be396f3b0 100644 --- a/src/scratchpad/src/org/apache/poi/hsmf/extractor/OutlookTextExtactor.java +++ b/src/scratchpad/src/org/apache/poi/hsmf/extractor/OutlookTextExtactor.java @@ -21,7 +21,6 @@ import java.io.IOException; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Locale; -import java.util.TimeZone; import org.apache.poi.POIOLE2TextExtractor; import org.apache.poi.hsmf.MAPIMessage; @@ -31,6 +30,7 @@ import org.apache.poi.hsmf.exceptions.ChunkNotFoundException; import org.apache.poi.poifs.filesystem.DirectoryNode; import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.StringUtil.StringsIterator; /** @@ -51,9 +51,6 @@ public class OutlookTextExtactor extends POIOLE2TextExtractor { public OutlookTextExtactor(DirectoryNode poifsDir) throws IOException { this(new MAPIMessage(poifsDir)); } - public OutlookTextExtactor(POIFSFileSystem fs) throws IOException { - this(new MAPIMessage(fs)); - } public OutlookTextExtactor(NPOIFSFileSystem fs) throws IOException { this(new MAPIMessage(fs)); } @@ -63,11 +60,16 @@ public class OutlookTextExtactor extends POIOLE2TextExtractor { public static void main(String[] args) throws Exception { for(String filename : args) { - OutlookTextExtactor extractor = new OutlookTextExtactor( - new NPOIFSFileSystem(new File(filename)) - ); - System.out.println( extractor.getText() ); - extractor.close(); + NPOIFSFileSystem poifs = null; + OutlookTextExtactor extractor = null; + try { + poifs = new NPOIFSFileSystem(new File(filename)); + extractor = new OutlookTextExtactor(poifs); + System.out.println( extractor.getText() ); + } finally { + if (extractor != null) extractor.close(); + if (poifs != null) poifs.close(); + } } } @@ -120,8 +122,8 @@ public class OutlookTextExtactor extends POIOLE2TextExtractor { // Date - try two ways to find it try { // First try via the proper chunk - SimpleDateFormat f = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss Z"); - f.setTimeZone(TimeZone.getTimeZone("UTC")); + SimpleDateFormat f = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss Z", Locale.ROOT); + f.setTimeZone(LocaleUtil.getUserTimeZone()); s.append("Date: " + f.format(msg.getMessageDate().getTime()) + "\n"); } catch(ChunkNotFoundException e) { try { diff --git a/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java b/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java index cac6c551c..c44f4947f 100644 --- a/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java +++ b/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java @@ -40,7 +40,7 @@ import org.apache.poi.poifs.filesystem.DirectoryNode; import org.apache.poi.poifs.filesystem.DocumentInputStream; import org.apache.poi.poifs.filesystem.DocumentNode; import org.apache.poi.poifs.filesystem.Entry; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; @@ -52,7 +52,7 @@ import org.apache.poi.util.POILogger; public final class POIFSChunkParser { private static POILogger logger = POILogFactory.getLogger(POIFSChunkParser.class); - public static ChunkGroup[] parse(POIFSFileSystem fs) throws IOException { + public static ChunkGroup[] parse(NPOIFSFileSystem fs) throws IOException { return parse(fs.getRoot()); } public static ChunkGroup[] parse(DirectoryNode node) throws IOException { @@ -205,12 +205,15 @@ public final class POIFSChunkParser { if(chunk != null) { if(entry instanceof DocumentNode) { + DocumentInputStream inp = null; try { - DocumentInputStream inp = new DocumentInputStream((DocumentNode)entry); + inp = new DocumentInputStream((DocumentNode)entry); chunk.readValue(inp); grouping.record(chunk); } catch(IOException e) { logger.log(POILogger.ERROR, "Error reading from part " + entry.getName() + " - " + e.toString()); + } finally { + if (inp != null) inp.close(); } } else { grouping.record(chunk); diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/PlexOfField.java b/src/scratchpad/src/org/apache/poi/hwpf/model/PlexOfField.java index c354b3ada..70e9fb1ce 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/PlexOfField.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/PlexOfField.java @@ -19,7 +19,7 @@ package org.apache.poi.hwpf.model; -import java.text.MessageFormat; +import java.util.Locale; import org.apache.poi.util.Internal; @@ -63,11 +63,9 @@ public class PlexOfField return fld; } - public String toString() - { - return MessageFormat.format( "[{0}, {1}) - FLD - 0x{2}; 0x{3}", - getFcStart(), getFcEnd(), - Integer.toHexString( 0xff & fld.getBoundaryType() ), - Integer.toHexString( 0xff & fld.getFlt() ) ); + public String toString() { + String str = String.format(Locale.ROOT, "[%d, %d) - FLD - 0x%x; 0x%x" + , getFcStart(), getFcEnd(), fld.getBoundaryType(), fld.getFlt()); + return str; } } diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/DateAndTime.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/DateAndTime.java index a9b2fd9da..b812b6667 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/DateAndTime.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/DateAndTime.java @@ -22,6 +22,7 @@ import java.util.Calendar; import org.apache.poi.util.BitField; import org.apache.poi.util.BitFieldFactory; import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.LocaleUtil; /** * This class is used to represent a date and time in a Word document. @@ -39,7 +40,7 @@ public final class DateAndTime private short _info2; private static final BitField _months = BitFieldFactory.getInstance(0xf); private static final BitField _years = BitFieldFactory.getInstance(0x1ff0); - private static final BitField _weekday = BitFieldFactory.getInstance(0xe000); + // private static final BitField _weekday = BitFieldFactory.getInstance(0xe000); public DateAndTime() { @@ -53,8 +54,7 @@ public final class DateAndTime public Calendar getDate() { // TODO Discover if the timezone is stored somewhere else or not - Calendar cal = Calendar.getInstance(); - cal.set( + Calendar cal = LocaleUtil.getLocaleCalendar( _years.getValue(_info2)+1900, _months.getValue(_info2)-1, _dom.getValue(_info), @@ -62,7 +62,6 @@ public final class DateAndTime _minutes.getValue(_info), 0 ); - cal.set(Calendar.MILLISECOND, 0); return cal; } diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestComment2000.java b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestComment2000.java index 0f7c30b06..4ceea41fe 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestComment2000.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestComment2000.java @@ -18,10 +18,19 @@ package org.apache.poi.hslf.record; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import java.io.ByteArrayOutputStream; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Locale; + +import org.apache.poi.util.LocaleUtil; +import org.junit.BeforeClass; +import org.junit.Test; /** * Tests that Comment2000 works properly. @@ -29,7 +38,7 @@ import java.util.Date; * * @author Nick Burch (nick at torchbox dot com) */ -public final class TestComment2000 extends TestCase { +public final class TestComment2000 { // From a real file private byte[] data_a = new byte[] { 0x0F, 00, 0xE0-256, 0x2E, 0x9C-256, 00, 00, 00, @@ -82,22 +91,35 @@ public final class TestComment2000 extends TestCase { 0x0A, 00, 00, 00 }; - private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + private static SimpleDateFormat sdf; + + @BeforeClass + public static void initDateFormat() { + sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.ROOT); + sdf.setTimeZone(LocaleUtil.getUserTimeZone()); + } + @Test public void testRecordType() { Comment2000 ca = new Comment2000(data_a, 0, data_a.length); assertEquals(12000l, ca.getRecordType()); } - public void testAuthor() { + + @Test + public void testAuthor() { Comment2000 ca = new Comment2000(data_a, 0, data_a.length); assertEquals("Dumbledore", ca.getAuthor()); assertEquals("D", ca.getAuthorInitials()); } - public void testText() { + + @Test + public void testText() { Comment2000 ca = new Comment2000(data_a, 0, data_a.length); assertEquals("Yes, they certainly are, aren't they!", ca.getText()); } - public void testCommentAtom() throws Exception { + + @Test + public void testCommentAtom() throws Exception { Comment2000 ca = new Comment2000(data_a, 0, data_a.length); Comment2000Atom c2a = ca.getComment2000Atom(); @@ -107,7 +129,9 @@ public final class TestComment2000 extends TestCase { Date exp_a = sdf.parse("2006-01-24 10:26:15.205"); assertEquals(exp_a, c2a.getDate()); } - public void testCommentAtomB() throws Exception { + + @Test + public void testCommentAtomB() throws Exception { Comment2000 cb = new Comment2000(data_b, 0, data_b.length); Comment2000Atom c2b = cb.getComment2000Atom(); @@ -118,7 +142,8 @@ public final class TestComment2000 extends TestCase { assertEquals(exp_b, c2b.getDate()); } - public void testWrite() throws Exception { + @Test + public void testWrite() throws Exception { Comment2000 ca = new Comment2000(data_a, 0, data_a.length); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ca.writeOut(baos); @@ -131,7 +156,8 @@ public final class TestComment2000 extends TestCase { } // Change a few things - public void testChange() throws Exception { + @Test + public void testChange() throws Exception { Comment2000 ca = new Comment2000(data_a, 0, data_a.length); Comment2000 cb = new Comment2000(data_b, 0, data_b.length); Comment2000 cn = new Comment2000(); @@ -196,6 +222,7 @@ public final class TestComment2000 extends TestCase { /** * A Comment2000 records with missing commentTextAtom */ + @Test public void testBug44770() { byte[] data = { 0x0F, 0x00, (byte)0xE0, 0x2E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0xBA, 0x0F, diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestComment2000Atom.java b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestComment2000Atom.java index 0e5f946a5..26ca6dbb3 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestComment2000Atom.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestComment2000Atom.java @@ -18,17 +18,23 @@ package org.apache.poi.hslf.record; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; + import java.io.ByteArrayOutputStream; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Locale; + +import org.apache.poi.util.LocaleUtil; +import org.junit.BeforeClass; +import org.junit.Test; /** * Tests that Comment2000Atom works properly. * * @author Nick Burch (nick at torchbox dot com) */ -public final class TestComment2000Atom extends TestCase { +public final class TestComment2000Atom { // From a real file private byte[] data_a = new byte[] { 00, 00, 0xE1-256, 0x2E, 0x1C, 00, 00, 00, @@ -45,14 +51,22 @@ public final class TestComment2000Atom extends TestCase { 0x0E, 00, 00, 00 }; - private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + private static SimpleDateFormat sdf; + + @BeforeClass + public static void initDateFormat() { + sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.ROOT); + sdf.setTimeZone(LocaleUtil.getUserTimeZone()); + } + @Test public void testRecordType() { Comment2000Atom ca = new Comment2000Atom(data_a, 0, data_a.length); assertEquals(12001l, ca.getRecordType()); } - public void testGetDate() throws Exception { + @Test + public void testGetDate() throws Exception { Comment2000Atom ca = new Comment2000Atom(data_a, 0, data_a.length); Comment2000Atom cb = new Comment2000Atom(data_b, 0, data_b.length); @@ -65,7 +79,8 @@ public final class TestComment2000Atom extends TestCase { assertEquals(exp_b, cb.getDate()); } - public void testGetNums() { + @Test + public void testGetNums() { Comment2000Atom ca = new Comment2000Atom(data_a, 0, data_a.length); Comment2000Atom cb = new Comment2000Atom(data_b, 0, data_b.length); @@ -75,7 +90,8 @@ public final class TestComment2000Atom extends TestCase { assertEquals(5, cb.getNumber()); } - public void testGetPos() { + @Test + public void testGetPos() { Comment2000Atom ca = new Comment2000Atom(data_a, 0, data_a.length); Comment2000Atom cb = new Comment2000Atom(data_b, 0, data_b.length); @@ -88,7 +104,8 @@ public final class TestComment2000Atom extends TestCase { assertEquals(0x0E, cb.getYOffset()); } - public void testWrite() throws Exception { + @Test + public void testWrite() throws Exception { Comment2000Atom ca = new Comment2000Atom(data_a, 0, data_a.length); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ca.writeOut(baos); @@ -101,7 +118,8 @@ public final class TestComment2000Atom extends TestCase { } // Create A from scratch - public void testCreate() throws Exception { + @Test + public void testCreate() throws Exception { Comment2000Atom a = new Comment2000Atom(); // Set number, x and y @@ -125,7 +143,8 @@ public final class TestComment2000Atom extends TestCase { } // Try to turn a into b - public void testChange() throws Exception { + @Test + public void testChange() throws Exception { Comment2000Atom ca = new Comment2000Atom(data_a, 0, data_a.length); // Change the number diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/util/TestSystemTimeUtils.java b/src/scratchpad/testcases/org/apache/poi/hslf/util/TestSystemTimeUtils.java index 46a728469..1de83d997 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/util/TestSystemTimeUtils.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/util/TestSystemTimeUtils.java @@ -18,17 +18,22 @@ package org.apache.poi.hslf.util; +import static org.junit.Assert.assertEquals; + import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Locale; -import junit.framework.TestCase; +import org.apache.poi.util.LocaleUtil; +import org.junit.BeforeClass; +import org.junit.Test; /** * Tests that SystemTimeUtils works properly. * * @author Nick Burch (nick at torchbox dot com) */ -public final class TestSystemTimeUtils extends TestCase { +public final class TestSystemTimeUtils { // From real files private byte[] data_a = new byte[] { 0xD6-256, 07, 01, 00, @@ -43,9 +48,16 @@ public final class TestSystemTimeUtils extends TestCase { 0x0A, 00, 00, 00 }; - private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS"); + private static SimpleDateFormat sdf; + + @BeforeClass + public static void initDateFormat() { + sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.ROOT); + sdf.setTimeZone(LocaleUtil.getUserTimeZone()); + } - public void testGetDateA() throws Exception { + @Test + public void testGetDateA() throws Exception { Date date = SystemTimeUtils.getDate(data_a); // Is 2006-01-24 (2nd day of week) 10:26:15.205 @@ -54,6 +66,7 @@ public final class TestSystemTimeUtils extends TestCase { assertEquals(exp, date); } + @Test public void testGetDateB() throws Exception { Date date = SystemTimeUtils.getDate(data_b, 8+4); @@ -63,6 +76,7 @@ public final class TestSystemTimeUtils extends TestCase { assertEquals(exp, date); } + @Test public void testWriteDateA() throws Exception { byte[] out_a = new byte[data_a.length]; Date date = sdf.parse("2006-01-24 10:26:15.205"); @@ -73,6 +87,7 @@ public final class TestSystemTimeUtils extends TestCase { } } + @Test public void testWriteDateB() throws Exception { byte[] out_b = new byte[data_b.length]; // Copy over start and end, ignoring the 16 byte date field in the middle diff --git a/src/scratchpad/testcases/org/apache/poi/hsmf/AllHSMFTests.java b/src/scratchpad/testcases/org/apache/poi/hsmf/AllHSMFTests.java index 7664bddec..fc042c747 100644 --- a/src/scratchpad/testcases/org/apache/poi/hsmf/AllHSMFTests.java +++ b/src/scratchpad/testcases/org/apache/poi/hsmf/AllHSMFTests.java @@ -17,30 +17,28 @@ package org.apache.poi.hsmf; -import junit.framework.Test; -import junit.framework.TestSuite; - -import org.apache.poi.hsmf.datatypes.*; +import org.apache.poi.hsmf.datatypes.TestChunkData; +import org.apache.poi.hsmf.datatypes.TestSorters; +import org.apache.poi.hsmf.datatypes.TestTypes; import org.apache.poi.hsmf.extractor.TestOutlookTextExtractor; -import org.apache.poi.hsmf.parsers.*; +import org.apache.poi.hsmf.parsers.TestPOIFSChunkParser; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; -public final class AllHSMFTests { - public static Test suite() { - TestSuite suite = new TestSuite(AllHSMFTests.class.getName()); - - suite.addTestSuite(TestBasics.class); - suite.addTestSuite(TestBlankFileRead.class); - suite.addTestSuite(TestSimpleFileRead.class); - suite.addTestSuite(TestOutlook30FileRead.class); - suite.addTestSuite(TestFileWithAttachmentsRead.class); - suite.addTestSuite(TestChunkData.class); - suite.addTestSuite(TestTypes.class); - suite.addTestSuite(TestSorters.class); - suite.addTestSuite(TestOutlookTextExtractor.class); - suite.addTestSuite(TestPOIFSChunkParser.class); - suite.addTestSuite(TestMessageSubmissionChunkY2KRead.class); - suite.addTestSuite(TestMessageSubmissionChunk.class); - - return suite; - } +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TestBasics.class, + TestBlankFileRead.class, + TestSimpleFileRead.class, + TestOutlook30FileRead.class, + TestFileWithAttachmentsRead.class, + TestChunkData.class, + TestTypes.class, + TestSorters.class, + TestOutlookTextExtractor.class, + TestPOIFSChunkParser.class, + TestMessageSubmissionChunkY2KRead.class, + TestMessageSubmissionChunk.class +}) +public class AllHSMFTests { } diff --git a/src/scratchpad/testcases/org/apache/poi/hsmf/TestFixedSizedProperties.java b/src/scratchpad/testcases/org/apache/poi/hsmf/TestFixedSizedProperties.java index 4108ec0ec..21bf3132f 100644 --- a/src/scratchpad/testcases/org/apache/poi/hsmf/TestFixedSizedProperties.java +++ b/src/scratchpad/testcases/org/apache/poi/hsmf/TestFixedSizedProperties.java @@ -17,19 +17,24 @@ package org.apache.poi.hsmf; +import static org.apache.poi.POITestCase.assertContains; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; import java.io.IOException; import java.io.PrintStream; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.TimeZone; import org.apache.poi.POIDataSamples; -import org.apache.poi.POITestCase; import org.apache.poi.hsmf.datatypes.ChunkBasedPropertyValue; import org.apache.poi.hsmf.datatypes.Chunks; import org.apache.poi.hsmf.datatypes.MAPIProperty; @@ -38,41 +43,58 @@ import org.apache.poi.hsmf.datatypes.PropertyValue.LongPropertyValue; import org.apache.poi.hsmf.datatypes.PropertyValue.TimePropertyValue; import org.apache.poi.hsmf.dev.HSMFDump; import org.apache.poi.hsmf.extractor.OutlookTextExtactor; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; +import org.apache.poi.util.LocaleUtil; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; /** * Tests that we can read fixed sized properties, as well as variable * ones, for example Submission Dates */ -public final class TestFixedSizedProperties extends POITestCase { - protected static final String messageSucceeds = "53784_succeeds.msg"; - protected static final String messageFails = "53784_fails.msg"; - private MAPIMessage mapiMessageSucceeds; - private MAPIMessage mapiMessageFails; - private POIFSFileSystem fsMessageSucceeds; - private POIFSFileSystem fsMessageFails; - private SimpleDateFormat messageDateFormat; +public final class TestFixedSizedProperties { + private static final String messageSucceeds = "53784_succeeds.msg"; + private static final String messageFails = "53784_fails.msg"; + private static MAPIMessage mapiMessageSucceeds; + private static MAPIMessage mapiMessageFails; + private static NPOIFSFileSystem fsMessageSucceeds; + private static NPOIFSFileSystem fsMessageFails; + private static SimpleDateFormat messageDateFormat; + private static TimeZone userTimeZone; /** * Initialize this test, load up the messages. */ - public TestFixedSizedProperties() throws Exception { + @BeforeClass + public static void initMapi() throws Exception { POIDataSamples samples = POIDataSamples.getHSMFInstance(); - this.mapiMessageSucceeds = new MAPIMessage( - samples.openResourceAsStream(messageSucceeds)); - this.mapiMessageFails = new MAPIMessage( - samples.openResourceAsStream(messageFails)); - this.fsMessageSucceeds = new POIFSFileSystem(new FileInputStream(samples.getFile(messageSucceeds))); - this.fsMessageFails = new POIFSFileSystem(new FileInputStream(samples.getFile(messageFails))); + fsMessageSucceeds = new NPOIFSFileSystem(samples.getFile(messageSucceeds)); + fsMessageFails = new NPOIFSFileSystem(samples.getFile(messageFails)); + + mapiMessageSucceeds = new MAPIMessage(fsMessageSucceeds); + mapiMessageFails = new MAPIMessage(fsMessageFails); - messageDateFormat = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss"); - messageDateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); + messageDateFormat = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss", Locale.ROOT); + messageDateFormat.setTimeZone(LocaleUtil.TIMEZONE_UTC); + + userTimeZone = LocaleUtil.getUserTimeZone(); + LocaleUtil.setUserTimeZone(LocaleUtil.TIMEZONE_UTC); + } + + + @AfterClass + public static void closeFS() throws Exception { + LocaleUtil.setUserTimeZone(userTimeZone); + fsMessageSucceeds.close(); + fsMessageFails.close(); } /** * Check we can find a sensible number of properties on a few * of our test files */ + @Test public void testPropertiesFound() throws Exception { Map> props; @@ -86,6 +108,7 @@ public final class TestFixedSizedProperties extends POITestCase { /** * Check we find properties of a variety of different types */ + @Test public void testPropertyValueTypes() throws Exception { Chunks mainChunks = mapiMessageSucceeds.getMainChunks(); @@ -116,30 +139,32 @@ public final class TestFixedSizedProperties extends POITestCase { /** * Test to see if we can read the Date Chunk with OutlookTextExtractor. - * TODO Work out why the Fri 22nd vs Monday 25th problem is occurring and fix */ - public void DISABLEDtestReadMessageDateSucceedsWithOutlookTextExtractor() { + @Test + // @Ignore("TODO Work out why the Fri 22nd vs Monday 25th problem is occurring and fix") + public void testReadMessageDateSucceedsWithOutlookTextExtractor() throws Exception { OutlookTextExtactor ext = new OutlookTextExtactor(mapiMessageSucceeds); String text = ext.getText(); - - assertContains(text, "Date: Fri, 22 Jun 2012 21:32:54\n"); + assertContains(text, "Date: Fri, 22 Jun 2012 18:32:54 +0000\n"); + ext.close(); } /** * Test to see if we can read the Date Chunk with OutlookTextExtractor. - * TODO Work out why the Thu 21st vs Monday 25th problem is occurring and fix */ - public void DISABLEDtestReadMessageDateFailsWithOutlookTextExtractor() { + @Test + // @Ignore("TODO Work out why the Thu 21st vs Monday 25th problem is occurring and fix") + public void testReadMessageDateFailsWithOutlookTextExtractor() throws Exception { OutlookTextExtactor ext = new OutlookTextExtactor(mapiMessageFails); String text = ext.getText(); - - assertContains(text, "Date: Thu, 21 Jun 2012 17:14:04\n"); + assertContains(text, "Date: Thu, 21 Jun 2012 14:14:04 +0000\n"); + ext.close(); } /** * Test to see if we can read the Date Chunk with HSMFDump. - * @throws IOException */ + @Test public void testReadMessageDateSucceedsWithHSMFDump() throws IOException { PrintStream stream = new PrintStream(new ByteArrayOutputStream()); HSMFDump dump = new HSMFDump(fsMessageSucceeds); @@ -148,8 +173,8 @@ public final class TestFixedSizedProperties extends POITestCase { /** * Test to see if we can read the Date Chunk with HSMFDump. - * @throws Exception */ + @Test public void testReadMessageDateFailsWithHSMFDump() throws Exception { PrintStream stream = new PrintStream(new ByteArrayOutputStream()); HSMFDump dump = new HSMFDump(fsMessageFails); @@ -159,6 +184,7 @@ public final class TestFixedSizedProperties extends POITestCase { /** * Will be based on the ClientSubmit time */ + @Test public void testClientSubmitTime() throws Exception { // Check via the message date Calendar clientSubmitTime = mapiMessageSucceeds.getMessageDate(); diff --git a/src/scratchpad/testcases/org/apache/poi/hsmf/extractor/TestOutlookTextExtractor.java b/src/scratchpad/testcases/org/apache/poi/hsmf/extractor/TestOutlookTextExtractor.java index 5550adbb6..b8f34a17e 100644 --- a/src/scratchpad/testcases/org/apache/poi/hsmf/extractor/TestOutlookTextExtractor.java +++ b/src/scratchpad/testcases/org/apache/poi/hsmf/extractor/TestOutlookTextExtractor.java @@ -17,33 +17,47 @@ package org.apache.poi.hsmf.extractor; +import static org.apache.poi.POITestCase.assertContains; +import static org.apache.poi.POITestCase.assertNotContained; +import static org.junit.Assert.assertEquals; + import java.io.FileInputStream; -import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Calendar; -import java.util.GregorianCalendar; +import java.util.Locale; import java.util.TimeZone; import org.apache.poi.POIDataSamples; -import org.apache.poi.POITestCase; import org.apache.poi.hsmf.MAPIMessage; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; +import org.apache.poi.util.LocaleUtil; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; /** * Tests to verify that the text extractor works */ -public final class TestOutlookTextExtractor extends POITestCase { - private POIDataSamples samples; - - public TestOutlookTextExtractor() throws IOException { - samples = POIDataSamples.getHSMFInstance(); - } +public final class TestOutlookTextExtractor { + private POIDataSamples samples = POIDataSamples.getHSMFInstance(); + private static TimeZone userTZ; + + @BeforeClass + public static void initTimeZone() { + userTZ = LocaleUtil.getUserTimeZone(); + LocaleUtil.setUserTimeZone(LocaleUtil.TIMEZONE_UTC); + } + + @AfterClass + public static void resetTimeZone() { + LocaleUtil.setUserTimeZone(userTZ); + } + + @Test public void testQuick() throws Exception { - POIFSFileSystem simple = new POIFSFileSystem( - new FileInputStream(samples.getFile("quick.msg")) - ); - MAPIMessage msg = new MAPIMessage(simple); + NPOIFSFileSystem poifs = new NPOIFSFileSystem(samples.getFile("quick.msg"), true); + MAPIMessage msg = new MAPIMessage(poifs); OutlookTextExtactor ext = new OutlookTextExtactor(msg); String text = ext.getText(); @@ -54,20 +68,21 @@ public final class TestOutlookTextExtractor extends POITestCase { assertEquals(-1, text.indexOf("BCC:")); assertEquals(-1, text.indexOf("Attachment:")); assertContains(text, "Subject: Test the content transformer\n"); - Calendar cal = new GregorianCalendar(2007, 5, 14, 9, 42, 55); - SimpleDateFormat f = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss Z"); - f.setTimeZone(TimeZone.getTimeZone("UTC")); + Calendar cal = LocaleUtil.getLocaleCalendar(2007, 5, 14, 9, 42, 55); + SimpleDateFormat f = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss Z", Locale.ROOT); + f.setTimeZone(LocaleUtil.getUserTimeZone()); String dateText = f.format(cal.getTime()); assertContains(text, "Date: " + dateText + "\n"); assertContains(text, "The quick brown fox jumps over the lazy dog"); ext.close(); + poifs.close(); } + @Test public void testSimple() throws Exception { - MAPIMessage msg = new MAPIMessage(new POIFSFileSystem( - new FileInputStream(samples.getFile("simple_test_msg.msg")) - )); + NPOIFSFileSystem poifs = new NPOIFSFileSystem(samples.getFile("simple_test_msg.msg"), true); + MAPIMessage msg = new MAPIMessage(poifs); OutlookTextExtactor ext = new OutlookTextExtactor(msg); String text = ext.getText(); @@ -81,25 +96,30 @@ public final class TestOutlookTextExtractor extends POITestCase { assertContains(text, "This is a test message."); ext.close(); + poifs.close(); } + @Test public void testConstructors() throws Exception { - OutlookTextExtactor ext = new OutlookTextExtactor(new FileInputStream( - samples.getFile("simple_test_msg.msg"))); + FileInputStream fis = new FileInputStream(samples.getFile("simple_test_msg.msg")); + OutlookTextExtactor ext = new OutlookTextExtactor(fis); String inp = ext.getText(); ext.close(); + fis.close(); - ext = new OutlookTextExtactor(new POIFSFileSystem(new FileInputStream( - samples.getFile("simple_test_msg.msg")))); - String poifs = ext.getText(); + NPOIFSFileSystem poifs = new NPOIFSFileSystem(samples.getFile("simple_test_msg.msg"), true); + ext = new OutlookTextExtactor(poifs); + String poifsTxt = ext.getText(); ext.close(); + poifs.close(); - ext = new OutlookTextExtactor(new MAPIMessage(new FileInputStream( - samples.getFile("simple_test_msg.msg")))); + fis = new FileInputStream(samples.getFile("simple_test_msg.msg")); + ext = new OutlookTextExtactor(new MAPIMessage(fis)); String mapi = ext.getText(); ext.close(); + fis.close(); - assertEquals(inp, poifs); + assertEquals(inp, poifsTxt); assertEquals(inp, mapi); } @@ -107,6 +127,7 @@ public final class TestOutlookTextExtractor extends POITestCase { * Test that we correctly handle multiple To+CC+BCC * recipients in an email we sent. */ + @Test public void testSentWithMulipleRecipients() throws Exception { // To: 'Ashutosh Dandavate' , // 'Paul Holmes-Higgin' , @@ -120,9 +141,8 @@ public final class TestOutlookTextExtractor extends POITestCase { "example_sent_regular.msg", "example_sent_unicode.msg" }; for(String file : files) { - MAPIMessage msg = new MAPIMessage(new POIFSFileSystem( - new FileInputStream(samples.getFile(file)) - )); + NPOIFSFileSystem poifs = new NPOIFSFileSystem(samples.getFile(file), true); + MAPIMessage msg = new MAPIMessage(poifs); OutlookTextExtactor ext = new OutlookTextExtactor(msg); String text = ext.getText(); @@ -139,6 +159,7 @@ public final class TestOutlookTextExtractor extends POITestCase { assertContains(text, "The quick brown fox jumps over the lazy dog"); ext.close(); + poifs.close(); } } @@ -146,6 +167,7 @@ public final class TestOutlookTextExtractor extends POITestCase { * Test that we correctly handle multiple To+CC * recipients in an email we received. */ + @Test public void testReceivedWithMultipleRecipients() throws Exception { // To: 'Ashutosh Dandavate' , // 'Paul Holmes-Higgin' , @@ -159,9 +181,9 @@ public final class TestOutlookTextExtractor extends POITestCase { "example_received_regular.msg", "example_received_unicode.msg" }; for(String file : files) { - MAPIMessage msg = new MAPIMessage(new POIFSFileSystem( - new FileInputStream(samples.getFile(file)) - )); + NPOIFSFileSystem poifs = new NPOIFSFileSystem(samples.getFile(file), true); + MAPIMessage msg = new MAPIMessage(poifs); + OutlookTextExtactor ext = new OutlookTextExtactor(msg); String text = ext.getText(); @@ -177,6 +199,7 @@ public final class TestOutlookTextExtractor extends POITestCase { assertContains(text, "The quick brown fox jumps over the lazy dog"); ext.close(); + poifs.close(); } } @@ -184,10 +207,8 @@ public final class TestOutlookTextExtractor extends POITestCase { * See also {@link org.apache.poi.extractor.TestExtractorFactory#testEmbeded()} */ public void testWithAttachments() throws Exception { - POIFSFileSystem simple = new POIFSFileSystem( - new FileInputStream(samples.getFile("attachment_test_msg.msg")) - ); - MAPIMessage msg = new MAPIMessage(simple); + NPOIFSFileSystem poifs = new NPOIFSFileSystem(samples.getFile("attachment_test_msg.msg"), true); + MAPIMessage msg = new MAPIMessage(poifs); OutlookTextExtactor ext = new OutlookTextExtactor(msg); // Check the normal bits @@ -207,13 +228,12 @@ public final class TestOutlookTextExtractor extends POITestCase { // TestExtractorFactory ext.close(); + poifs.close(); } public void testWithAttachedMessage() throws Exception { - POIFSFileSystem simple = new POIFSFileSystem( - new FileInputStream(samples.getFile("58214_with_attachment.msg")) - ); - MAPIMessage msg = new MAPIMessage(simple); + NPOIFSFileSystem poifs = new NPOIFSFileSystem(samples.getFile("58214_with_attachment.msg"), true); + MAPIMessage msg = new MAPIMessage(poifs); OutlookTextExtactor ext = new OutlookTextExtactor(msg); String text = ext.getText(); @@ -226,13 +246,12 @@ public final class TestOutlookTextExtractor extends POITestCase { assertNotContained(text, "Lorem ipsum dolor sit"); ext.close(); + poifs.close(); } public void testEncodings() throws Exception { - POIFSFileSystem simple = new POIFSFileSystem( - new FileInputStream(samples.getFile("chinese-traditional.msg")) - ); - MAPIMessage msg = new MAPIMessage(simple); + NPOIFSFileSystem poifs = new NPOIFSFileSystem(samples.getFile("chinese-traditional.msg"), true); + MAPIMessage msg = new MAPIMessage(poifs); OutlookTextExtactor ext = new OutlookTextExtactor(msg); String text = ext.getText(); @@ -245,5 +264,6 @@ public final class TestOutlookTextExtractor extends POITestCase { assertContains(text, "( MSG \u683c\u5f0f\u6e2c\u8a66 )"); ext.close(); + poifs.close(); } } diff --git a/src/scratchpad/testcases/org/apache/poi/hsmf/parsers/TestPOIFSChunkParser.java b/src/scratchpad/testcases/org/apache/poi/hsmf/parsers/TestPOIFSChunkParser.java index 721f60591..e4b8142b9 100644 --- a/src/scratchpad/testcases/org/apache/poi/hsmf/parsers/TestPOIFSChunkParser.java +++ b/src/scratchpad/testcases/org/apache/poi/hsmf/parsers/TestPOIFSChunkParser.java @@ -17,13 +17,16 @@ package org.apache.poi.hsmf.parsers; -import java.io.FileInputStream; -import java.io.FileNotFoundException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import java.io.IOException; -import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Calendar; +import org.apache.poi.POIDataSamples; import org.apache.poi.hsmf.MAPIMessage; import org.apache.poi.hsmf.datatypes.AttachmentChunks; import org.apache.poi.hsmf.datatypes.ChunkGroup; @@ -35,25 +38,19 @@ import org.apache.poi.hsmf.datatypes.RecipientChunks.RecipientChunksSorter; import org.apache.poi.hsmf.datatypes.StringChunk; import org.apache.poi.hsmf.datatypes.Types; import org.apache.poi.hsmf.exceptions.ChunkNotFoundException; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.POIDataSamples; - -import junit.framework.TestCase; +import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; +import org.apache.poi.util.LocaleUtil; +import org.junit.Test; /** * Tests to verify that the chunk parser works properly */ -public final class TestPOIFSChunkParser extends TestCase { - private POIDataSamples samples; +public final class TestPOIFSChunkParser { + private POIDataSamples samples = POIDataSamples.getHSMFInstance(); - public TestPOIFSChunkParser() throws IOException { - samples = POIDataSamples.getHSMFInstance(); - } - - public void testFindsCore() throws IOException { - POIFSFileSystem simple = new POIFSFileSystem( - new FileInputStream(samples.getFile("quick.msg")) - ); + @Test + public void testFindsCore() throws Exception { + NPOIFSFileSystem simple = new NPOIFSFileSystem(samples.getFile("quick.msg"), true); // Check a few core things are present simple.getRoot().getEntry( @@ -65,29 +62,20 @@ public final class TestPOIFSChunkParser extends TestCase { // Now load the file MAPIMessage msg = new MAPIMessage(simple); - try { - assertEquals("Kevin Roast", msg.getDisplayTo()); - assertEquals("Kevin Roast", msg.getDisplayFrom()); - assertEquals("Test the content transformer", msg.getSubject()); - } catch(ChunkNotFoundException e) { - fail(); - } + assertEquals("Kevin Roast", msg.getDisplayTo()); + assertEquals("Kevin Roast", msg.getDisplayFrom()); + assertEquals("Test the content transformer", msg.getSubject()); // Check date too - try { - SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - - Calendar c = msg.getMessageDate(); - assertEquals( "2007-06-14 09:42:55", f.format(c.getTime()) ); - } catch(ChunkNotFoundException e) { - fail(); - } + Calendar calExp = LocaleUtil.getLocaleCalendar(2007,5,14,9,42,55); + Calendar calAct = msg.getMessageDate(); + assertEquals( calExp, calAct ); + + simple.close(); } public void testFindsRecips() throws IOException, ChunkNotFoundException { - POIFSFileSystem simple = new POIFSFileSystem( - new FileInputStream(samples.getFile("quick.msg")) - ); + NPOIFSFileSystem simple = new NPOIFSFileSystem(samples.getFile("quick.msg"), true); simple.getRoot().getEntry("__recip_version1.0_#00000000"); @@ -121,11 +109,12 @@ public final class TestPOIFSChunkParser extends TestCase { assertEquals("kevin.roast@alfresco.org", msg.getRecipientDetailsChunks()[0].recipientSMTPChunk.getValue()); assertEquals("/O=HOSTEDSERVICE2/OU=FIRST ADMINISTRATIVE GROUP/CN=RECIPIENTS/CN=Kevin.roast@ben", msg.getRecipientDetailsChunks()[0].recipientEmailChunk.getValue()); + simple.close(); + // Now look at another message - msg = new MAPIMessage(new POIFSFileSystem( - new FileInputStream(samples.getFile("simple_test_msg.msg")) - )); + simple = new NPOIFSFileSystem(samples.getFile("simple_test_msg.msg"), true); + msg = new MAPIMessage(simple); assertNotNull(msg.getRecipientDetailsChunks()); assertEquals(1, msg.getRecipientDetailsChunks().length); @@ -134,12 +123,12 @@ public final class TestPOIFSChunkParser extends TestCase { assertEquals(null, msg.getRecipientDetailsChunks()[0].recipientNameChunk); assertEquals("travis@overwrittenstack.com", msg.getRecipientDetailsChunks()[0].recipientEmailChunk.getValue()); assertEquals("travis@overwrittenstack.com", msg.getRecipientEmailAddress()); + + simple.close(); } public void testFindsMultipleRecipients() throws IOException, ChunkNotFoundException { - POIFSFileSystem multiple = new POIFSFileSystem( - new FileInputStream(samples.getFile("example_received_unicode.msg")) - ); + NPOIFSFileSystem multiple = new NPOIFSFileSystem(samples.getFile("example_received_unicode.msg"), true); multiple.getRoot().getEntry("__recip_version1.0_#00000000"); multiple.getRoot().getEntry("__recip_version1.0_#00000001"); @@ -225,12 +214,12 @@ public final class TestPOIFSChunkParser extends TestCase { assertEquals("nickb@alfresco.com", msg.getRecipientEmailAddressList()[3]); assertEquals("nick.burch@alfresco.com", msg.getRecipientEmailAddressList()[4]); assertEquals("roy.wetherall@alfresco.com", msg.getRecipientEmailAddressList()[5]); + + multiple.close(); } public void testFindsNameId() throws IOException { - POIFSFileSystem simple = new POIFSFileSystem( - new FileInputStream(samples.getFile("quick.msg")) - ); + NPOIFSFileSystem simple = new NPOIFSFileSystem(samples.getFile("quick.msg"), true); simple.getRoot().getEntry("__nameid_version1.0"); @@ -247,15 +236,13 @@ public final class TestPOIFSChunkParser extends TestCase { MAPIMessage msg = new MAPIMessage(simple); assertNotNull(msg.getNameIdChunks()); assertEquals(10, msg.getNameIdChunks().getAll().length); + + simple.close(); } - public void testFindsAttachments() throws IOException { - POIFSFileSystem with = new POIFSFileSystem( - new FileInputStream(samples.getFile("attachment_test_msg.msg")) - ); - POIFSFileSystem without = new POIFSFileSystem( - new FileInputStream(samples.getFile("quick.msg")) - ); + public void testFindsAttachments() throws Exception { + NPOIFSFileSystem with = new NPOIFSFileSystem(samples.getFile("attachment_test_msg.msg"), true); + NPOIFSFileSystem without = new NPOIFSFileSystem(samples.getFile("quick.msg"), true); AttachmentChunks attachment; @@ -284,15 +271,8 @@ public final class TestPOIFSChunkParser extends TestCase { // Check raw details on one without - try { - without.getRoot().getEntry("__attach_version1.0_#00000000"); - fail(); - } catch(FileNotFoundException e) {} - try { - without.getRoot().getEntry("__attach_version1.0_#00000001"); - fail(); - } catch(FileNotFoundException e) {} - + assertFalse(without.getRoot().hasEntry("__attach_version1.0_#00000000")); + assertFalse(without.getRoot().hasEntry("__attach_version1.0_#00000001")); // One with, from the top MAPIMessage msgWith = new MAPIMessage(with); @@ -309,14 +289,9 @@ public final class TestPOIFSChunkParser extends TestCase { assertEquals(89, attachment.attachData.getValue().length); // Plus check core details are there - try { - assertEquals("'nicolas1.23456@free.fr'", msgWith.getDisplayTo()); - assertEquals("Nicolas1 23456", msgWith.getDisplayFrom()); - assertEquals("test pi\u00e8ce jointe 1", msgWith.getSubject()); - } catch(ChunkNotFoundException e) { - fail(); - } - + assertEquals("'nicolas1.23456@free.fr'", msgWith.getDisplayTo()); + assertEquals("Nicolas1 23456", msgWith.getDisplayFrom()); + assertEquals("test pi\u00e8ce jointe 1", msgWith.getSubject()); // One without, from the top MAPIMessage msgWithout = new MAPIMessage(without); @@ -325,13 +300,12 @@ public final class TestPOIFSChunkParser extends TestCase { assertEquals(0, msgWithout.getAttachmentFiles().length); // But has core details - try { - assertEquals("Kevin Roast", msgWithout.getDisplayTo()); - assertEquals("Kevin Roast", msgWithout.getDisplayFrom()); - assertEquals("Test the content transformer", msgWithout.getSubject()); - } catch(ChunkNotFoundException e) { - fail(); - } + assertEquals("Kevin Roast", msgWithout.getDisplayTo()); + assertEquals("Kevin Roast", msgWithout.getDisplayFrom()); + assertEquals("Test the content transformer", msgWithout.getSubject()); + + without.close(); + with.close(); } /** @@ -340,13 +314,13 @@ public final class TestPOIFSChunkParser extends TestCase { * such as "Olk10SideProps_0001" */ public void testOlk10SideProps() throws Exception { - POIFSFileSystem poifs = new POIFSFileSystem( - new FileInputStream(samples.getFile("51873.msg")) - ); + NPOIFSFileSystem poifs = new NPOIFSFileSystem(samples.getFile("51873.msg"), true); MAPIMessage msg = new MAPIMessage(poifs); // Check core details came through assertEquals("bubba@bubbasmith.com", msg.getDisplayTo()); assertEquals("Test with Olk10SideProps_ Chunk", msg.getSubject()); + + poifs.close(); } } diff --git a/src/testcases/org/apache/poi/hpsf/basic/TestWrite.java b/src/testcases/org/apache/poi/hpsf/basic/TestWrite.java index 6efa51bb5..045f66f78 100644 --- a/src/testcases/org/apache/poi/hpsf/basic/TestWrite.java +++ b/src/testcases/org/apache/poi/hpsf/basic/TestWrite.java @@ -38,6 +38,7 @@ import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.util.Date; import java.util.HashMap; +import java.util.Locale; import java.util.Map; import org.apache.poi.POIDataSamples; @@ -117,8 +118,8 @@ public class TestWrite * * @exception IOException if an I/O exception occurs */ - @Test - public void withoutAFormatID() throws IOException + @Test(expected=NoFormatIDException.class) + public void withoutAFormatID() throws Exception { final File filename = TempFile.createTempFile(POI_FS, ".doc"); @@ -131,8 +132,7 @@ public class TestWrite ps.addSection(new MutableSection()); /* Write it to a POIFS and the latter to disk: */ - try - { + try { final ByteArrayOutputStream psStream = new ByteArrayOutputStream(); ps.write(psStream); psStream.close(); @@ -140,15 +140,8 @@ public class TestWrite poiFs.createDocument(new ByteArrayInputStream(streamData), SummaryInformation.DEFAULT_STREAM_NAME); poiFs.writeFilesystem(out); - out.close(); - fail("Should have thrown a NoFormatIDException."); - } - catch (Exception ex) - { - assertTrue(ex instanceof NoFormatIDException); - } - finally - { + } finally { + poiFs.close(); out.close(); } } @@ -185,6 +178,7 @@ public class TestWrite poiFs.createDocument(new ByteArrayInputStream(streamData), SummaryInformation.DEFAULT_STREAM_NAME); poiFs.writeFilesystem(out); + poiFs.close(); out.close(); /* Read the POIFS: */ @@ -236,6 +230,7 @@ public class TestWrite poiFs.createDocument(ps.toInputStream(), SummaryInformation.DEFAULT_STREAM_NAME); poiFs.writeFilesystem(out); + poiFs.close(); out.close(); /* Read the POIFS: */ @@ -317,6 +312,7 @@ public class TestWrite poiFs.createDocument(ps.toInputStream(), STREAM_NAME); poiFs.writeFilesystem(out); + poiFs.close(); out.close(); /* Read the POIFS: */ @@ -755,6 +751,7 @@ public class TestWrite psf1[i].getName()); poiFs.writeFilesystem(out); } + poiFs.close(); out.close(); @@ -805,6 +802,7 @@ public class TestWrite Integer.valueOf(codepage)); poiFs.createDocument(ps1.toInputStream(), "Test"); poiFs.writeFilesystem(out); + poiFs.close(); out.close(); /* Read back: */ @@ -1010,7 +1008,7 @@ public class TestWrite // or via sun.misc.Cleaner, but this is regarded unsafe // http://stackoverflow.com/questions/2972986 // http://bugs.java.com/view_bug.do?bug_id=4724038 - Assume.assumeFalse(System.getProperty("os.name").toLowerCase().contains("win")); + Assume.assumeFalse(System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("win")); throw e; } } @@ -1022,7 +1020,7 @@ public class TestWrite * @throws IOException * @throws HPSFException */ - @Test + @Test(expected=IllegalPropertySetDataException.class) public void dictionaryWithInvalidCodepage() throws IOException, HPSFException { final File copy = TempFile.createTempFile("Test-HPSF", "ole2"); @@ -1039,8 +1037,7 @@ public class TestWrite m.put(Long.valueOf(2), "String 2"); m.put(Long.valueOf(3), "String 3"); - try - { + try { s.setDictionary(m); s.setFormatID(SectionIDMap.DOCUMENT_SUMMARY_INFORMATION_ID[0]); int codepage = 12345; @@ -1048,13 +1045,9 @@ public class TestWrite Integer.valueOf(codepage)); poiFs.createDocument(ps1.toInputStream(), "Test"); poiFs.writeFilesystem(out); + } finally { + poiFs.close(); out.close(); - fail("This testcase did not detect the invalid codepage value."); - } - catch (IllegalPropertySetDataException ex) - { - out.close(); - assertTrue(true); } } @@ -1069,7 +1062,7 @@ public class TestWrite { final String charSetName = System.getProperty("file.encoding"); final Charset charSet = Charset.forName(charSetName); - return charSet.displayName(); + return charSet.displayName(Locale.ROOT); } diff --git a/src/testcases/org/apache/poi/hpsf/basic/TestWriteWellKnown.java b/src/testcases/org/apache/poi/hpsf/basic/TestWriteWellKnown.java index b58b4cd8f..6769861e4 100644 --- a/src/testcases/org/apache/poi/hpsf/basic/TestWriteWellKnown.java +++ b/src/testcases/org/apache/poi/hpsf/basic/TestWriteWellKnown.java @@ -17,6 +17,12 @@ package org.apache.poi.hpsf.basic; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; @@ -26,45 +32,47 @@ import java.io.IOException; import java.io.OutputStream; import java.util.Calendar; import java.util.Date; -import java.util.GregorianCalendar; import java.util.HashMap; -import java.util.Locale; import java.util.Map; -import junit.framework.TestCase; - import org.apache.poi.POIDataSamples; -import org.apache.poi.hpsf.*; +import org.apache.poi.hpsf.CustomProperties; +import org.apache.poi.hpsf.CustomProperty; +import org.apache.poi.hpsf.DocumentSummaryInformation; +import org.apache.poi.hpsf.MarkUnsupportedException; +import org.apache.poi.hpsf.MutableProperty; +import org.apache.poi.hpsf.MutableSection; +import org.apache.poi.hpsf.NoPropertySetStreamException; +import org.apache.poi.hpsf.PropertySet; +import org.apache.poi.hpsf.PropertySetFactory; +import org.apache.poi.hpsf.SummaryInformation; +import org.apache.poi.hpsf.UnexpectedPropertySetTypeException; +import org.apache.poi.hpsf.Variant; +import org.apache.poi.hpsf.VariantSupport; +import org.apache.poi.hpsf.WritingNotSupportedException; import org.apache.poi.hpsf.wellknown.SectionIDMap; import org.apache.poi.poifs.filesystem.DirectoryEntry; -import org.apache.poi.poifs.filesystem.DocumentEntry; import org.apache.poi.poifs.filesystem.DocumentInputStream; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; +import org.apache.poi.util.IOUtils; +import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.TempFile; +import org.junit.BeforeClass; +import org.junit.Test; /** *

Tests HPSF's high-level writing functionality for the well-known property * set "SummaryInformation" and "DocumentSummaryInformation".

- * - * @author Rainer Klute - * klute@rainer-klute.de */ -public class TestWriteWellKnown extends TestCase { +public class TestWriteWellKnown { private static final String POI_FS = "TestWriteWellKnown.doc"; - - /** - * @see TestCase#setUp() - */ - @Override - public void setUp() - { + @BeforeClass + public static void setUp() { VariantSupport.setLogUnsupportedTypes(false); } - - /** *

This test method checks whether DocumentSummary information streams * can be read. This is done by opening all "Test*" files in the 'poifs' directrory @@ -72,6 +80,7 @@ public class TestWriteWellKnown extends TestCase { * the document summary information stream in the root directory and calling * its get... methods.

*/ + @Test public void testReadDocumentSummaryInformation() throws FileNotFoundException, IOException, NoPropertySetStreamException, MarkUnsupportedException, @@ -88,36 +97,18 @@ public class TestWriteWellKnown extends TestCase { } }); - for (int i = 0; i < docs.length; i++) - { + for (final File doc : docs) { + NPOIFSFileSystem poifs = null; try { - final File doc = docs[i]; - /* Read a test document doc into a POI filesystem. */ - final POIFSFileSystem poifs = new POIFSFileSystem(new FileInputStream(doc)); + poifs = new NPOIFSFileSystem(doc, true); final DirectoryEntry dir = poifs.getRoot(); - DocumentEntry dsiEntry = null; - try - { - dsiEntry = (DocumentEntry) dir.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME); - } - catch (FileNotFoundException ex) - { - /* - * A missing document summary information stream is not an error - * and therefore silently ignored here. - */ - } - /* * If there is a document summry information stream, read it from * the POI filesystem. */ - if (dsiEntry != null) - { - final DocumentInputStream dis = new DocumentInputStream(dsiEntry); - final PropertySet ps = new PropertySet(dis); - final DocumentSummaryInformation dsi = new DocumentSummaryInformation(ps); + if (dir.hasEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME)) { + final DocumentSummaryInformation dsi = getDocumentSummaryInformation(poifs); /* Execute the get... methods. */ dsi.getByteCount(); @@ -139,12 +130,72 @@ public class TestWriteWellKnown extends TestCase { dsi.getSlideCount(); } } catch (Exception e) { - throw new IOException("While handling file " + docs[i], e); + throw new IOException("While handling file " + doc, e); + } finally { + if (poifs != null) poifs.close(); } } } + static final String P_APPLICATION_NAME = "ApplicationName"; + static final String P_AUTHOR = "Author"; + static final int P_CHAR_COUNT = 4712; + static final String P_COMMENTS = "Comments"; + static final Date P_CREATE_DATE_TIME; + static final long P_EDIT_TIME = 4713 * 1000 * 10; + static final String P_KEYWORDS = "Keywords"; + static final String P_LAST_AUTHOR = "LastAuthor"; + static final Date P_LAST_PRINTED; + static final Date P_LAST_SAVE_DATE_TIME; + static final int P_PAGE_COUNT = 4714; + static final String P_REV_NUMBER = "RevNumber"; + static final int P_SECURITY = 1; + static final String P_SUBJECT = "Subject"; + static final String P_TEMPLATE = "Template"; + // FIXME (byte array properties not yet implemented): static final byte[] P_THUMBNAIL = new byte[123]; + static final String P_TITLE = "Title"; + static final int P_WORD_COUNT = 4715; + static final int P_BYTE_COUNT = 4716; + static final String P_CATEGORY = "Category"; + static final String P_COMPANY = "Company"; + // FIXME (byte array properties not yet implemented): static final byte[] P_DOCPARTS = new byte[123]; + // FIXME (byte array properties not yet implemented): static final byte[] P_HEADING_PAIR = new byte[123]; + static final int P_HIDDEN_COUNT = 4717; + static final int P_LINE_COUNT = 4718; + static final boolean P_LINKS_DIRTY = true; + static final String P_MANAGER = "Manager"; + static final int P_MM_CLIP_COUNT = 4719; + static final int P_NOTE_COUNT = 4720; + static final int P_PAR_COUNT = 4721; + static final String P_PRESENTATION_FORMAT = "PresentationFormat"; + static final boolean P_SCALE = false; + static final int P_SLIDE_COUNT = 4722; + static final Date now = new Date(); + + static final Integer POSITIVE_INTEGER = new Integer(2222); + static final Long POSITIVE_LONG = new Long(3333); + static final Double POSITIVE_DOUBLE = new Double(4444); + static final Integer NEGATIVE_INTEGER = new Integer(2222); + static final Long NEGATIVE_LONG = new Long(3333); + static final Double NEGATIVE_DOUBLE = new Double(4444); + + static final Integer MAX_INTEGER = new Integer(Integer.MAX_VALUE); + static final Integer MIN_INTEGER = new Integer(Integer.MIN_VALUE); + static final Long MAX_LONG = new Long(Long.MAX_VALUE); + static final Long MIN_LONG = new Long(Long.MIN_VALUE); + static final Double MAX_DOUBLE = new Double(Double.MAX_VALUE); + static final Double MIN_DOUBLE = new Double(Double.MIN_VALUE); + + static { + Calendar cal = LocaleUtil.getLocaleCalendar(2000, 6, 6, 6, 6, 6); + P_CREATE_DATE_TIME = cal.getTime(); + cal.set(2001, 7, 7, 7, 7, 7); + P_LAST_PRINTED = cal.getTime(); + cal.set(2002, 8, 8, 8, 8, 8); + P_LAST_SAVE_DATE_TIME = cal.getTime(); + } + /** *

This test method test the writing of properties in the well-known * property set streams "SummaryInformation" and @@ -192,19 +243,35 @@ public class TestWriteWellKnown extends TestCase { * @throws UnexpectedPropertySetTypeException * @throws WritingNotSupportedException */ - public void testWriteWellKnown() throws IOException, - NoPropertySetStreamException, MarkUnsupportedException, - UnexpectedPropertySetTypeException, WritingNotSupportedException - { + @Test + public void testWriteWellKnown() throws Exception { POIDataSamples _samples = POIDataSamples.getHPSFInstance(); - final File dataDir = _samples.getFile(""); - final File doc1 = new File(dataDir, POI_FS); + + final File doc1 = TempFile.createTempFile("POI_HPSF_Test1.", ".tmp"); + final File doc2 = TempFile.createTempFile("POI_HPSF_Test2.", ".tmp"); + final File doc3 = TempFile.createTempFile("POI_HPSF_Test3.", ".tmp"); + FileInputStream fis = new FileInputStream(_samples.getFile(POI_FS)); + FileOutputStream fos = new FileOutputStream(doc1); + IOUtils.copy(fis, fos); + fos.close(); + fis.close(); + + CustomProperties cps1 = write1stFile(doc1, doc2); + CustomProperties cps2 = write2ndFile(doc2, doc3); + write3rdFile(doc3, null); + + assertEquals(cps1, cps2); + } + + /* + * Write all properties supported by HPSF to the summary information + * (e.g. author, edit date, application name) and to the document + * summary information (e.g. company, manager). + */ + private static CustomProperties write1stFile(File fileIn, File fileOut) throws Exception { /* Read a test document doc1 into a POI filesystem. */ - POIFSFileSystem poifs = new POIFSFileSystem(new FileInputStream(doc1)); - DirectoryEntry dir = poifs.getRoot(); - DocumentEntry siEntry = (DocumentEntry) dir.getEntry(SummaryInformation.DEFAULT_STREAM_NAME); - DocumentEntry dsiEntry = (DocumentEntry) dir.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME); + NPOIFSFileSystem poifs = new NPOIFSFileSystem(fileIn, false); /* * Read the summary information stream and the document summary @@ -216,76 +283,8 @@ public class TestWriteWellKnown extends TestCase { * explicitly (overwriting the former contents). Then the POI filesystem * should be saved to a file. */ - DocumentInputStream dis = new DocumentInputStream(siEntry); - PropertySet ps = new PropertySet(dis); - SummaryInformation si = new SummaryInformation(ps); - dis = new DocumentInputStream(dsiEntry); - ps = new PropertySet(dis); - DocumentSummaryInformation dsi = new DocumentSummaryInformation(ps); - - /* - * Write all properties supported by HPSF to the summary information - * (e.g. author, edit date, application name) and to the document - * summary information (e.g. company, manager). - */ - Calendar cal = new GregorianCalendar(Locale.ROOT); - cal.set(2000, 6, 6, 6, 6, 6); - final long time1 = cal.getTimeInMillis(); - cal.set(2001, 7, 7, 7, 7, 7); - final long time2 = cal.getTimeInMillis(); - cal.set(2002, 8, 8, 8, 8, 8); - final long time3 = cal.getTimeInMillis(); - - int nr = 4711; - final String P_APPLICATION_NAME = "ApplicationName"; - final String P_AUTHOR = "Author"; - final int P_CHAR_COUNT = ++nr; - final String P_COMMENTS = "Comments"; - final Date P_CREATE_DATE_TIME = new Date(time1); - final long P_EDIT_TIME = ++nr * 1000 * 10; - final String P_KEYWORDS = "Keywords"; - final String P_LAST_AUTHOR = "LastAuthor"; - final Date P_LAST_PRINTED = new Date(time2); - final Date P_LAST_SAVE_DATE_TIME = new Date(time3); - final int P_PAGE_COUNT = ++nr; - final String P_REV_NUMBER = "RevNumber"; - final int P_SECURITY = 1; - final String P_SUBJECT = "Subject"; - final String P_TEMPLATE = "Template"; - // FIXME (byte array properties not yet implemented): final byte[] P_THUMBNAIL = new byte[123]; - final String P_TITLE = "Title"; - final int P_WORD_COUNT = ++nr; - - final int P_BYTE_COUNT = ++nr; - final String P_CATEGORY = "Category"; - final String P_COMPANY = "Company"; - // FIXME (byte array properties not yet implemented): final byte[] P_DOCPARTS = new byte[123]; - // FIXME (byte array properties not yet implemented): final byte[] P_HEADING_PAIR = new byte[123]; - final int P_HIDDEN_COUNT = ++nr; - final int P_LINE_COUNT = ++nr; - final boolean P_LINKS_DIRTY = true; - final String P_MANAGER = "Manager"; - final int P_MM_CLIP_COUNT = ++nr; - final int P_NOTE_COUNT = ++nr; - final int P_PAR_COUNT = ++nr; - final String P_PRESENTATION_FORMAT = "PresentationFormat"; - final boolean P_SCALE = false; - final int P_SLIDE_COUNT = ++nr; - final Date now = new Date(); - - final Integer POSITIVE_INTEGER = new Integer(2222); - final Long POSITIVE_LONG = new Long(3333); - final Double POSITIVE_DOUBLE = new Double(4444); - final Integer NEGATIVE_INTEGER = new Integer(2222); - final Long NEGATIVE_LONG = new Long(3333); - final Double NEGATIVE_DOUBLE = new Double(4444); - - final Integer MAX_INTEGER = new Integer(Integer.MAX_VALUE); - final Integer MIN_INTEGER = new Integer(Integer.MIN_VALUE); - final Long MAX_LONG = new Long(Long.MAX_VALUE); - final Long MIN_LONG = new Long(Long.MIN_VALUE); - final Double MAX_DOUBLE = new Double(Double.MAX_VALUE); - final Double MIN_DOUBLE = new Double(Double.MIN_VALUE); + SummaryInformation si = getSummaryInformation(poifs); + DocumentSummaryInformation dsi = getDocumentSummaryInformation(poifs); si.setApplicationName(P_APPLICATION_NAME); si.setAuthor(P_AUTHOR); @@ -322,76 +321,71 @@ public class TestWriteWellKnown extends TestCase { dsi.setScale(P_SCALE); dsi.setSlideCount(P_SLIDE_COUNT); - CustomProperties customProperties = dsi.getCustomProperties(); - if (customProperties == null) - customProperties = new CustomProperties(); - customProperties.put("Schl\u00fcssel \u00e4", "Wert \u00e4"); - customProperties.put("Schl\u00fcssel \u00e4\u00f6", "Wert \u00e4\u00f6"); - customProperties.put("Schl\u00fcssel \u00e4\u00f6\u00fc", "Wert \u00e4\u00f6\u00fc"); - customProperties.put("Schl\u00fcssel \u00e4\u00f6\u00fc\u00d6", "Wert \u00e4\u00f6\u00fc\u00d6"); - customProperties.put("positive_Integer", POSITIVE_INTEGER); - customProperties.put("positive_Long", POSITIVE_LONG); - customProperties.put("positive_Double", POSITIVE_DOUBLE); - customProperties.put("negative_Integer", NEGATIVE_INTEGER); - customProperties.put("negative_Long", NEGATIVE_LONG); - customProperties.put("negative_Double", NEGATIVE_DOUBLE); - customProperties.put("Boolean", Boolean.TRUE); - customProperties.put("Date", now); - customProperties.put("max_Integer", MAX_INTEGER); - customProperties.put("min_Integer", MIN_INTEGER); - customProperties.put("max_Long", MAX_LONG); - customProperties.put("min_Long", MIN_LONG); - customProperties.put("max_Double", MAX_DOUBLE); - customProperties.put("min_Double", MIN_DOUBLE); + CustomProperties cps = dsi.getCustomProperties(); + assertNull(cps); + cps = new CustomProperties(); + cps.put("Schl\u00fcssel \u00e4", "Wert \u00e4"); + cps.put("Schl\u00fcssel \u00e4\u00f6", "Wert \u00e4\u00f6"); + cps.put("Schl\u00fcssel \u00e4\u00f6\u00fc", "Wert \u00e4\u00f6\u00fc"); + cps.put("Schl\u00fcssel \u00e4\u00f6\u00fc\u00d6", "Wert \u00e4\u00f6\u00fc\u00d6"); + cps.put("positive_Integer", POSITIVE_INTEGER); + cps.put("positive_Long", POSITIVE_LONG); + cps.put("positive_Double", POSITIVE_DOUBLE); + cps.put("negative_Integer", NEGATIVE_INTEGER); + cps.put("negative_Long", NEGATIVE_LONG); + cps.put("negative_Double", NEGATIVE_DOUBLE); + cps.put("Boolean", Boolean.TRUE); + cps.put("Date", now); + cps.put("max_Integer", MAX_INTEGER); + cps.put("min_Integer", MIN_INTEGER); + cps.put("max_Long", MAX_LONG); + cps.put("min_Long", MIN_LONG); + cps.put("max_Double", MAX_DOUBLE); + cps.put("min_Double", MIN_DOUBLE); // Check the keys went in - assertTrue(customProperties.containsKey("Schl\u00fcssel \u00e4")); - assertTrue(customProperties.containsKey("Boolean")); + assertTrue(cps.containsKey("Schl\u00fcssel \u00e4")); + assertTrue(cps.containsKey("Boolean")); // Check the values went in - assertEquals("Wert \u00e4", customProperties.get("Schl\u00fcssel \u00e4")); - assertEquals(Boolean.TRUE, customProperties.get("Boolean")); - assertTrue(customProperties.containsValue(Boolean.TRUE)); - assertTrue(customProperties.containsValue("Wert \u00e4")); + assertEquals("Wert \u00e4", cps.get("Schl\u00fcssel \u00e4")); + assertEquals(Boolean.TRUE, cps.get("Boolean")); + assertTrue(cps.containsValue(Boolean.TRUE)); + assertTrue(cps.containsValue("Wert \u00e4")); // Check that things that aren't in aren't in - assertFalse(customProperties.containsKey("False Boolean")); - assertFalse(customProperties.containsValue(Boolean.FALSE)); + assertFalse(cps.containsKey("False Boolean")); + assertFalse(cps.containsValue(Boolean.FALSE)); // Save as our custom properties - dsi.setCustomProperties(customProperties); + dsi.setCustomProperties(cps); /* Write the summary information stream and the document summary * information stream to the POI filesystem. */ - si.write(dir, siEntry.getName()); - dsi.write(dir, dsiEntry.getName()); + si.write(poifs.getRoot(), SummaryInformation.DEFAULT_STREAM_NAME); + dsi.write(poifs.getRoot(), DocumentSummaryInformation.DEFAULT_STREAM_NAME); /* Write the POI filesystem to a (temporary) file doc2 * and close the latter. */ - final File doc2 = TempFile.createTempFile("POI_HPSF_Test.", ".tmp"); - doc2.deleteOnExit(); - OutputStream out = new FileOutputStream(doc2); + OutputStream out = new FileOutputStream(fileOut); poifs.writeFilesystem(out); out.close(); - - /* - * Open doc2 for reading and check summary information and - * document summary information. All properties written before must be - * found in the property streams of doc2 and have the correct - * values. - */ - poifs = new POIFSFileSystem(new FileInputStream(doc2)); - dir = poifs.getRoot(); - siEntry = (DocumentEntry) dir.getEntry(SummaryInformation.DEFAULT_STREAM_NAME); - dsiEntry = (DocumentEntry) dir.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME); - - dis = new DocumentInputStream(siEntry); - ps = new PropertySet(dis); - si = new SummaryInformation(ps); - dis = new DocumentInputStream(dsiEntry); - ps = new PropertySet(dis); - dsi = new DocumentSummaryInformation(ps); + poifs.close(); + + return cps; + } + + /* + * Open doc2 for reading and check summary information and + * document summary information. All properties written before must be + * found in the property streams of doc2 and have the correct + * values. + */ + private static CustomProperties write2ndFile(File fileIn, File fileOut) throws Exception { + NPOIFSFileSystem poifs = new NPOIFSFileSystem(fileIn, false); + SummaryInformation si = getSummaryInformation(poifs); + DocumentSummaryInformation dsi = getDocumentSummaryInformation(poifs); assertEquals(P_APPLICATION_NAME, si.getApplicationName()); assertEquals(P_AUTHOR, si.getAuthor()); @@ -429,7 +423,7 @@ public class TestWriteWellKnown extends TestCase { assertEquals(P_SLIDE_COUNT, dsi.getSlideCount()); final CustomProperties cps = dsi.getCustomProperties(); - assertEquals(customProperties, cps); + assertNotNull(cps); assertNull(cps.get("No value available")); assertEquals("Wert \u00e4", cps.get("Schl\u00fcssel \u00e4")); assertEquals("Wert \u00e4\u00f6", cps.get("Schl\u00fcssel \u00e4\u00f6")); @@ -492,93 +486,108 @@ public class TestWriteWellKnown extends TestCase { /* *

  • Write the summary information stream and the document summary * information stream to the POI filesystem. */ - si.write(dir, siEntry.getName()); - dsi.write(dir, dsiEntry.getName()); + si.write(poifs.getRoot(), SummaryInformation.DEFAULT_STREAM_NAME); + dsi.write(poifs.getRoot(), DocumentSummaryInformation.DEFAULT_STREAM_NAME); /* *

  • Write the POI filesystem to a (temporary) file doc3 * and close the latter. */ - final File doc3 = TempFile.createTempFile("POI_HPSF_Test.", ".tmp"); - doc3.deleteOnExit(); - out = new FileOutputStream(doc3); + FileOutputStream out = new FileOutputStream(fileOut); poifs.writeFilesystem(out); out.close(); + poifs.close(); + + return cps; + } + + /* + * Open doc3 for reading and check summary information + * and document summary information. All properties removed before must not + * be found in the property streams of doc3. + */ + private static CustomProperties write3rdFile(File fileIn, File fileOut) throws Exception { + NPOIFSFileSystem poifs = new NPOIFSFileSystem(fileIn, false); + SummaryInformation si = getSummaryInformation(poifs); + DocumentSummaryInformation dsi = getDocumentSummaryInformation(poifs); - /* - * Open doc3 for reading and check summary information - * and document summary information. All properties removed before must not - * be found in the property streams of doc3. - */ - poifs = new POIFSFileSystem(new FileInputStream(doc3)); - dir = poifs.getRoot(); - siEntry = (DocumentEntry) dir.getEntry(SummaryInformation.DEFAULT_STREAM_NAME); - dsiEntry = (DocumentEntry) dir.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME); - - dis = new DocumentInputStream(siEntry); - ps = new PropertySet(dis); - si = new SummaryInformation(ps); - dis = new DocumentInputStream(dsiEntry); - ps = new PropertySet(dis); - dsi = new DocumentSummaryInformation(ps); - - assertEquals(null, si.getApplicationName()); - assertEquals(null, si.getAuthor()); + assertNull(si.getApplicationName()); + assertNull(si.getAuthor()); assertEquals(0, si.getCharCount()); assertTrue(si.wasNull()); - assertEquals(null, si.getComments()); - assertEquals(null, si.getCreateDateTime()); + assertNull(si.getComments()); + assertNull(si.getCreateDateTime()); assertEquals(0, si.getEditTime()); assertTrue(si.wasNull()); - assertEquals(null, si.getKeywords()); - assertEquals(null, si.getLastAuthor()); - assertEquals(null, si.getLastPrinted()); - assertEquals(null, si.getLastSaveDateTime()); + assertNull(si.getKeywords()); + assertNull(si.getLastAuthor()); + assertNull(si.getLastPrinted()); + assertNull(si.getLastSaveDateTime()); assertEquals(0, si.getPageCount()); assertTrue(si.wasNull()); - assertEquals(null, si.getRevNumber()); + assertNull(si.getRevNumber()); assertEquals(0, si.getSecurity()); assertTrue(si.wasNull()); - assertEquals(null, si.getSubject()); - assertEquals(null, si.getTemplate()); - assertEquals(null, si.getThumbnail()); - assertEquals(null, si.getTitle()); + assertNull(si.getSubject()); + assertNull(si.getTemplate()); + assertNull(si.getThumbnail()); + assertNull(si.getTitle()); assertEquals(0, si.getWordCount()); assertTrue(si.wasNull()); assertEquals(0, dsi.getByteCount()); assertTrue(dsi.wasNull()); - assertEquals(null, dsi.getCategory()); - assertEquals(null, dsi.getCustomProperties()); - // FIXME (byte array properties not yet implemented): assertEquals(null, dsi.getDocparts()); - // FIXME (byte array properties not yet implemented): assertEquals(null, dsi.getHeadingPair()); + assertNull(dsi.getCategory()); + assertNull(dsi.getCustomProperties()); + // FIXME (byte array properties not yet implemented): assertNull(dsi.getDocparts()); + // FIXME (byte array properties not yet implemented): assertNull(dsi.getHeadingPair()); assertEquals(0, dsi.getHiddenCount()); assertTrue(dsi.wasNull()); assertEquals(0, dsi.getLineCount()); assertTrue(dsi.wasNull()); - assertEquals(false, dsi.getLinksDirty()); + assertFalse(dsi.getLinksDirty()); assertTrue(dsi.wasNull()); - assertEquals(null, dsi.getManager()); + assertNull(dsi.getManager()); assertEquals(0, dsi.getMMClipCount()); assertTrue(dsi.wasNull()); assertEquals(0, dsi.getNoteCount()); assertTrue(dsi.wasNull()); assertEquals(0, dsi.getParCount()); assertTrue(dsi.wasNull()); - assertEquals(null, dsi.getPresentationFormat()); - assertEquals(false, dsi.getScale()); + assertNull(dsi.getPresentationFormat()); + assertFalse(dsi.getScale()); assertTrue(dsi.wasNull()); assertEquals(0, dsi.getSlideCount()); assertTrue(dsi.wasNull()); + poifs.close(); + + return dsi.getCustomProperties(); } + private static SummaryInformation getSummaryInformation(NPOIFSFileSystem poifs) throws Exception { + DocumentInputStream dis = poifs.createDocumentInputStream(SummaryInformation.DEFAULT_STREAM_NAME); + PropertySet ps = new PropertySet(dis); + SummaryInformation si = new SummaryInformation(ps); + dis.close(); + return si; + } + + private static DocumentSummaryInformation getDocumentSummaryInformation(NPOIFSFileSystem poifs) throws Exception { + DocumentInputStream dis = poifs.createDocumentInputStream(DocumentSummaryInformation.DEFAULT_STREAM_NAME); + PropertySet ps = new PropertySet(dis); + DocumentSummaryInformation dsi = new DocumentSummaryInformation(ps); + dis.close(); + return dsi; + } - + + /** *

    Tests the simplified custom properties by reading them from the * available test files.

    * * @throws Throwable if anything goes wrong. */ + @Test public void testReadCustomPropertiesFromFiles() throws Throwable { final AllDataFilesTester.TestTask task = new AllDataFilesTester.TestTask() @@ -590,43 +599,35 @@ public class TestWriteWellKnown extends TestCase { UnexpectedPropertySetTypeException { /* Read a test document doc into a POI filesystem. */ - final POIFSFileSystem poifs = new POIFSFileSystem(new FileInputStream(file)); - final DirectoryEntry dir = poifs.getRoot(); - DocumentEntry dsiEntry = null; - try - { - dsiEntry = (DocumentEntry) dir.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME); - } - catch (FileNotFoundException ex) - { + NPOIFSFileSystem poifs = null; + try { + poifs = new NPOIFSFileSystem(file); + final DirectoryEntry dir = poifs.getRoot(); /* - * A missing document summary information stream is not an error - * and therefore silently ignored here. + * If there is a document summry information stream, read it from + * the POI filesystem, else create a new one. */ - } - - /* - * If there is a document summry information stream, read it from - * the POI filesystem, else create a new one. - */ - DocumentSummaryInformation dsi; - if (dsiEntry != null) - { - final DocumentInputStream dis = new DocumentInputStream(dsiEntry); - final PropertySet ps = new PropertySet(dis); - dsi = new DocumentSummaryInformation(ps); - } - else - dsi = PropertySetFactory.newDocumentSummaryInformation(); - final CustomProperties cps = dsi.getCustomProperties(); - - if (cps == null) - /* The document does not have custom properties. */ - return; - - for (CustomProperty cp : cps.values()) { - cp.getName(); - cp.getValue(); + DocumentSummaryInformation dsi; + if (dir.hasEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME)) { + final DocumentInputStream dis = poifs.createDocumentInputStream(DocumentSummaryInformation.DEFAULT_STREAM_NAME); + final PropertySet ps = new PropertySet(dis); + dsi = new DocumentSummaryInformation(ps); + dis.close(); + } else { + dsi = PropertySetFactory.newDocumentSummaryInformation(); + } + final CustomProperties cps = dsi.getCustomProperties(); + + if (cps == null) + /* The document does not have custom properties. */ + return; + + for (CustomProperty cp : cps.values()) { + cp.getName(); + cp.getValue(); + } + } finally { + if (poifs != null) poifs.close(); } } }; @@ -657,6 +658,7 @@ public class TestWriteWellKnown extends TestCase { /** *

    Tests basic custom property features.

    */ + @Test public void testCustomerProperties() { final String KEY = "Schl\u00fcssel \u00e4"; @@ -695,6 +697,7 @@ public class TestWriteWellKnown extends TestCase { *

    Tests reading custom properties from a section including reading * custom properties which are not pure.

    */ + @Test public void testGetCustomerProperties() { final int ID_1 = 2; @@ -709,7 +712,7 @@ public class TestWriteWellKnown extends TestCase { /* A document summary information set stream by default does have custom properties. */ cps = dsi.getCustomProperties(); - assertEquals(null, cps); + assertNull(cps); /* Test an empty custom properties set. */ s = new MutableSection(); diff --git a/src/testcases/org/apache/poi/hssf/extractor/TestExcelExtractor.java b/src/testcases/org/apache/poi/hssf/extractor/TestExcelExtractor.java index 793215a02..15f4a3cb0 100644 --- a/src/testcases/org/apache/poi/hssf/extractor/TestExcelExtractor.java +++ b/src/testcases/org/apache/poi/hssf/extractor/TestExcelExtractor.java @@ -17,10 +17,13 @@ package org.apache.poi.hssf.extractor; -import java.io.IOException; -import java.io.InputStream; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; -import junit.framework.TestCase; +import java.io.File; +import java.io.IOException; +import java.util.Locale; import org.apache.poi.POIDataSamples; import org.apache.poi.hssf.HSSFTestDataSamples; @@ -28,24 +31,22 @@ import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.poifs.filesystem.DirectoryNode; import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.util.LocaleUtil; +import org.junit.Test; /** * */ -public final class TestExcelExtractor extends TestCase { +public final class TestExcelExtractor { - private static ExcelExtractor createExtractor(String sampleFileName) { - - InputStream is = HSSFTestDataSamples.openSampleFileStream(sampleFileName); - - try { - return new ExcelExtractor(new POIFSFileSystem(is)); - } catch (IOException e) { - throw new RuntimeException(e); - } + @SuppressWarnings("resource") + private static ExcelExtractor createExtractor(String sampleFileName) throws IOException { + File file = HSSFTestDataSamples.getSampleFile(sampleFileName); + return new ExcelExtractor(new POIFSFileSystem(file)); } + @Test public void testSimple() throws IOException { ExcelExtractor extractor = createExtractor("Simple.xls"); @@ -60,7 +61,8 @@ public final class TestExcelExtractor extends TestCase { } } - public void testNumericFormula() { + @Test + public void testNumericFormula() throws IOException { ExcelExtractor extractor = createExtractor("sumifformula.xls"); @@ -87,9 +89,12 @@ public final class TestExcelExtractor extends TestCase { "Sheet2\nSheet3\n", extractor.getText() ); + + extractor.close(); } - public void testwithContinueRecords() { + @Test + public void testwithContinueRecords() throws IOException { ExcelExtractor extractor = createExtractor("StringContinueRecords.xls"); @@ -99,9 +104,12 @@ public final class TestExcelExtractor extends TestCase { // Until we fixed bug #41064, this would've // failed by now assertTrue(extractor.getText().length() > 40960); + + extractor.close(); } - public void testStringConcat() { + @Test + public void testStringConcat() throws IOException { ExcelExtractor extractor = createExtractor("SimpleWithFormula.xls"); @@ -112,9 +120,12 @@ public final class TestExcelExtractor extends TestCase { extractor.setFormulasNotResults(true); assertEquals("Sheet1\nreplaceme\nreplaceme\nCONCATENATE(A1,A2)\nSheet2\nSheet3\n", extractor.getText()); + + extractor.close(); } - public void testStringFormula() { + @Test + public void testStringFormula() throws IOException { ExcelExtractor extractor = createExtractor("StringFormulas.xls"); @@ -125,40 +136,49 @@ public final class TestExcelExtractor extends TestCase { extractor.setFormulasNotResults(true); assertEquals("Sheet1\nUPPER(\"xyz\")\nSheet2\nSheet3\n", extractor.getText()); + + extractor.close(); } - public void testEventExtractor() throws Exception { + @Test + public void testEventExtractor() throws Exception { // First up, a simple file with string // based formulas in it - EventBasedExcelExtractor extractor = new EventBasedExcelExtractor( - new POIFSFileSystem( - HSSFTestDataSamples.openSampleFileStream("SimpleWithFormula.xls") - ) - ); + EventBasedExcelExtractor extractor1 = null; try { - extractor.setIncludeSheetNames(true); - - String text = extractor.getText(); + extractor1 = new EventBasedExcelExtractor( + new POIFSFileSystem( + HSSFTestDataSamples.openSampleFileStream("SimpleWithFormula.xls") + ) + ); + extractor1.setIncludeSheetNames(true); + + String text = extractor1.getText(); assertEquals("Sheet1\nreplaceme\nreplaceme\nreplacemereplaceme\nSheet2\nSheet3\n", text); - extractor.setIncludeSheetNames(false); - extractor.setFormulasNotResults(true); + extractor1.setIncludeSheetNames(false); + extractor1.setFormulasNotResults(true); - text = extractor.getText(); + text = extractor1.getText(); assertEquals("replaceme\nreplaceme\nCONCATENATE(A1,A2)\n", text); + } finally { + if (extractor1 != null) extractor1.close(); + } + + // Now, a slightly longer file with numeric formulas + EventBasedExcelExtractor extractor2 = null; + try { + extractor2 = new EventBasedExcelExtractor( + new POIFSFileSystem( + HSSFTestDataSamples.openSampleFileStream("sumifformula.xls") + ) + ); + + extractor2.setIncludeSheetNames(false); + extractor2.setFormulasNotResults(true); - - // Now, a slightly longer file with numeric formulas - extractor = new EventBasedExcelExtractor( - new POIFSFileSystem( - HSSFTestDataSamples.openSampleFileStream("sumifformula.xls") - ) - ); - extractor.setIncludeSheetNames(false); - extractor.setFormulasNotResults(true); - - text = extractor.getText(); + String text = extractor2.getText(); assertEquals( "1000\t1\tSUMIF(A1:A5,\">4000\",B1:B5)\n" + "2000\t2\n" + @@ -168,11 +188,12 @@ public final class TestExcelExtractor extends TestCase { text ); } finally { - extractor.close(); + if (extractor2 != null) extractor2.close(); } } - public void testWithComments() { + @Test + public void testWithComments() throws IOException { ExcelExtractor extractor = createExtractor("SimpleWithComments.xls"); extractor.setIncludeSheetNames(false); @@ -192,9 +213,12 @@ public final class TestExcelExtractor extends TestCase { "3\tthree Comment by Yegor Kozlov: Yegor Kozlov: third cell\n", extractor.getText() ); + + extractor.close(); } - public void testWithBlank() { + @Test + public void testWithBlank() throws IOException { ExcelExtractor extractor = createExtractor("MissingBits.xls"); String def = extractor.getText(); extractor.setIncludeBlankCells(true); @@ -213,136 +237,145 @@ public final class TestExcelExtractor extends TestCase { "Hello\n" + "11\t\t\t23\n" )); + + extractor.close(); } - public void testFormatting() throws Exception { - ExcelExtractor extractor = createExtractor("Formatting.xls"); - extractor.setIncludeBlankCells(false); - extractor.setIncludeSheetNames(false); - String text = extractor.getText(); - - // Note - not all the formats in the file - // actually quite match what they claim to - // be, as some are auto-local builtins... - - assertTrue(text.startsWith( - "Dates, all 24th November 2006\n" - )); - assertTrue( - text.indexOf( - "yyyy/mm/dd\t2006/11/24\n" - ) > -1 - ); - assertTrue( - text.indexOf( - "yyyy-mm-dd\t2006-11-24\n" - ) > -1 - ); - assertTrue( - text.indexOf( - "dd-mm-yy\t24-11-06\n" - ) > -1 - ); - - assertTrue("Had: " + text + ", but should contain 'nn.nn\\t10.52\\n'", - text.indexOf( - "nn.nn\t10.52\n" - ) > -1 - ); - assertTrue( - text.indexOf( - "nn.nnn\t10.520\n" - ) > -1 - ); - assertTrue( - text.indexOf( - "\u00a3nn.nn\t\u00a310.52\n" - ) > -1 - ); + @Test + public void testFormatting() throws Exception { + Locale userLocale = LocaleUtil.getUserLocale(); + LocaleUtil.setUserLocale(Locale.ROOT); + try { + ExcelExtractor extractor = createExtractor("Formatting.xls"); + extractor.setIncludeBlankCells(false); + extractor.setIncludeSheetNames(false); + String text = extractor.getText(); + + // Note - not all the formats in the file + // actually quite match what they claim to + // be, as some are auto-local builtins... + + assertTrue(text.startsWith( + "Dates, all 24th November 2006\n" + )); + assertTrue( + text.indexOf( + "yyyy/mm/dd\t2006/11/24\n" + ) > -1 + ); + assertTrue( + text.indexOf( + "yyyy-mm-dd\t2006-11-24\n" + ) > -1 + ); + assertTrue( + text.indexOf( + "dd-mm-yy\t24-11-06\n" + ) > -1 + ); + + assertTrue("Had: " + text + ", but should contain 'nn.nn\\t10.52\\n'", + text.indexOf( + "nn.nn\t10.52\n" + ) > -1 + ); + assertTrue( + text.indexOf( + "nn.nnn\t10.520\n" + ) > -1 + ); + assertTrue( + text.indexOf( + "\u00a3nn.nn\t\u00a310.52\n" + ) > -1 + ); + extractor.close(); + } finally { + LocaleUtil.setUserLocale(userLocale); + } } /** * Embeded in a non-excel file */ - public void testWithEmbeded() throws Exception { - POIFSFileSystem fs = new POIFSFileSystem( - POIDataSamples.getDocumentInstance().openResourceAsStream("word_with_embeded.doc") - ); + @Test + public void testWithEmbeded() throws Exception { + POIFSFileSystem fs = null; + + HSSFWorkbook wbA = null, wbB = null; + ExcelExtractor exA = null, exB = null; - DirectoryNode objPool = (DirectoryNode) fs.getRoot().getEntry("ObjectPool"); - DirectoryNode dirA = (DirectoryNode) objPool.getEntry("_1269427460"); - DirectoryNode dirB = (DirectoryNode) objPool.getEntry("_1269427461"); - - HSSFWorkbook wbA = new HSSFWorkbook(dirA, fs, true); - HSSFWorkbook wbB = new HSSFWorkbook(dirB, fs, true); - - ExcelExtractor exA = new ExcelExtractor(wbA); try { - ExcelExtractor exB = new ExcelExtractor(wbB); - try { - assertEquals("Sheet1\nTest excel file\nThis is the first file\nSheet2\nSheet3\n", - exA.getText()); - assertEquals("Sample Excel", exA.getSummaryInformation().getTitle()); - - assertEquals("Sheet1\nAnother excel file\nThis is the second file\nSheet2\nSheet3\n", - exB.getText()); - assertEquals("Sample Excel 2", exB.getSummaryInformation().getTitle()); - } finally { - exB.close(); - } + fs = new POIFSFileSystem(POIDataSamples.getDocumentInstance().getFile("word_with_embeded.doc")); + + DirectoryNode objPool = (DirectoryNode) fs.getRoot().getEntry("ObjectPool"); + DirectoryNode dirA = (DirectoryNode) objPool.getEntry("_1269427460"); + DirectoryNode dirB = (DirectoryNode) objPool.getEntry("_1269427461"); + + wbA = new HSSFWorkbook(dirA, fs, true); + exA = new ExcelExtractor(wbA); + wbB = new HSSFWorkbook(dirB, fs, true); + exB = new ExcelExtractor(wbB); + + assertEquals("Sheet1\nTest excel file\nThis is the first file\nSheet2\nSheet3\n", exA.getText()); + assertEquals("Sample Excel", exA.getSummaryInformation().getTitle()); + assertEquals("Sheet1\nAnother excel file\nThis is the second file\nSheet2\nSheet3\n", exB.getText()); + assertEquals("Sample Excel 2", exB.getSummaryInformation().getTitle()); } finally { - exA.close(); + if (exB != null) exB.close(); + if (wbB != null) wbB.close(); + if (exA != null) exA.close(); + if (wbA != null) wbA.close(); + if (fs != null) fs.close(); } } /** * Excel embeded in excel */ - public void testWithEmbededInOwn() throws Exception { + @Test + public void testWithEmbededInOwn() throws Exception { POIDataSamples ssSamples = POIDataSamples.getSpreadSheetInstance(); - POIFSFileSystem fs = new POIFSFileSystem( - ssSamples.openResourceAsStream("excel_with_embeded.xls") - ); + POIFSFileSystem fs = null; + HSSFWorkbook wbA = null, wbB = null; + ExcelExtractor exA = null, exB = null, ex = null; - DirectoryNode dirA = (DirectoryNode) fs.getRoot().getEntry("MBD0000A3B5"); - DirectoryNode dirB = (DirectoryNode) fs.getRoot().getEntry("MBD0000A3B4"); - - HSSFWorkbook wbA = new HSSFWorkbook(dirA, fs, true); - HSSFWorkbook wbB = new HSSFWorkbook(dirB, fs, true); - - ExcelExtractor exA = new ExcelExtractor(wbA); try { - ExcelExtractor exB = new ExcelExtractor(wbB); - try { - assertEquals("Sheet1\nTest excel file\nThis is the first file\nSheet2\nSheet3\n", - exA.getText()); - assertEquals("Sample Excel", exA.getSummaryInformation().getTitle()); + fs = new POIFSFileSystem(ssSamples.getFile("excel_with_embeded.xls")); + + DirectoryNode dirA = (DirectoryNode) fs.getRoot().getEntry("MBD0000A3B5"); + DirectoryNode dirB = (DirectoryNode) fs.getRoot().getEntry("MBD0000A3B4"); + + wbA = new HSSFWorkbook(dirA, fs, true); + wbB = new HSSFWorkbook(dirB, fs, true); + + exA = new ExcelExtractor(wbA); + exB = new ExcelExtractor(wbB); + assertEquals("Sheet1\nTest excel file\nThis is the first file\nSheet2\nSheet3\n", exA.getText()); + assertEquals("Sample Excel", exA.getSummaryInformation().getTitle()); + + assertEquals("Sheet1\nAnother excel file\nThis is the second file\nSheet2\nSheet3\n", exB.getText()); + assertEquals("Sample Excel 2", exB.getSummaryInformation().getTitle()); - assertEquals("Sheet1\nAnother excel file\nThis is the second file\nSheet2\nSheet3\n", - exB.getText()); - assertEquals("Sample Excel 2", exB.getSummaryInformation().getTitle()); - - // And the base file too - ExcelExtractor ex = new ExcelExtractor(fs); - try { - assertEquals("Sheet1\nI have lots of embeded files in me\nSheet2\nSheet3\n", - ex.getText()); - assertEquals("Excel With Embeded", ex.getSummaryInformation().getTitle()); - } finally { - ex.close(); - } - } finally { - exB.close(); - } - } finally { - exA.close(); + // And the base file too + ex = new ExcelExtractor(fs); + assertEquals("Sheet1\nI have lots of embeded files in me\nSheet2\nSheet3\n", ex.getText()); + assertEquals("Excel With Embeded", ex.getSummaryInformation().getTitle()); + } finally { + if (ex != null) ex.close(); + if (exB != null) exB.close(); + if (exA != null) exA.close(); + if (wbB != null) wbB.close(); + if (wbA != null) wbA.close(); + if (fs != null) fs.close(); } } /** * Test that we get text from headers and footers */ - public void test45538() { + @Test + public void test45538() throws IOException { String[] files = { "45538_classic_Footer.xls", "45538_form_Footer.xls", "45538_classic_Header.xls", "45538_form_Header.xls" @@ -352,21 +385,26 @@ public final class TestExcelExtractor extends TestCase { String text = extractor.getText(); assertTrue("Unable to find expected word in text\n" + text, text.indexOf("testdoc") >=0); assertTrue("Unable to find expected word in text\n" + text, text.indexOf("test phrase") >= 0); + extractor.close(); } } - public void testPassword() { + @Test + public void testPassword() throws IOException { Biff8EncryptionKey.setCurrentUserPassword("password"); ExcelExtractor extractor = createExtractor("password.xls"); String text = extractor.getText(); Biff8EncryptionKey.setCurrentUserPassword(null); assertTrue(text.contains("ZIP")); + extractor.close(); } - public void testNullPointerException() { + @Test + public void testNullPointerException() throws IOException { ExcelExtractor extractor = createExtractor("ar.org.apsme.www_Form%20Inscripcion%20Curso%20NO%20Socios.xls"); assertNotNull(extractor); assertNotNull(extractor.getText()); + extractor.close(); } } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java index e15453da9..f472e3d1d 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java @@ -36,9 +36,9 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; -import java.util.Date; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.TimeZone; import org.apache.poi.EncryptedDocumentException; @@ -69,13 +69,13 @@ import org.apache.poi.ss.usermodel.BaseTestBugzillaIssues; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.DataFormatter; -import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.FormulaEvaluator; import org.apache.poi.ss.usermodel.Name; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.TempFile; import org.junit.Ignore; import org.junit.Test; @@ -2193,10 +2193,9 @@ public final class TestBugs extends BaseTestBugzillaIssues { @Test public void bug48968() throws Exception { - TimeZone tz = DateUtil.getUserTimeZone(); - try { - DateUtil.setUserTimeZone(TimeZone.getTimeZone("CET")); - + TimeZone userTimeZone = LocaleUtil.getUserTimeZone(); + LocaleUtil.setUserTimeZone(TimeZone.getTimeZone("CET")); + try { HSSFWorkbook wb = openSample("48968.xls"); assertEquals(1, wb.getNumberOfSheets()); @@ -2241,9 +2240,9 @@ public final class TestBugs extends BaseTestBugzillaIssues { assertEquals(39.0+14.0+1, s.getRow(6).getCell(0).getNumericCellValue(), 0); assertEquals("SECOND(A1)", s.getRow(7).getCell(0).getCellFormula()); assertEquals(54.0+24.0-60, s.getRow(7).getCell(0).getNumericCellValue(), 0); - } finally { - DateUtil.setUserTimeZone(tz); - } + } finally { + LocaleUtil.setUserTimeZone(userTimeZone); + } } @@ -2474,12 +2473,13 @@ public final class TestBugs extends BaseTestBugzillaIssues { Sheet sheet = wb.getSheet("test-sheet"); int rowCount = sheet.getLastRowNum() + 1; int newRows = 5; + Calendar cal = LocaleUtil.getLocaleCalendar(); for (int r = rowCount; r < rowCount + newRows; r++) { Row row = sheet.createRow((short) r); row.createCell(0).setCellValue(1.03 * (r + 7)); - row.createCell(1).setCellValue(new Date()); - row.createCell(2).setCellValue(Calendar.getInstance()); - row.createCell(3).setCellValue(String.format("row:%d/col:%d", r, 3)); + row.createCell(1).setCellValue(cal.getTime()); + row.createCell(2).setCellValue(cal); + row.createCell(3).setCellValue(String.format(Locale.ROOT, "row:%d/col:%d", r, 3)); row.createCell(4).setCellValue(true); row.createCell(5).setCellType(Cell.CELL_TYPE_ERROR); row.createCell(6).setCellValue("added cells."); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestCellStyle.java b/src/testcases/org/apache/poi/hssf/usermodel/TestCellStyle.java index 759363a29..002803486 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestCellStyle.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestCellStyle.java @@ -32,12 +32,11 @@ import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.TempFile; /** * Class to test cell styling functionality - * - * @author Andrew C. Oliver */ public final class TestCellStyle extends TestCase { @@ -115,8 +114,7 @@ public final class TestCellStyle extends TestCase { cell = row.createCell(2); cs.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy")); cell.setCellStyle(cs); - Calendar cal = Calendar.getInstance(); - cal.setTime(new Date()); + Calendar cal = LocaleUtil.getLocaleCalendar(); cell.setCellValue(cal); wb.write(out); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java index b18cfe9ce..eb59e8a75 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java @@ -17,15 +17,14 @@ package org.apache.poi.hssf.usermodel; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + import java.io.File; import java.io.FileOutputStream; import java.util.Calendar; -import java.util.GregorianCalendar; import java.util.Iterator; -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; - import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.record.FormulaRecord; import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; @@ -43,15 +42,19 @@ import org.apache.poi.ss.formula.ptg.RefPtg; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.util.CellReference; +import org.apache.poi.util.LocaleUtil; +import org.junit.BeforeClass; +import org.junit.Test; /** * */ -public final class TestFormulaEvaluatorBugs extends TestCase { +public final class TestFormulaEvaluatorBugs { private static boolean OUTPUT_TEST_FILES = false; - private String tmpDirName; + private static String tmpDirName; - protected void setUp() { + @BeforeClass + public static void setUp() { tmpDirName = System.getProperty("java.io.tmpdir"); OUTPUT_TEST_FILES = Boolean.parseBoolean( System.getProperty("org.apache.poi.test.output_test_files", "False")); @@ -66,6 +69,7 @@ public final class TestFormulaEvaluatorBugs extends TestCase { * WARNING - tedious bug where you actually have to * open up excel */ + @Test public void test44636() throws Exception { // Open the existing file, tweak one value and // re-calculate @@ -80,15 +84,16 @@ public final class TestFormulaEvaluatorBugs extends TestCase { HSSFFormulaEvaluator.evaluateAllFormulaCells(wb); assertEquals(4.2 * 25, row.getCell(3).getNumericCellValue(), 0.0001); - FileOutputStream out; if (OUTPUT_TEST_FILES) { // Save File existing = new File(tmpDirName, "44636-existing.xls"); - out = new FileOutputStream(existing); + FileOutputStream out = new FileOutputStream(existing); wb.write(out); out.close(); System.err.println("Existing file for bug #44636 written to " + existing.toString()); } + wb.close(); + // Now, do a new file from scratch wb = new HSSFWorkbook(); sheet = wb.createSheet(); @@ -106,21 +111,21 @@ public final class TestFormulaEvaluatorBugs extends TestCase { if (OUTPUT_TEST_FILES) { // Save File scratch = new File(tmpDirName, "44636-scratch.xls"); - out = new FileOutputStream(scratch); + FileOutputStream out = new FileOutputStream(scratch); wb.write(out); out.close(); System.err.println("New file for bug #44636 written to " + scratch.toString()); } + wb.close(); } /** * Bug 44297: 32767+32768 is evaluated to -1 * Fix: IntPtg must operate with unsigned short. Reading signed short results in incorrect formula calculation * if a formula has values in the interval [Short.MAX_VALUE, (Short.MAX_VALUE+1)*2] - * - * @author Yegor Kozlov */ - public void test44297() { + @Test + public void test44297() throws Exception { HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("44297.xls"); @@ -175,13 +180,16 @@ public final class TestFormulaEvaluatorBugs extends TestCase { cell = row.getCell(0); assertEquals("-1000000-3000000", cell.getCellFormula()); assertEquals(-4000000, eva.evaluate(cell).getNumberValue(), 0); + + wb.close(); } /** * Bug 44410: SUM(C:C) is valid in excel, and means a sum * of all the rows in Column C */ - public void test44410() { + @Test + public void test44410() throws Exception { HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("SingleLetterRanges.xls"); HSSFSheet sheet = wb.getSheetAt(0); @@ -233,12 +241,15 @@ public final class TestFormulaEvaluatorBugs extends TestCase { HSSFCell cellSUM2D = rowSUM2D.getCell(0); assertEquals("SUM(C:D)", cellSUM2D.getCellFormula()); assertEquals(66, eva.evaluate(cellSUM2D).getNumberValue(), 0); + + wb.close(); } /** * Tests that we can evaluate boolean cells properly */ - public void testEvaluateBooleanInCell_bug44508() { + @Test + public void testEvaluateBooleanInCell_bug44508() throws Exception { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet(); wb.setSheetName(0, "Sheet1"); @@ -254,9 +265,12 @@ public final class TestFormulaEvaluatorBugs extends TestCase { fail("Identified bug 44508"); } assertEquals(true, cell.getBooleanCellValue()); + + wb.close(); } - public void testClassCast_bug44861() { + @Test + public void testClassCast_bug44861() throws Exception { HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("44861.xls"); // Check direct @@ -276,9 +290,12 @@ public final class TestFormulaEvaluatorBugs extends TestCase { } } } + + wb.close(); } - public void testEvaluateInCellWithErrorCode_bug44950() { + @Test + public void testEvaluateInCellWithErrorCode_bug44950() throws Exception { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet("Sheet1"); HSSFRow row = sheet.createRow(1); @@ -289,13 +306,16 @@ public final class TestFormulaEvaluatorBugs extends TestCase { fe.evaluateInCell(cell); } catch (NumberFormatException e) { if (e.getMessage().equals("You cannot get an error value from a non-error cell")) { - throw new AssertionFailedError("Identified bug 44950 b"); + fail("Identified bug 44950 b"); } throw e; + } finally { + wb.close(); } } - public void testDateWithNegativeParts_bug48528() { + @Test + public void testDateWithNegativeParts_bug48528() throws Exception { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet("Sheet1"); HSSFRow row = sheet.createRow(1); @@ -310,31 +330,33 @@ public final class TestFormulaEvaluatorBugs extends TestCase { cell.setCellFormula("DATE(2012,2,1)"); fe.notifyUpdateCell(cell); - assertEquals(40940.0, fe.evaluate(cell).getNumberValue()); + assertEquals(40940.0, fe.evaluate(cell).getNumberValue(), 0); cell.setCellFormula("DATE(2012,2,1+4)"); fe.notifyUpdateCell(cell); - assertEquals(40944.0, fe.evaluate(cell).getNumberValue()); + assertEquals(40944.0, fe.evaluate(cell).getNumberValue(), 0); cell.setCellFormula("DATE(2012,2-1,1+4)"); fe.notifyUpdateCell(cell); - assertEquals(40913.0, fe.evaluate(cell).getNumberValue()); + assertEquals(40913.0, fe.evaluate(cell).getNumberValue(), 0); cell.setCellFormula("DATE(2012,2,1-27)"); fe.notifyUpdateCell(cell); - assertEquals(40913.0, fe.evaluate(cell).getNumberValue()); + assertEquals(40913.0, fe.evaluate(cell).getNumberValue(), 0); cell.setCellFormula("DATE(2012,2-2,1+4)"); fe.notifyUpdateCell(cell); - assertEquals(40882.0, fe.evaluate(cell).getNumberValue()); + assertEquals(40882.0, fe.evaluate(cell).getNumberValue(), 0); cell.setCellFormula("DATE(2012,2,1-58)"); fe.notifyUpdateCell(cell); - assertEquals(40882.0, fe.evaluate(cell).getNumberValue()); + assertEquals(40882.0, fe.evaluate(cell).getNumberValue(), 0); cell.setCellFormula("DATE(2012,2-12,1+4)"); fe.notifyUpdateCell(cell); - assertEquals(40579.0, fe.evaluate(cell).getNumberValue()); + assertEquals(40579.0, fe.evaluate(cell).getNumberValue(), 0); + + wb.close(); } private static final class EvalListener extends EvaluationListener { @@ -363,7 +385,8 @@ public final class TestFormulaEvaluatorBugs extends TestCase { /** * The HSSFFormula evaluator performance benefits greatly from caching of intermediate cell values */ - public void testSlowEvaluate45376() { + @Test + public void testSlowEvaluate45376() throws Exception { /* * Note - to observe behaviour without caching, disable the call to * updateValue() from FormulaCellCacheEntry.updateFormulaResult(). @@ -384,7 +407,7 @@ public final class TestFormulaEvaluatorBugs extends TestCase { "DATE(YEAR(" + prevCell + "),MONTH(" + prevCell + ")+1,1),NA())"; cell.setCellFormula(formula); } - Calendar cal = new GregorianCalendar(2000, 0, 1, 0, 0, 0); + Calendar cal = LocaleUtil.getLocaleCalendar(2000, 0, 1, 0, 0, 0); row.createCell(0).setCellValue(cal); // Choose cell A9 instead of A10, so that the failing test case doesn't take too long to execute. @@ -397,8 +420,8 @@ public final class TestFormulaEvaluatorBugs extends TestCase { // Without caching, evaluating cell 'A9' takes 21845 evaluations which consumes // much time (~3 sec on Core 2 Duo 2.2GHz) // short-circuit-if optimisation cuts this down to 255 evaluations which is still too high - System.err.println("Cell A9 took " + evalCount + " intermediate evaluations"); - throw new AssertionFailedError("Identifed bug 45376 - Formula evaluator should cache values"); + // System.err.println("Cell A9 took " + evalCount + " intermediate evaluations"); + fail("Identifed bug 45376 - Formula evaluator should cache values"); } // With caching, the evaluationCount is 8 which is exactly the // number of formula cells that needed to be evaluated. @@ -413,9 +436,12 @@ public final class TestFormulaEvaluatorBugs extends TestCase { // confirm the evaluation result too assertEquals(ErrorEval.NA, ve); + + wb.close(); } @SuppressWarnings("resource") + @Test public void test55747_55324() throws Exception { HSSFWorkbook wb = new HSSFWorkbook(); HSSFFormulaEvaluator ev = wb.getCreationHelper().createFormulaEvaluator(); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFCell.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFCell.java index 015edf41d..a512f52f1 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFCell.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFCell.java @@ -17,12 +17,15 @@ package org.apache.poi.hssf.usermodel; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + import java.io.IOException; import java.util.Calendar; import java.util.Date; -import java.util.GregorianCalendar; -import java.util.Locale; -import java.util.TimeZone; import org.apache.poi.hssf.HSSFITestDataProvider; import org.apache.poi.hssf.HSSFTestDataSamples; @@ -38,15 +41,14 @@ import org.apache.poi.ss.usermodel.RichTextString; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.util.LocaleUtil; +import org.junit.Test; import junit.framework.AssertionFailedError; /** * Tests various functionality having to do with {@link HSSFCell}. For instance support for * particular datatypes, etc. - * @author Andrew C. Oliver (andy at superlinksoftware dot com) - * @author Dan Sherman (dsherman at isisph.com) - * @author Alex Jacoby (ajacoby at gmail.com) */ public final class TestHSSFCell extends BaseTestCell { @@ -59,27 +61,28 @@ public final class TestHSSFCell extends BaseTestCell { * is working properly. Conversion of the date is also an issue, * but there's a separate unit test for that. */ - public void testDateWindowingRead() { - Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ROOT); - cal.set(2000, 0, 1, 0, 0, 0); // Jan. 1, 2000 - cal.clear(Calendar.MILLISECOND); + @Test + public void testDateWindowingRead() throws Exception { + Calendar cal = LocaleUtil.getLocaleCalendar(2000, 0, 1, 0, 0, 0);// Jan. 1, 2000 Date date = cal.getTime(); // first check a file with 1900 Date Windowing - HSSFWorkbook workbook = HSSFTestDataSamples.openSampleWorkbook("1900DateWindowing.xls"); - HSSFSheet sheet = workbook.getSheetAt(0); + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("1900DateWindowing.xls"); + HSSFSheet sheet = wb.getSheetAt(0); assertEquals("Date from file using 1900 Date Windowing", date.getTime(), sheet.getRow(0).getCell(0).getDateCellValue().getTime()); + wb.close(); // now check a file with 1904 Date Windowing - workbook = HSSFTestDataSamples.openSampleWorkbook("1904DateWindowing.xls"); - sheet = workbook.getSheetAt(0); + wb = HSSFTestDataSamples.openSampleWorkbook("1904DateWindowing.xls"); + sheet = wb.getSheetAt(0); assertEquals("Date from file using 1904 Date Windowing", date.getTime(), sheet.getRow(0).getCell(0).getDateCellValue().getTime()); + wb.close(); } @@ -90,28 +93,32 @@ public final class TestHSSFCell extends BaseTestCell { * previous test ({@link #testDateWindowingRead}) fails, the * results of this test are meaningless. */ - public void testDateWindowingWrite() { - GregorianCalendar cal = new GregorianCalendar(2000,0,1); // Jan. 1, 2000 + @Test + public void testDateWindowingWrite() throws Exception { + Calendar cal = LocaleUtil.getLocaleCalendar(2000,0,1,0,0,0); // Jan. 1, 2000 Date date = cal.getTime(); // first check a file with 1900 Date Windowing - HSSFWorkbook wb; - wb = HSSFTestDataSamples.openSampleWorkbook("1900DateWindowing.xls"); + HSSFWorkbook wb1 = HSSFTestDataSamples.openSampleWorkbook("1900DateWindowing.xls"); - setCell(wb, 0, 1, date); - wb = HSSFTestDataSamples.writeOutAndReadBack(wb); + setCell(wb1, 0, 1, date); + HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1); assertEquals("Date from file using 1900 Date Windowing", date.getTime(), - readCell(wb, 0, 1).getTime()); + readCell(wb2, 0, 1).getTime()); + wb1.close(); + wb2.close(); // now check a file with 1904 Date Windowing - wb = HSSFTestDataSamples.openSampleWorkbook("1904DateWindowing.xls"); - setCell(wb, 0, 1, date); - wb = HSSFTestDataSamples.writeOutAndReadBack(wb); + wb1 = HSSFTestDataSamples.openSampleWorkbook("1904DateWindowing.xls"); + setCell(wb1, 0, 1, date); + wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1); assertEquals("Date from file using 1900 Date Windowing", date.getTime(), - readCell(wb, 0, 1).getTime()); + readCell(wb2, 0, 1).getTime()); + wb1.close(); + wb2.close(); } private static void setCell(HSSFWorkbook workbook, int rowIdx, int colIdx, Date date) { @@ -135,12 +142,13 @@ public final class TestHSSFCell extends BaseTestCell { /** * Tests that the active cell can be correctly read and set */ - public void testActiveCell() { + @Test + public void testActiveCell() throws Exception { //read in sample - HSSFWorkbook book = HSSFTestDataSamples.openSampleWorkbook("Simple.xls"); + HSSFWorkbook wb1 = HSSFTestDataSamples.openSampleWorkbook("Simple.xls"); //check initial position - HSSFSheet umSheet = book.getSheetAt(0); + HSSFSheet umSheet = wb1.getSheetAt(0); InternalSheet s = umSheet.getSheet(); assertEquals("Initial active cell should be in col 0", (short) 0, s.getActiveCellCol()); @@ -156,18 +164,22 @@ public final class TestHSSFCell extends BaseTestCell { 3, s.getActiveCellRow()); //write book to temp file; read and verify that position is serialized - book = HSSFTestDataSamples.writeOutAndReadBack(book); + HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1); + wb1.close(); - umSheet = book.getSheetAt(0); + umSheet = wb2.getSheetAt(0); s = umSheet.getSheet(); assertEquals("After serialize, active cell should be in col 2", (short) 2, s.getActiveCellCol()); assertEquals("After serialize, active cell should be on row 3", 3, s.getActiveCellRow()); + + wb2.close(); } + @Test public void testActiveCellBug56114() throws IOException { Workbook wb = new HSSFWorkbook(); Sheet sh = wb.createSheet(); @@ -222,7 +234,8 @@ public final class TestHSSFCell extends BaseTestCell { /** * Test reading hyperlinks */ - public void testWithHyperlink() { + @Test + public void testWithHyperlink() throws Exception { HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("WithHyperlink.xls"); @@ -235,12 +248,15 @@ public final class TestHSSFCell extends BaseTestCell { assertEquals("http://poi.apache.org/", link.getAddress()); assertEquals(4, link.getFirstRow()); assertEquals(0, link.getFirstColumn()); + + wb.close(); } /** * Test reading hyperlinks */ - public void testWithTwoHyperlinks() { + @Test + public void testWithTwoHyperlinks() throws Exception { HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("WithTwoHyperLinks.xls"); @@ -261,13 +277,16 @@ public final class TestHSSFCell extends BaseTestCell { assertEquals("http://poi.apache.org/hssf/", link2.getAddress()); assertEquals(8, link2.getFirstRow()); assertEquals(1, link2.getFirstColumn()); + + wb.close(); } /** * Test to ensure we can only assign cell styles that belong * to our workbook, and not those from other workbooks. */ - public void testCellStyleWorkbookMatch() { + @Test + public void testCellStyleWorkbookMatch() throws Exception { HSSFWorkbook wbA = new HSSFWorkbook(); HSSFWorkbook wbB = new HSSFWorkbook(); @@ -306,6 +325,9 @@ public final class TestHSSFCell extends BaseTestCell { } catch (IllegalArgumentException e) { // expected during successful test } + + wbB.close(); + wbA.close(); } /** @@ -315,6 +337,7 @@ public final class TestHSSFCell extends BaseTestCell { * versions (prior to bug 46213 / r717883) crash instead. * @throws IOException */ + @Test public void testCachedTypeChange() throws IOException { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet("Sheet1"); @@ -362,22 +385,27 @@ public final class TestHSSFCell extends BaseTestCell { /** * HSSF prior to version 3.7 had a bug: it could write a NaN but could not read such a file back. */ - public void testReadNaN() { + @Test + public void testReadNaN() throws Exception { HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("49761.xls"); assertNotNull(wb); + wb.close(); } - public void testHSSFCell() { + @Test + public void testHSSFCell() throws Exception { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet(); HSSFRow row = sheet.createRow(0); row.createCell(0); HSSFCell cell = new HSSFCell(wb, sheet, 0, (short)0); - assertNotNull(cell); + assertNotNull(cell); + wb.close(); } @SuppressWarnings("deprecation") - public void testDeprecatedMethods() { + @Test + public void testDeprecatedMethods() throws Exception { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet(); HSSFRow row = sheet.createRow(0); @@ -402,8 +430,11 @@ public final class TestHSSFCell extends BaseTestCell { cell.removeCellComment(); cell.removeCellComment(); + + wb.close(); } + @Test public void testCellType() throws IOException { Workbook wb = _testDataProvider.createWorkbook(); Sheet sheet = wb.createSheet(); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDataFormatter.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDataFormatter.java index f1aad88c1..4abffc5ce 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDataFormatter.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDataFormatter.java @@ -17,18 +17,25 @@ package org.apache.poi.hssf.usermodel; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.Format; import java.text.SimpleDateFormat; -import java.util.GregorianCalendar; +import java.util.Calendar; import java.util.Iterator; +import java.util.Locale; +import java.util.TimeZone; import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.DateUtil; - -import junit.framework.TestCase; +import org.apache.poi.util.LocaleUtil; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; /** * Unit tests for HSSFDataFormatter.java @@ -36,9 +43,25 @@ import junit.framework.TestCase; * @author James May (james dot may at fmr dot com) * */ -public final class TestHSSFDataFormatter extends TestCase { +public final class TestHSSFDataFormatter { - private final HSSFDataFormatter formatter; + private static TimeZone userTimeZone; + + @BeforeClass + public static void setTimeZone() { + userTimeZone = LocaleUtil.getUserTimeZone(); + LocaleUtil.setUserTimeZone(TimeZone.getTimeZone("CET")); + LocaleUtil.setUserLocale(Locale.US); + } + + @AfterClass + public static void resetTimeZone() { + LocaleUtil.setUserTimeZone(userTimeZone); + LocaleUtil.setUserLocale(Locale.ROOT); + } + + + private final HSSFDataFormatter formatter; private final HSSFWorkbook wb; public TestHSSFDataFormatter() { @@ -197,6 +220,7 @@ public final class TestHSSFDataFormatter extends TestCase { /** * Test getting formatted values from numeric and date cells. */ + @Test public void testGetFormattedCellValueHSSFCell() { // Valid date formats -- cell values should be date formatted & not "555.555" HSSFRow row = wb.getSheetAt(0).getRow(0); @@ -216,7 +240,9 @@ public final class TestHSSFDataFormatter extends TestCase { //assert the correct month form, as in the original Excel format String monthPtrn = fmt.indexOf("mmmm") != -1 ? "MMMM" : "MMM"; // this line is intended to compute how "July" would look like in the current locale - String jul = new SimpleDateFormat(monthPtrn).format(new GregorianCalendar(2010,6,15).getTime()); + SimpleDateFormat sdf = new SimpleDateFormat(monthPtrn, LocaleUtil.getUserLocale()); + Calendar calDef = LocaleUtil.getLocaleCalendar(2010, 6, 15, 0, 0, 0); + String jul = sdf.format(calDef.getTime()); // special case for MMMMM = 1st letter of month name if(fmt.indexOf("mmmmm") > -1) { jul = jul.substring(0,1); @@ -228,7 +254,6 @@ public final class TestHSSFDataFormatter extends TestCase { row = wb.getSheetAt(0).getRow(1); it = row.cellIterator(); log("==== VALID TIME FORMATS ===="); - while (it.hasNext()) { Cell cell = it.next(); String fmt = cell.getCellStyle().getDataFormatString(); @@ -265,7 +290,7 @@ public final class TestHSSFDataFormatter extends TestCase { log(formatter.formatCellValue(cell)); // should be equal to "1234567890.12345" // in some locales the the decimal delimiter is a comma, not a dot - char decimalSeparator = new DecimalFormatSymbols().getDecimalSeparator(); + char decimalSeparator = new DecimalFormatSymbols(LocaleUtil.getUserLocale()).getDecimalSeparator(); assertEquals("1234567890" + decimalSeparator + "12345", formatter.formatCellValue(cell)); } @@ -297,6 +322,7 @@ public final class TestHSSFDataFormatter extends TestCase { assertEquals(formatter.formatCellValue(null), ""); } + @Test public void testGetFormattedCellValueHSSFCellHSSFFormulaEvaluator() { // test formula format HSSFRow row = wb.getSheetAt(0).getRow(7); @@ -310,7 +336,7 @@ public final class TestHSSFDataFormatter extends TestCase { // now with a formula evaluator HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb); log(formatter.formatCellValue(cell, evaluator) + "\t\t\t (with evaluator)"); - char decimalSeparator = new DecimalFormatSymbols().getDecimalSeparator(); + char decimalSeparator = new DecimalFormatSymbols(LocaleUtil.getUserLocale()).getDecimalSeparator(); assertEquals("24" + decimalSeparator + "50%", formatter.formatCellValue(cell,evaluator)); } @@ -319,10 +345,12 @@ public final class TestHSSFDataFormatter extends TestCase { * Test using a default number format. The format should be used when a * format pattern cannot be parsed by DecimalFormat. */ + @Test public void testSetDefaultNumberFormat() { HSSFRow row = wb.getSheetAt(0).getRow(3); Iterator it = row.cellIterator(); - Format defaultFormat = new DecimalFormat("Balance $#,#00.00 USD;Balance -$#,#00.00 USD"); + DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(LocaleUtil.getUserLocale()); + Format defaultFormat = new DecimalFormat("Balance $#,#00.00 USD;Balance -$#,#00.00 USD", dfs); formatter.setDefaultNumberFormat(defaultFormat); log("\n==== DEFAULT NUMBER FORMAT ===="); @@ -338,6 +366,7 @@ public final class TestHSSFDataFormatter extends TestCase { /** * A format of "@" means use the general format */ + @Test public void testGeneralAtFormat() { HSSFWorkbook workbook = HSSFTestDataSamples.openSampleWorkbook("47154.xls"); HSSFSheet sheet = workbook.getSheetAt(0); @@ -356,6 +385,7 @@ public final class TestHSSFDataFormatter extends TestCase { /** * Tests various formattings of dates and numbers */ + @Test public void testFromFile() { HSSFWorkbook workbook = HSSFTestDataSamples.openSampleWorkbook("Formatting.xls"); HSSFSheet sheet = workbook.getSheetAt(0); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java index 7abd51574..224c2bd7d 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java @@ -17,41 +17,38 @@ package org.apache.poi.hssf.usermodel; -import static org.junit.Assert.*; +import static java.util.Calendar.AUGUST; +import static java.util.Calendar.FEBRUARY; +import static java.util.Calendar.JANUARY; +import static java.util.Calendar.JULY; +import static java.util.Calendar.MARCH; +import static java.util.Calendar.MAY; +import static java.util.Calendar.OCTOBER; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; -import java.util.GregorianCalendar; import java.util.Locale; import java.util.TimeZone; import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.model.InternalWorkbook; import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.util.LocaleUtil; import org.junit.Test; /** * Class TestHSSFDateUtil - * - * - * @author Dan Sherman (dsherman at isisph.com) - * @author Hack Kampbjorn (hak at 2mba.dk) - * @author Pavel Krupets (pkrupets at palmtreebusiness dot com) - * @author Alex Jacoby (ajacoby at gmail.com) - * @version %I%, %G% */ public final class TestHSSFDateUtil { - public static final int CALENDAR_JANUARY = 0; - public static final int CALENDAR_FEBRUARY = 1; - public static final int CALENDAR_MARCH = 2; - public static final int CALENDAR_APRIL = 3; - public static final int CALENDAR_JULY = 6; - public static final int CALENDAR_OCTOBER = 9; - /** * Checks the date conversion functions in the HSSFDateUtil class. */ @@ -59,25 +56,24 @@ public final class TestHSSFDateUtil { public void dateConversion() { // Iteratating over the hours exposes any rounding issues. - for (int hour = 0; hour < 23; hour++) - { - GregorianCalendar date = new GregorianCalendar(2002, 0, 1, - hour, 1, 1); - double excelDate = - HSSFDateUtil.getExcelDate(date.getTime(), false); + Calendar cal = LocaleUtil.getLocaleCalendar(2002,JANUARY,1,0,1,1); + for (int hour = 0; hour < 23; hour++) { + double excelDate = HSSFDateUtil.getExcelDate(cal.getTime(), false); - assertEquals("Checking hour = " + hour, date.getTime().getTime(), + assertEquals("Checking hour = " + hour, cal.getTime().getTime(), HSSFDateUtil.getJavaDate(excelDate, false).getTime()); + + cal.add(Calendar.HOUR_OF_DAY, 1); } // check 1900 and 1904 date windowing conversions double excelDate = 36526.0; // with 1900 windowing, excelDate is Jan. 1, 2000 // with 1904 windowing, excelDate is Jan. 2, 2004 - GregorianCalendar cal = new GregorianCalendar(2000,0,1); // Jan. 1, 2000 + cal.set(2000,JANUARY,1,0,0,0); // Jan. 1, 2000 Date dateIf1900 = cal.getTime(); - cal.add(GregorianCalendar.YEAR,4); // now Jan. 1, 2004 - cal.add(GregorianCalendar.DATE,1); // now Jan. 2, 2004 + cal.add(Calendar.YEAR,4); // now Jan. 1, 2004 + cal.add(Calendar.DATE,1); // now Jan. 2, 2004 Date dateIf1904 = cal.getTime(); // 1900 windowing assertEquals("Checking 1900 Date Windowing", @@ -95,11 +91,9 @@ public final class TestHSSFDateUtil { */ @Test public void excelConversionOnDSTStart() { - TimeZone cet = TimeZone.getTimeZone("Europe/Copenhagen"); - TimeZone.setDefault(cet); - Calendar cal = new GregorianCalendar(2004, CALENDAR_MARCH, 28); + Calendar cal = LocaleUtil.getLocaleCalendar(2004,MARCH,28,0,0,0); for (int hour = 0; hour < 24; hour++) { - + // Skip 02:00 CET as that is the Daylight change time // and Java converts it automatically to 03:00 CEST if (hour == 2) { @@ -108,6 +102,8 @@ public final class TestHSSFDateUtil { cal.set(Calendar.HOUR_OF_DAY, hour); Date javaDate = cal.getTime(); + + double excelDate = HSSFDateUtil.getExcelDate(javaDate, false); double difference = excelDate - Math.floor(excelDate); int differenceInHours = (int) (difference * 24 * 60 + 0.5) / 60; @@ -126,9 +122,7 @@ public final class TestHSSFDateUtil { */ @Test public void javaConversionOnDSTStart() { - TimeZone cet = TimeZone.getTimeZone("Europe/Copenhagen"); - TimeZone.setDefault(cet); - Calendar cal = new GregorianCalendar(2004, CALENDAR_MARCH, 28); + Calendar cal = LocaleUtil.getLocaleCalendar(2004,MARCH,28,0,0,0); double excelDate = HSSFDateUtil.getExcelDate(cal.getTime(), false); double oneHour = 1.0 / 24; double oneMinute = oneHour / 60; @@ -154,9 +148,7 @@ public final class TestHSSFDateUtil { */ @Test public void excelConversionOnDSTEnd() { - TimeZone cet = TimeZone.getTimeZone("Europe/Copenhagen"); - TimeZone.setDefault(cet); - Calendar cal = new GregorianCalendar(2004, CALENDAR_OCTOBER, 31); + Calendar cal = LocaleUtil.getLocaleCalendar(2004,OCTOBER,31,0,0,0); for (int hour = 0; hour < 24; hour++) { cal.set(Calendar.HOUR_OF_DAY, hour); Date javaDate = cal.getTime(); @@ -178,9 +170,7 @@ public final class TestHSSFDateUtil { */ @Test public void javaConversionOnDSTEnd() { - TimeZone cet = TimeZone.getTimeZone("Europe/Copenhagen"); - TimeZone.setDefault(cet); - Calendar cal = new GregorianCalendar(2004, CALENDAR_OCTOBER, 31); + Calendar cal = LocaleUtil.getLocaleCalendar(2004,OCTOBER,31,0,0,0); double excelDate = HSSFDateUtil.getExcelDate(cal.getTime(), false); double oneHour = 1.0 / 24; double oneMinute = oneHour / 60; @@ -198,40 +188,45 @@ public final class TestHSSFDateUtil { */ @Test public void calendarConversion() { - GregorianCalendar date = new GregorianCalendar(2002, 0, 1, 12, 1, 1); - Date expected = date.getTime(); - - // Iterating over the hours exposes any rounding issues. - for (int hour = -12; hour <= 12; hour++) - { - String id = "GMT" + (hour < 0 ? "" : "+") + hour + ":00"; - date.setTimeZone(TimeZone.getTimeZone(id)); - date.set(Calendar.HOUR_OF_DAY, 12); - double excelDate = HSSFDateUtil.getExcelDate(date, false); - Date javaDate = HSSFDateUtil.getJavaDate(excelDate); - - // Should match despite time-zone - assertEquals("Checking timezone " + id, expected.getTime(), javaDate.getTime()); + TimeZone userTZ = LocaleUtil.getUserTimeZone(); + LocaleUtil.setUserTimeZone(TimeZone.getTimeZone("CET")); + try { + Calendar cal = LocaleUtil.getLocaleCalendar(2002,JANUARY,1,12,1,1); + Date expected = cal.getTime(); + + // Iterating over the hours exposes any rounding issues. + for (int hour = -12; hour <= 12; hour++) + { + String id = "GMT" + (hour < 0 ? "" : "+") + hour + ":00"; + cal.setTimeZone(TimeZone.getTimeZone(id)); + cal.set(Calendar.HOUR_OF_DAY, 12); + double excelDate = HSSFDateUtil.getExcelDate(cal, false); + Date javaDate = HSSFDateUtil.getJavaDate(excelDate); + + // Should match despite time-zone + assertEquals("Checking timezone " + id, expected.getTime(), javaDate.getTime()); + } + + // Check that the timezone aware getter works correctly + TimeZone cet = TimeZone.getTimeZone("Europe/Copenhagen"); + TimeZone ldn = TimeZone.getTimeZone("Europe/London"); + + // 12:45 on 27th April 2012 + double excelDate = 41026.53125; + + // Same, no change + assertEquals( + HSSFDateUtil.getJavaDate(excelDate, false).getTime(), + HSSFDateUtil.getJavaDate(excelDate, false, cet).getTime() + ); + + // London vs Copenhagen, should differ by an hour + Date cetDate = HSSFDateUtil.getJavaDate(excelDate, false); + Date ldnDate = HSSFDateUtil.getJavaDate(excelDate, false, ldn); + assertEquals(ldnDate.getTime() - cetDate.getTime(), 60*60*1000); + } finally { + LocaleUtil.setUserTimeZone(userTZ); } - - // Check that the timezone aware getter works correctly - TimeZone cet = TimeZone.getTimeZone("Europe/Copenhagen"); - TimeZone ldn = TimeZone.getTimeZone("Europe/London"); - TimeZone.setDefault(cet); - - // 12:45 on 27th April 2012 - double excelDate = 41026.53125; - - // Same, no change - assertEquals( - HSSFDateUtil.getJavaDate(excelDate, false).getTime(), - HSSFDateUtil.getJavaDate(excelDate, false, cet).getTime() - ); - - // London vs Copenhagen, should differ by an hour - Date cetDate = HSSFDateUtil.getJavaDate(excelDate, false); - Date ldnDate = HSSFDateUtil.getJavaDate(excelDate, false, ldn); - assertEquals(ldnDate.getTime() - cetDate.getTime(), 60*60*1000); } /** @@ -405,7 +400,8 @@ public final class TestHSSFDateUtil { @Test public void excelDateBorderCases() throws ParseException { - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd", Locale.ROOT); + df.setTimeZone(LocaleUtil.getUserTimeZone()); assertEquals(1.0, DateUtil.getExcelDate(df.parse("1900-01-01")), 0.00001); assertEquals(31.0, DateUtil.getExcelDate(df.parse("1900-01-31")), 0.00001); @@ -415,38 +411,38 @@ public final class TestHSSFDateUtil { @Test public void dateBug_2Excel() { - assertEquals(59.0, HSSFDateUtil.getExcelDate(createDate(1900, CALENDAR_FEBRUARY, 28), false), 0.00001); - assertEquals(61.0, HSSFDateUtil.getExcelDate(createDate(1900, CALENDAR_MARCH, 1), false), 0.00001); + assertEquals(59.0, HSSFDateUtil.getExcelDate(createDate(1900, FEBRUARY, 28), false), 0.00001); + assertEquals(61.0, HSSFDateUtil.getExcelDate(createDate(1900, MARCH, 1), false), 0.00001); - assertEquals(37315.00, HSSFDateUtil.getExcelDate(createDate(2002, CALENDAR_FEBRUARY, 28), false), 0.00001); - assertEquals(37316.00, HSSFDateUtil.getExcelDate(createDate(2002, CALENDAR_MARCH, 1), false), 0.00001); - assertEquals(37257.00, HSSFDateUtil.getExcelDate(createDate(2002, CALENDAR_JANUARY, 1), false), 0.00001); - assertEquals(38074.00, HSSFDateUtil.getExcelDate(createDate(2004, CALENDAR_MARCH, 28), false), 0.00001); + assertEquals(37315.00, HSSFDateUtil.getExcelDate(createDate(2002, FEBRUARY, 28), false), 0.00001); + assertEquals(37316.00, HSSFDateUtil.getExcelDate(createDate(2002, MARCH, 1), false), 0.00001); + assertEquals(37257.00, HSSFDateUtil.getExcelDate(createDate(2002, JANUARY, 1), false), 0.00001); + assertEquals(38074.00, HSSFDateUtil.getExcelDate(createDate(2004, MARCH, 28), false), 0.00001); } @Test public void dateBug_2Java() { - assertEquals(createDate(1900, CALENDAR_FEBRUARY, 28), HSSFDateUtil.getJavaDate(59.0, false)); - assertEquals(createDate(1900, CALENDAR_MARCH, 1), HSSFDateUtil.getJavaDate(61.0, false)); + assertEquals(createDate(1900, FEBRUARY, 28), HSSFDateUtil.getJavaDate(59.0, false)); + assertEquals(createDate(1900, MARCH, 1), HSSFDateUtil.getJavaDate(61.0, false)); - assertEquals(createDate(2002, CALENDAR_FEBRUARY, 28), HSSFDateUtil.getJavaDate(37315.00, false)); - assertEquals(createDate(2002, CALENDAR_MARCH, 1), HSSFDateUtil.getJavaDate(37316.00, false)); - assertEquals(createDate(2002, CALENDAR_JANUARY, 1), HSSFDateUtil.getJavaDate(37257.00, false)); - assertEquals(createDate(2004, CALENDAR_MARCH, 28), HSSFDateUtil.getJavaDate(38074.00, false)); + assertEquals(createDate(2002, FEBRUARY, 28), HSSFDateUtil.getJavaDate(37315.00, false)); + assertEquals(createDate(2002, MARCH, 1), HSSFDateUtil.getJavaDate(37316.00, false)); + assertEquals(createDate(2002, JANUARY, 1), HSSFDateUtil.getJavaDate(37257.00, false)); + assertEquals(createDate(2004, MARCH, 28), HSSFDateUtil.getJavaDate(38074.00, false)); } @Test public void date1904() { - assertEquals(createDate(1904, CALENDAR_JANUARY, 2), HSSFDateUtil.getJavaDate(1.0, true)); - assertEquals(createDate(1904, CALENDAR_JANUARY, 1), HSSFDateUtil.getJavaDate(0.0, true)); - assertEquals(0.0, HSSFDateUtil.getExcelDate(createDate(1904, CALENDAR_JANUARY, 1), true), 0.00001); - assertEquals(1.0, HSSFDateUtil.getExcelDate(createDate(1904, CALENDAR_JANUARY, 2), true), 0.00001); + assertEquals(createDate(1904, JANUARY, 2), HSSFDateUtil.getJavaDate(1.0, true)); + assertEquals(createDate(1904, JANUARY, 1), HSSFDateUtil.getJavaDate(0.0, true)); + assertEquals(0.0, HSSFDateUtil.getExcelDate(createDate(1904, JANUARY, 1), true), 0.00001); + assertEquals(1.0, HSSFDateUtil.getExcelDate(createDate(1904, JANUARY, 2), true), 0.00001); - assertEquals(createDate(1998, CALENDAR_JULY, 5), HSSFDateUtil.getJavaDate(35981, false)); - assertEquals(createDate(1998, CALENDAR_JULY, 5), HSSFDateUtil.getJavaDate(34519, true)); + assertEquals(createDate(1998, JULY, 5), HSSFDateUtil.getJavaDate(35981, false)); + assertEquals(createDate(1998, JULY, 5), HSSFDateUtil.getJavaDate(34519, true)); - assertEquals(35981.0, HSSFDateUtil.getExcelDate(createDate(1998, CALENDAR_JULY, 5), false), 0.00001); - assertEquals(34519.0, HSSFDateUtil.getExcelDate(createDate(1998, CALENDAR_JULY, 5), true), 0.00001); + assertEquals(35981.0, HSSFDateUtil.getExcelDate(createDate(1998, JULY, 5), false), 0.00001); + assertEquals(34519.0, HSSFDateUtil.getExcelDate(createDate(1998, JULY, 5), true), 0.00001); } /** @@ -462,9 +458,7 @@ public final class TestHSSFDateUtil { * @param day one based */ private static Date createDate(int year, int month, int day, int hour, int minute, int second) { - Calendar c = new GregorianCalendar(Locale.ROOT); - c.set(year, month, day, hour, minute, second); - c.set(Calendar.MILLISECOND, 0); + Calendar c = LocaleUtil.getLocaleCalendar(year, month, day, hour, minute, second); return c.getTime(); } @@ -474,26 +468,26 @@ public final class TestHSSFDateUtil { @Test public void absoluteDay() { // 1 Jan 1900 is 1 day after 31 Dec 1899 - GregorianCalendar calendar = new GregorianCalendar(1900, 0, 1); - assertEquals("Checking absolute day (1 Jan 1900)", 1, HSSFDateUtil.absoluteDay(calendar, false)); + Calendar cal = LocaleUtil.getLocaleCalendar(1900,JANUARY,1,0,0,0); + assertEquals("Checking absolute day (1 Jan 1900)", 1, HSSFDateUtil.absoluteDay(cal, false)); // 1 Jan 1901 is 366 days after 31 Dec 1899 - calendar = new GregorianCalendar(1901, 0, 1); - assertEquals("Checking absolute day (1 Jan 1901)", 366, HSSFDateUtil.absoluteDay(calendar, false)); + cal.set(1901,JANUARY,1,0,0,0); + assertEquals("Checking absolute day (1 Jan 1901)", 366, HSSFDateUtil.absoluteDay(cal, false)); } @Test public void absoluteDayYearTooLow() { - GregorianCalendar calendar = new GregorianCalendar(1899, 0, 1); + Calendar cal = LocaleUtil.getLocaleCalendar(1899,JANUARY,1,0,0,0); try { - HSSFDateUtil.absoluteDay(calendar, false); + HSSFDateUtil.absoluteDay(cal, false); fail("Should fail here"); } catch (IllegalArgumentException e) { // expected here } try { - calendar = new GregorianCalendar(1903, 0, 1); - HSSFDateUtil.absoluteDay(calendar, true); + cal.set(1903,JANUARY,1,0,0,0); + HSSFDateUtil.absoluteDay(cal, true); fail("Should fail here"); } catch (IllegalArgumentException e) { // expected here @@ -512,8 +506,8 @@ public final class TestHSSFDateUtil { @Test public void parseDate() { - assertEquals(createDate(2008, Calendar.AUGUST, 3), HSSFDateUtil.parseYYYYMMDDDate("2008/08/03")); - assertEquals(createDate(1994, Calendar.MAY, 1), HSSFDateUtil.parseYYYYMMDDDate("1994/05/01")); + assertEquals(createDate(2008, AUGUST, 3), HSSFDateUtil.parseYYYYMMDDDate("2008/08/03")); + assertEquals(createDate(1994, MAY, 1), HSSFDateUtil.parseYYYYMMDDDate("1994/05/01")); } /** @@ -540,10 +534,8 @@ public final class TestHSSFDateUtil { HSSFSheet sheet = workbook.createSheet(); HSSFCell cell = sheet.createRow(0).createCell(0); - Calendar cal = Calendar.getInstance(); - // A pseudo special Excel dates - cal.set(1900, 0, 1); + Calendar cal = LocaleUtil.getLocaleCalendar(1900, JANUARY, 1); Date valueToTest = cal.getTime(); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestReadWriteChart.java b/src/testcases/org/apache/poi/hssf/usermodel/TestReadWriteChart.java index 1b7cf18d4..57be4a6d6 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestReadWriteChart.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestReadWriteChart.java @@ -17,42 +17,50 @@ package org.apache.poi.hssf.usermodel; -import java.util.GregorianCalendar; -import java.util.List; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; -import junit.framework.TestCase; +import java.util.Calendar; +import java.util.Date; +import java.util.List; import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.model.InternalSheet; import org.apache.poi.hssf.record.BOFRecord; import org.apache.poi.hssf.record.EOFRecord; +import org.apache.poi.hssf.record.RecordBase; +import org.apache.poi.util.LocaleUtil; +import org.junit.Test; /** * @author Glen Stampoultzis (glens at apache.org) */ -public final class TestReadWriteChart extends TestCase { +public final class TestReadWriteChart { /** * In the presence of a chart we need to make sure BOF/EOF records still exist. */ - public void testBOFandEOFRecords() { + @Test + public void testBOFandEOFRecords() throws Exception { HSSFWorkbook workbook = HSSFTestDataSamples.openSampleWorkbook("SimpleChart.xls"); HSSFSheet sheet = workbook.getSheetAt(0); HSSFRow firstRow = sheet.getRow(0); HSSFCell firstCell = firstRow.getCell(0); //System.out.println("first assertion for date"); - assertEquals(new GregorianCalendar(2000, 0, 1, 10, 51, 2).getTime(), - HSSFDateUtil - .getJavaDate(firstCell.getNumericCellValue(), false)); + Calendar calExp = LocaleUtil.getLocaleCalendar(2000, 0, 1, 10, 51, 2); + Date dateAct = HSSFDateUtil.getJavaDate(firstCell.getNumericCellValue(), false); + assertEquals(calExp.getTime(), dateAct); HSSFRow row = sheet.createRow(15); HSSFCell cell = row.createCell(1); cell.setCellValue(22); InternalSheet newSheet = workbook.getSheetAt(0).getSheet(); - List records = newSheet.getRecords(); + List records = newSheet.getRecords(); assertTrue(records.get(0) instanceof BOFRecord); assertTrue(records.get(records.size() - 1) instanceof EOFRecord); + + workbook.close(); } } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestText.java b/src/testcases/org/apache/poi/hssf/usermodel/TestText.java index 7231330ee..42a30ec8e 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestText.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestText.java @@ -18,21 +18,23 @@ package org.apache.poi.hssf.usermodel; import static org.junit.Assert.assertArrayEquals; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.model.HSSFTestModelHelper; import org.apache.poi.hssf.model.TextboxShape; import org.apache.poi.hssf.record.ObjRecord; import org.apache.poi.hssf.record.TextObjectRecord; +import org.junit.Test; /** * @author Evgeniy Berlog * @date 25.06.12 */ -public class TestText extends TestCase { +public class TestText { - public void testResultEqualsToAbstractShape() { + @Test + public void testResultEqualsToAbstractShape() throws Exception { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sh = wb.createSheet(); HSSFPatriarch patriarch = sh.createDrawingPatriarch(); @@ -81,11 +83,14 @@ public class TestText extends TestCase { assertEquals(expected.length, actual.length); assertArrayEquals(expected, actual); + + wb.close(); } - public void testAddTextToExistingFile() { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sh = wb.createSheet(); + @Test + public void testAddTextToExistingFile() throws Exception { + HSSFWorkbook wb1 = new HSSFWorkbook(); + HSSFSheet sh = wb1.createSheet(); HSSFPatriarch patriarch = sh.createDrawingPatriarch(); HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor()); textbox.setString(new HSSFRichTextString("just for test")); @@ -94,8 +99,9 @@ public class TestText extends TestCase { assertEquals(patriarch.getChildren().size(), 2); - wb = HSSFTestDataSamples.writeOutAndReadBack(wb); - sh = wb.getSheetAt(0); + HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1); + wb1.close(); + sh = wb2.getSheetAt(0); patriarch = sh.getDrawingPatriarch(); assertEquals(patriarch.getChildren().size(), 2); @@ -103,19 +109,23 @@ public class TestText extends TestCase { text3.setString(new HSSFRichTextString("text3")); assertEquals(patriarch.getChildren().size(), 3); - wb = HSSFTestDataSamples.writeOutAndReadBack(wb); - sh = wb.getSheetAt(0); + HSSFWorkbook wb3 = HSSFTestDataSamples.writeOutAndReadBack(wb2); + wb2.close(); + sh = wb3.getSheetAt(0); patriarch = sh.getDrawingPatriarch(); assertEquals(patriarch.getChildren().size(), 3); assertEquals(((HSSFTextbox) patriarch.getChildren().get(0)).getString().getString(), "just for test"); assertEquals(((HSSFTextbox) patriarch.getChildren().get(1)).getString().getString(), "just for test2"); assertEquals(((HSSFTextbox) patriarch.getChildren().get(2)).getString().getString(), "text3"); + + wb3.close(); } - public void testSetGetProperties() { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sh = wb.createSheet(); + @Test + public void testSetGetProperties() throws Exception { + HSSFWorkbook wb1 = new HSSFWorkbook(); + HSSFSheet sh = wb1.createSheet(); HSSFPatriarch patriarch = sh.createDrawingPatriarch(); HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor()); textbox.setString(new HSSFRichTextString("test")); @@ -139,8 +149,9 @@ public class TestText extends TestCase { textbox.setMarginTop(10); assertEquals(textbox.getMarginTop(), 10); - wb = HSSFTestDataSamples.writeOutAndReadBack(wb); - sh = wb.getSheetAt(0); + HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1); + wb1.close(); + sh = wb2.getSheetAt(0); patriarch = sh.getDrawingPatriarch(); textbox = (HSSFTextbox) patriarch.getChildren().get(0); assertEquals(textbox.getString().getString(), "test"); @@ -167,8 +178,9 @@ public class TestText extends TestCase { assertEquals(textbox.getMarginRight(), 91); assertEquals(textbox.getMarginTop(), 101); - wb = HSSFTestDataSamples.writeOutAndReadBack(wb); - sh = wb.getSheetAt(0); + HSSFWorkbook wb3 = HSSFTestDataSamples.writeOutAndReadBack(wb2); + wb2.close(); + sh = wb3.getSheetAt(0); patriarch = sh.getDrawingPatriarch(); textbox = (HSSFTextbox) patriarch.getChildren().get(0); @@ -179,9 +191,12 @@ public class TestText extends TestCase { assertEquals(textbox.getMarginLeft(), 81); assertEquals(textbox.getMarginRight(), 91); assertEquals(textbox.getMarginTop(), 101); + + wb3.close(); } - public void testExistingFileWithText(){ + @Test + public void testExistingFileWithText() throws Exception { HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls"); HSSFSheet sheet = wb.getSheet("text"); HSSFPatriarch drawing = sheet.getDrawingPatriarch(); @@ -194,5 +209,6 @@ public class TestText extends TestCase { assertEquals(textbox.getMarginLeft(), 3600000); assertEquals(textbox.getMarginRight(), 0); assertEquals(textbox.getString().getString(), "teeeeesssstttt"); + wb.close(); } } diff --git a/src/testcases/org/apache/poi/ss/format/CellFormatTestBase.java b/src/testcases/org/apache/poi/ss/format/CellFormatTestBase.java index 28e9cfe46..537dafbb3 100644 --- a/src/testcases/org/apache/poi/ss/format/CellFormatTestBase.java +++ b/src/testcases/org/apache/poi/ss/format/CellFormatTestBase.java @@ -25,10 +25,12 @@ import static java.awt.Color.ORANGE; import static java.awt.Color.RED; import static java.awt.Color.WHITE; import static java.awt.Color.YELLOW; +import static org.junit.Assert.assertEquals; import java.awt.Color; import java.io.IOException; import java.util.Arrays; +import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; @@ -36,15 +38,14 @@ import java.util.TreeSet; import javax.swing.JLabel; -import junit.framework.TestCase; - import org.apache.poi.ss.ITestDataProvider; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.util.POILogger; +import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; /** * This class is a base class for spreadsheet-based tests, such as are used for @@ -57,9 +58,7 @@ import org.apache.poi.util.POILogFactory; * flag "Categories" is not empty, only tests that have at least one category * listed in "Categories" are run. */ -@SuppressWarnings( - {"JUnitTestCaseWithNoTests", "JUnitTestClassNamingConvention"}) -public class CellFormatTestBase extends TestCase { +public class CellFormatTestBase { private static final POILogger logger = POILogFactory.getLogger(CellFormatTestBase.class); private final ITestDataProvider _testDataProvider; @@ -86,7 +85,6 @@ public class CellFormatTestBase extends TestCase { abstract static class CellValue { abstract Object getValue(Cell cell); - @SuppressWarnings({"UnusedDeclaration"}) Color getColor(Cell cell) { return TEST_COLOR; } @@ -114,20 +112,19 @@ public class CellFormatTestBase extends TestCase { } Sheet sheet = workbook.getSheet("Tests"); - int end = sheet.getLastRowNum(); - // Skip the header row, therefore "+ 1" - for (int r = sheet.getFirstRowNum() + 1; r <= end; r++) { - Row row = sheet.getRow(r); - if (row == null) - continue; - int cellnum = 0; - String expectedText = row.getCell(cellnum).getStringCellValue(); - String format = row.getCell(1).getStringCellValue(); + Iterator rowIter = sheet.rowIterator(); + // Skip the header row + rowIter.next(); + while (rowIter.hasNext()) { + Row row = rowIter.next(); + if (row == null) continue; + String expectedText = row.getCell(0).getStringCellValue(); + String format = row.getCell(1).getStringCellValue(); + Cell value = row.getCell(2); String testCategoryList = row.getCell(3).getStringCellValue(); boolean byCategory = runByCategory(runCategories, testCategoryList); if ((expectedText.length() > 0 || format.length() > 0) && byCategory) { - Cell cell = row.getCell(2); - tryFormat(r, expectedText, format, valueGetter, cell); + tryFormat(row.getRowNum(), expectedText, format, valueGetter, value); } } } @@ -216,16 +213,17 @@ public class CellFormatTestBase extends TestCase { label.setForeground(testColor); label.setText("xyzzy"); - logger.log(POILogger.INFO, String.format("Row %d: \"%s\" -> \"%s\": expected \"%s\"", row + 1, - String.valueOf(value), desc, expectedText)); + logger.log(POILogger.INFO, String.format(LocaleUtil.getUserLocale(), + "Row %d: \"%s\" -> \"%s\": expected \"%s\"", + row + 1, String.valueOf(value), desc, expectedText)); String actualText = tryColor(desc, null, getter, value, expectedText, testColor); - logger.log(POILogger.INFO, String.format(", actual \"%s\")%n", actualText)); + logger.log(POILogger.INFO, String.format(LocaleUtil.getUserLocale(), + ", actual \"%s\")%n", actualText)); if (tryAllColors && testColor != TEST_COLOR) { for (int i = 0; i < COLOR_NAMES.length; i++) { - String cname = COLOR_NAMES[i]; - tryColor(desc, cname, getter, value, expectedText, COLORS[i]); + tryColor(desc, COLOR_NAMES[i], getter, value, expectedText, COLORS[i]); } } } diff --git a/src/testcases/org/apache/poi/ss/format/TestCellFormat.java b/src/testcases/org/apache/poi/ss/format/TestCellFormat.java index 9d2d7580c..b7983a3c8 100644 --- a/src/testcases/org/apache/poi/ss/format/TestCellFormat.java +++ b/src/testcases/org/apache/poi/ss/format/TestCellFormat.java @@ -16,23 +16,45 @@ ==================================================================== */ package org.apache.poi.ss.format; +import static org.junit.Assert.assertEquals; + import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; import javax.swing.JLabel; -import junit.framework.TestCase; - import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.util.LocaleUtil; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; -public class TestCellFormat extends TestCase { +public class TestCellFormat { + + private static TimeZone userTimeZone; + + @BeforeClass + public static void setTimeZone() { + userTimeZone = LocaleUtil.getUserTimeZone(); + LocaleUtil.setUserTimeZone(TimeZone.getTimeZone("CET")); + LocaleUtil.setUserLocale(Locale.US); + } + + @AfterClass + public static void resetTimeZone() { + LocaleUtil.setUserTimeZone(userTimeZone); + LocaleUtil.setUserLocale(Locale.ROOT); + } + private static final String _255_POUND_SIGNS; static { @@ -43,6 +65,7 @@ public class TestCellFormat extends TestCase { _255_POUND_SIGNS = sb.toString(); } + @Test public void testSome() { JLabel l = new JLabel(); CellFormat fmt = CellFormat.getInstance( @@ -50,48 +73,56 @@ public class TestCellFormat extends TestCase { fmt.apply(l, 1.1); } + @Test public void testPositiveFormatHasOnePart() { CellFormat fmt = CellFormat.getInstance("0.00"); CellFormatResult result = fmt.apply(12.345); assertEquals("12.35", result.text); } + @Test public void testNegativeFormatHasOnePart() { CellFormat fmt = CellFormat.getInstance("0.00"); CellFormatResult result = fmt.apply(-12.345); assertEquals("-12.35", result.text); } + @Test public void testZeroFormatHasOnePart() { CellFormat fmt = CellFormat.getInstance("0.00"); CellFormatResult result = fmt.apply(0.0); assertEquals("0.00", result.text); } + @Test public void testPositiveFormatHasPosAndNegParts() { CellFormat fmt = CellFormat.getInstance("0.00;-0.00"); CellFormatResult result = fmt.apply(12.345); assertEquals("12.35", result.text); } + @Test public void testNegativeFormatHasPosAndNegParts() { CellFormat fmt = CellFormat.getInstance("0.00;-0.00"); CellFormatResult result = fmt.apply(-12.345); assertEquals("-12.35", result.text); } + @Test public void testNegativeFormatHasPosAndNegParts2() { CellFormat fmt = CellFormat.getInstance("0.00;(0.00)"); CellFormatResult result = fmt.apply(-12.345); assertEquals("(12.35)", result.text); } + @Test public void testZeroFormatHasPosAndNegParts() { CellFormat fmt = CellFormat.getInstance("0.00;-0.00"); CellFormatResult result = fmt.apply(0.0); assertEquals("0.00", result.text); } + @Test public void testFormatWithThreeSections() { CellFormat fmt = CellFormat.getInstance("0.00;-0.00;-"); @@ -101,6 +132,7 @@ public class TestCellFormat extends TestCase { assertEquals("abc", fmt.apply("abc").text); } + @Test public void testFormatWithFourSections() { CellFormat fmt = CellFormat.getInstance("0.00;-0.00;-; @ "); @@ -110,7 +142,8 @@ public class TestCellFormat extends TestCase { assertEquals(" abc ", fmt.apply("abc").text); } - public void testApplyCellForGeneralFormat() { + @Test + public void testApplyCellForGeneralFormat() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -147,9 +180,11 @@ public class TestCellFormat extends TestCase { CellFormatResult result4 = cf.apply(cell4); assertEquals("abc", result4.text); + wb.close(); } - public void testApplyCellForAtFormat() { + @Test + public void testApplyCellForAtFormat() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -186,9 +221,11 @@ public class TestCellFormat extends TestCase { CellFormatResult result4 = cf.apply(cell4); assertEquals("abc", result4.text); + wb.close(); } - public void testApplyCellForDateFormat() { + @Test + public void testApplyCellForDateFormat() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -207,9 +244,11 @@ public class TestCellFormat extends TestCase { CellFormatResult result1 = cf.apply(cell1); assertEquals(_255_POUND_SIGNS, result1.text); + wb.close(); } - public void testApplyCellForTimeFormat() { + @Test + public void testApplyCellForTimeFormat() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -223,9 +262,11 @@ public class TestCellFormat extends TestCase { CellFormatResult result = cf.apply(cell); assertEquals("03:04", result.text); + wb.close(); } - public void testApplyCellForDateFormatAndNegativeFormat() { + @Test + public void testApplyCellForDateFormatAndNegativeFormat() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -244,9 +285,11 @@ public class TestCellFormat extends TestCase { CellFormatResult result1 = cf.apply(cell1); assertEquals("(1)", result1.text); + wb.close(); } - public void testApplyJLabelCellForGeneralFormat() { + @Test + public void testApplyJLabelCellForGeneralFormat() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -294,9 +337,11 @@ public class TestCellFormat extends TestCase { assertEquals("abc", result4.text); assertEquals("abc", label4.getText()); + wb.close(); } - public void testApplyJLabelCellForAtFormat() { + @Test + public void testApplyJLabelCellForAtFormat() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -344,9 +389,11 @@ public class TestCellFormat extends TestCase { assertEquals("abc", result4.text); assertEquals("abc", label4.getText()); + wb.close(); } - public void testApplyJLabelCellForDateFormat() { + @Test + public void testApplyJLabelCellForDateFormat() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -370,9 +417,11 @@ public class TestCellFormat extends TestCase { assertEquals(_255_POUND_SIGNS, result1.text); assertEquals(_255_POUND_SIGNS, label1.getText()); + wb.close(); } - public void testApplyJLabelCellForTimeFormat() { + @Test + public void testApplyJLabelCellForTimeFormat() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -389,9 +438,11 @@ public class TestCellFormat extends TestCase { assertEquals("03:04", result.text); assertEquals("03:04", label.getText()); + wb.close(); } - public void testApplyJLabelCellForDateFormatAndNegativeFormat() { + @Test + public void testApplyJLabelCellForDateFormatAndNegativeFormat() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -415,9 +466,11 @@ public class TestCellFormat extends TestCase { assertEquals("(1)", result1.text); assertEquals("(1)", label1.getText()); + wb.close(); } - public void testApplyFormatHasOnePartAndPartHasCondition() { + @Test + public void testApplyFormatHasOnePartAndPartHasCondition() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -442,9 +495,11 @@ public class TestCellFormat extends TestCase { cell.setCellValue("abc"); assertEquals("abc", cf.apply(cell).text); + wb.close(); } - public void testApplyFormatHasTwoPartsFirstHasCondition() { + @Test + public void testApplyFormatHasTwoPartsFirstHasCondition() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -475,9 +530,11 @@ public class TestCellFormat extends TestCase { cell.setCellValue("TRUE"); assertEquals("TRUE", cf.apply(cell).text); + wb.close(); } - public void testApplyFormatHasTwoPartsBothHaveCondition() { + @Test + public void testApplyFormatHasTwoPartsBothHaveCondition() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -505,9 +562,11 @@ public class TestCellFormat extends TestCase { cell.setCellValue("abc"); assertEquals("abc", cf.apply(cell).text); + wb.close(); } - public void testApplyFormatHasThreePartsFirstHasCondition() { + @Test + public void testApplyFormatHasThreePartsFirstHasCondition() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -537,9 +596,11 @@ public class TestCellFormat extends TestCase { cell.setCellValue("abc"); assertEquals("abc", cf.apply(cell).text); + wb.close(); } - public void testApplyFormatHasThreePartsFirstTwoHaveCondition() { + @Test + public void testApplyFormatHasThreePartsFirstTwoHaveCondition() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -564,9 +625,11 @@ public class TestCellFormat extends TestCase { cell.setCellValue("abc"); assertEquals("abc", cf.apply(cell).text); + wb.close(); } - public void testApplyFormatHasThreePartsFirstIsDateFirstTwoHaveCondition() { + @Test + public void testApplyFormatHasThreePartsFirstIsDateFirstTwoHaveCondition() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -591,9 +654,11 @@ public class TestCellFormat extends TestCase { cell.setCellValue("abc"); assertEquals("abc", cf.apply(cell).text); + wb.close(); } - public void testApplyFormatHasTwoPartsFirstHasConditionSecondIsGeneral() { + @Test + public void testApplyFormatHasTwoPartsFirstHasConditionSecondIsGeneral() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -618,9 +683,11 @@ public class TestCellFormat extends TestCase { cell.setCellValue("abc"); assertEquals("abc", cf.apply(cell).text); + wb.close(); } - public void testApplyFormatHasThreePartsFirstTwoHaveConditionThirdIsGeneral() { + @Test + public void testApplyFormatHasThreePartsFirstTwoHaveConditionThirdIsGeneral() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -645,9 +712,11 @@ public class TestCellFormat extends TestCase { cell.setCellValue("abc"); assertEquals("abc", cf.apply(cell).text); + wb.close(); } - public void testApplyFormatHasFourPartsFirstHasCondition() { + @Test + public void testApplyFormatHasFourPartsFirstHasCondition() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -677,9 +746,11 @@ public class TestCellFormat extends TestCase { cell.setCellValue("abc"); assertEquals("~~abc~~", cf.apply(cell).text); + wb.close(); } - public void testApplyFormatHasFourPartsSecondHasCondition() { + @Test + public void testApplyFormatHasFourPartsSecondHasCondition() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -710,9 +781,11 @@ public class TestCellFormat extends TestCase { cell.setCellValue(true); assertEquals("~~TRUE~~", cf.apply(cell).text); + wb.close(); } - public void testApplyFormatHasFourPartsFirstTwoHaveCondition() { + @Test + public void testApplyFormatHasFourPartsFirstTwoHaveCondition() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -739,11 +812,14 @@ public class TestCellFormat extends TestCase { cell.setCellValue(true); assertEquals("~~TRUE~~", cf.apply(cell).text); + + wb.close(); } /* * Test apply(Object value) with a number as parameter */ + @Test public void testApplyObjectNumber() { CellFormat cf1 = CellFormat.getInstance("0.000"); @@ -771,15 +847,17 @@ public class TestCellFormat extends TestCase { /* * Test apply(Object value) with a Date as parameter */ + @Test public void testApplyObjectDate() throws ParseException { CellFormat cf1 = CellFormat.getInstance("m/d/yyyy"); - Date date1 = new SimpleDateFormat("M/d/y").parse("01/11/2012"); + Date date1 = new SimpleDateFormat("M/d/y", Locale.ROOT).parse("01/11/2012"); assertEquals("1/11/2012", cf1.apply(date1).text); } - public void testApplyCellForDateFormatWithConditions() { + @Test + public void testApplyCellForDateFormatWithConditions() throws Exception { // Create a workbook, row and cell to test with Workbook wb = new HSSFWorkbook(); @@ -798,11 +876,13 @@ public class TestCellFormat extends TestCase { cell.setCellValue(-1); assertEquals(_255_POUND_SIGNS, cf.apply(cell).text); + wb.close(); } /* * Test apply(Object value) with a String as parameter */ + @Test public void testApplyObjectString() { CellFormat cf = CellFormat.getInstance("0.00"); @@ -814,6 +894,7 @@ public class TestCellFormat extends TestCase { /* * Test apply(Object value) with a Boolean as parameter */ + @Test public void testApplyObjectBoolean() { CellFormat cf1 = CellFormat.getInstance("0"); @@ -826,6 +907,7 @@ public class TestCellFormat extends TestCase { } + @Test public void testSimpleFractionFormat() throws IOException { CellFormat cf1 = CellFormat.getInstance("# ?/?"); // Create a workbook, row and cell to test with diff --git a/src/testcases/org/apache/poi/ss/formula/atp/TestDateParser.java b/src/testcases/org/apache/poi/ss/formula/atp/TestDateParser.java index 9dcbf16ac..5117787d6 100644 --- a/src/testcases/org/apache/poi/ss/formula/atp/TestDateParser.java +++ b/src/testcases/org/apache/poi/ss/formula/atp/TestDateParser.java @@ -17,21 +17,18 @@ package org.apache.poi.ss.formula.atp; -import static java.util.Calendar.OCTOBER; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; import java.util.Calendar; -import java.util.Date; - -import junit.framework.TestCase; import org.apache.poi.ss.formula.eval.ErrorEval; import org.apache.poi.ss.formula.eval.EvaluationException; +import org.apache.poi.util.LocaleUtil; +import org.junit.Test; -/** - * @author jfaenomoto@gmail.com - */ -public class TestDateParser extends TestCase { - +public class TestDateParser { + @Test public void testFailWhenNoDate() { try { DateParser.parseDate("potato"); @@ -41,6 +38,7 @@ public class TestDateParser extends TestCase { } } + @Test public void testFailWhenLooksLikeDateButItIsnt() { try { DateParser.parseDate("potato/cucumber/banana"); @@ -50,6 +48,7 @@ public class TestDateParser extends TestCase { } } + @Test public void testFailWhenIsInvalidDate() { try { DateParser.parseDate("13/13/13"); @@ -59,18 +58,18 @@ public class TestDateParser extends TestCase { } } - @SuppressWarnings("deprecation") + @Test public void testShouldParseValidDate() throws EvaluationException { - Calendar aDate = Calendar.getInstance(); - aDate.setTime(new Date(84, OCTOBER, 20)); - assertEquals(aDate, DateParser.parseDate("1984/10/20")); + Calendar expDate = LocaleUtil.getLocaleCalendar(1984, Calendar.OCTOBER, 20); + Calendar actDate = DateParser.parseDate("1984/10/20"); + assertEquals(expDate, actDate); } - @SuppressWarnings("deprecation") + @Test public void testShouldIgnoreTimestamp() throws EvaluationException { - Calendar aDate = Calendar.getInstance(); - aDate.setTime(new Date(84, OCTOBER, 20)); - assertEquals(aDate, DateParser.parseDate("1984/10/20 12:34:56")); + Calendar expDate = LocaleUtil.getLocaleCalendar(1984, Calendar.OCTOBER, 20); + Calendar actDate = DateParser.parseDate("1984/10/20 12:34:56"); + assertEquals(expDate, actDate); } } diff --git a/src/testcases/org/apache/poi/ss/formula/atp/TestNetworkdaysFunction.java b/src/testcases/org/apache/poi/ss/formula/atp/TestNetworkdaysFunction.java index 15309d5c1..9df80a9d7 100644 --- a/src/testcases/org/apache/poi/ss/formula/atp/TestNetworkdaysFunction.java +++ b/src/testcases/org/apache/poi/ss/formula/atp/TestNetworkdaysFunction.java @@ -17,21 +17,12 @@ package org.apache.poi.ss.formula.atp; -import static java.util.Calendar.DECEMBER; -import static java.util.Calendar.JANUARY; -import static java.util.Calendar.MARCH; -import static java.util.Calendar.NOVEMBER; -import static java.util.Calendar.OCTOBER; import static org.apache.poi.ss.formula.eval.ErrorEval.NAME_INVALID; import static org.apache.poi.ss.formula.eval.ErrorEval.VALUE_INVALID; -import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Date; import java.util.List; -import junit.framework.TestCase; - import org.apache.poi.ss.formula.OperationEvaluationContext; import org.apache.poi.ss.formula.TwoDEval; import org.apache.poi.ss.formula.eval.AreaEval; @@ -40,23 +31,15 @@ import org.apache.poi.ss.formula.eval.NumericValueEval; import org.apache.poi.ss.formula.eval.StringEval; import org.apache.poi.ss.formula.eval.ValueEval; -/** - * @author jfaenomoto@gmail.com - */ -@SuppressWarnings("deprecation") // YK: uses deprecated {@link java.util.Date(int year, int month, int date)} +import junit.framework.TestCase; + public class TestNetworkdaysFunction extends TestCase { - private static final SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd"); - - private static final String STARTING_DATE = formatter.format(new Date(108, OCTOBER, 1)); - - private static final String END_DATE = formatter.format(new Date(109, MARCH, 1)); - - private static final String FIRST_HOLIDAY = formatter.format(new Date(108, NOVEMBER, 26)); - - private static final String SECOND_HOLIDAY = formatter.format(new Date(108, DECEMBER, 4)); - - private static final String THIRD_HOLIDAY = formatter.format(new Date(109, JANUARY, 21)); + private static final String STARTING_DATE = "2008/10/01"; + private static final String END_DATE = "2009/03/01"; + private static final String FIRST_HOLIDAY = "2008/11/26"; + private static final String SECOND_HOLIDAY = "2008/12/04"; + private static final String THIRD_HOLIDAY = "2009/01/21"; private static final OperationEvaluationContext EC = new OperationEvaluationContext(null, null, 1, 1, 1, null); diff --git a/src/testcases/org/apache/poi/ss/formula/atp/TestWorkdayCalculator.java b/src/testcases/org/apache/poi/ss/formula/atp/TestWorkdayCalculator.java index 3ab1255a0..055149c6c 100644 --- a/src/testcases/org/apache/poi/ss/formula/atp/TestWorkdayCalculator.java +++ b/src/testcases/org/apache/poi/ss/formula/atp/TestWorkdayCalculator.java @@ -17,87 +17,100 @@ package org.apache.poi.ss.formula.atp; -import static java.util.Calendar.DECEMBER; import static java.util.Calendar.SATURDAY; +import static org.junit.Assert.assertEquals; +import java.util.Calendar; import java.util.Date; -import junit.framework.TestCase; - import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.util.LocaleUtil; +import org.junit.Test; -/** - * @author jfaenomoto@gmail.com - */ -@SuppressWarnings("deprecation") // YK: heavily uses deprecated {@link java.util.Date(int year, int month, int date)} -public class TestWorkdayCalculator extends TestCase { +public class TestWorkdayCalculator { + @Test public void testCalculateWorkdaysShouldReturnJustWeekdaysWhenNoWeekend() { - final double A_MONDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 12)); - final double A_FRIDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 16)); + final double A_MONDAY = DateUtil.getExcelDate(d(2011, 12, 12)); + final double A_FRIDAY = DateUtil.getExcelDate(d(2011, 12, 16)); assertEquals(5, WorkdayCalculator.instance.calculateWorkdays(A_MONDAY, A_FRIDAY, new double[0])); } + @Test public void testCalculateWorkdaysShouldReturnAllDaysButNoSaturdays() { - final double A_WEDNESDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 14)); - final double A_SATURDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 18)); + final double A_WEDNESDAY = DateUtil.getExcelDate(d(2011, 12, 14)); + final double A_SATURDAY = DateUtil.getExcelDate(d(2011, 12, 18)); assertEquals(3, WorkdayCalculator.instance.calculateWorkdays(A_WEDNESDAY, A_SATURDAY, new double[0])); } + @Test public void testCalculateWorkdaysShouldReturnAllDaysButNoSundays() { - final double A_SUNDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 11)); - final double A_THURSDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 15)); + final double A_SUNDAY = DateUtil.getExcelDate(d(2011, 12, 11)); + final double A_THURSDAY = DateUtil.getExcelDate(d(2011, 12, 15)); assertEquals(4, WorkdayCalculator.instance.calculateWorkdays(A_SUNDAY, A_THURSDAY, new double[0])); } + @Test public void testCalculateWorkdaysShouldReturnAllDaysButNoHolidays() { - final double A_MONDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 12)); - final double A_FRIDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 16)); - final double A_WEDNESDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 14)); + final double A_MONDAY = DateUtil.getExcelDate(d(2011, 12, 12)); + final double A_FRIDAY = DateUtil.getExcelDate(d(2011, 12, 16)); + final double A_WEDNESDAY = DateUtil.getExcelDate(d(2011, 12, 14)); assertEquals(4, WorkdayCalculator.instance.calculateWorkdays(A_MONDAY, A_FRIDAY, new double[]{ A_WEDNESDAY })); } + @Test public void testCalculateWorkdaysShouldIgnoreWeekendHolidays() { - final double A_FRIDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 16)); - final double A_SATURDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 17)); - final double A_SUNDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 18)); - final double A_WEDNESDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 21)); + final double A_FRIDAY = DateUtil.getExcelDate(d(2011, 12, 16)); + final double A_SATURDAY = DateUtil.getExcelDate(d(2011, 12, 17)); + final double A_SUNDAY = DateUtil.getExcelDate(d(2011, 12, 18)); + final double A_WEDNESDAY = DateUtil.getExcelDate(d(2011, 12, 21)); assertEquals(4, WorkdayCalculator.instance.calculateWorkdays(A_FRIDAY, A_WEDNESDAY, new double[]{ A_SATURDAY, A_SUNDAY })); } + @Test public void testCalculateWorkdaysNumberOfDays() { double start = 41553.0; int days = 1; - assertEquals(new Date(113, 9, 7), WorkdayCalculator.instance.calculateWorkdays(start, days, new double[0])); + assertEquals(d(2013, 10, 7), WorkdayCalculator.instance.calculateWorkdays(start, days, new double[0])); } + @Test public void testPastDaysOfWeekShouldReturn0Past0Saturdays() { - final double A_WEDNESDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 7)); - final double A_FRIDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 9)); + final double A_WEDNESDAY = DateUtil.getExcelDate(d(2011, 12, 7)); + final double A_FRIDAY = DateUtil.getExcelDate(d(2011, 12, 9)); assertEquals(0, WorkdayCalculator.instance.pastDaysOfWeek(A_WEDNESDAY, A_FRIDAY, SATURDAY)); } + @Test public void testPastDaysOfWeekShouldReturn1Past1Saturdays() { - final double A_WEDNESDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 7)); - final double A_SUNDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 11)); + final double A_WEDNESDAY = DateUtil.getExcelDate(d(2011, 12, 7)); + final double A_SUNDAY = DateUtil.getExcelDate(d(2011, 12, 11)); assertEquals(1, WorkdayCalculator.instance.pastDaysOfWeek(A_WEDNESDAY, A_SUNDAY, SATURDAY)); } + @Test public void testPastDaysOfWeekShouldReturn2Past2Saturdays() { - final double A_THURSDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 8)); - final double A_MONDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 19)); + final double A_THURSDAY = DateUtil.getExcelDate(d(2011, 12, 8)); + final double A_MONDAY = DateUtil.getExcelDate(d(2011, 12, 19)); assertEquals(2, WorkdayCalculator.instance.pastDaysOfWeek(A_THURSDAY, A_MONDAY, SATURDAY)); } + @Test public void testPastDaysOfWeekShouldReturn1BeginningFromASaturday() { - final double A_SATURDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 10)); - final double A_SUNDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 11)); + final double A_SATURDAY = DateUtil.getExcelDate(d(2011, 12, 10)); + final double A_SUNDAY = DateUtil.getExcelDate(d(2011, 12, 11)); assertEquals(1, WorkdayCalculator.instance.pastDaysOfWeek(A_SATURDAY, A_SUNDAY, SATURDAY)); } + @Test public void testPastDaysOfWeekShouldReturn1EndingAtASaturday() { - final double A_THURSDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 8)); - final double A_SATURDAY = DateUtil.getExcelDate(new Date(111, DECEMBER, 10)); + final double A_THURSDAY = DateUtil.getExcelDate(d(2011, 12, 8)); + final double A_SATURDAY = DateUtil.getExcelDate(d(2011, 12, 10)); assertEquals(1, WorkdayCalculator.instance.pastDaysOfWeek(A_THURSDAY, A_SATURDAY, SATURDAY)); } + + private static Date d(int year, int month, int day) { + Calendar cal = LocaleUtil.getLocaleCalendar(year, month-1, day, 0, 0, 0); + return cal.getTime(); + } } diff --git a/src/testcases/org/apache/poi/ss/formula/atp/TestWorkdayFunction.java b/src/testcases/org/apache/poi/ss/formula/atp/TestWorkdayFunction.java index 94deb2db0..02af969a2 100644 --- a/src/testcases/org/apache/poi/ss/formula/atp/TestWorkdayFunction.java +++ b/src/testcases/org/apache/poi/ss/formula/atp/TestWorkdayFunction.java @@ -18,17 +18,12 @@ package org.apache.poi.ss.formula.atp; -import static java.util.Calendar.APRIL; -import static java.util.Calendar.DECEMBER; -import static java.util.Calendar.JANUARY; -import static java.util.Calendar.MAY; -import static java.util.Calendar.NOVEMBER; -import static java.util.Calendar.OCTOBER; -import static java.util.Calendar.SEPTEMBER; -import static org.apache.poi.ss.formula.eval.ErrorEval.VALUE_INVALID; -import java.text.SimpleDateFormat; +import static org.apache.poi.ss.formula.eval.ErrorEval.VALUE_INVALID; +import static org.junit.Assert.assertEquals; + import java.util.ArrayList; +import java.util.Calendar; import java.util.Date; import java.util.List; @@ -40,114 +35,140 @@ import org.apache.poi.ss.formula.eval.NumberEval; import org.apache.poi.ss.formula.eval.StringEval; import org.apache.poi.ss.formula.eval.ValueEval; import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.util.LocaleUtil; +import org.junit.Test; -import junit.framework.TestCase; +public class TestWorkdayFunction { -/** - * @author jfaenomoto@gmail.com - */ -@SuppressWarnings("deprecation") // YK: heavily uses deprecated {@link java.util.Date(int year, int month, int date)} -public class TestWorkdayFunction extends TestCase { - - private static final SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd"); - - private static final String STARTING_DATE = formatter.format(new Date(108, OCTOBER, 1)); - - private static final String FIRST_HOLIDAY = formatter.format(new Date(108, NOVEMBER, 26)); - - private static final String SECOND_HOLIDAY = formatter.format(new Date(108, DECEMBER, 4)); - - private static final String THIRD_HOLIDAY = formatter.format(new Date(109, JANUARY, 21)); - - private static final String RETROATIVE_HOLIDAY = formatter.format(new Date(108, SEPTEMBER, 29)); + private static final String STARTING_DATE = "2008/10/01"; + private static final String FIRST_HOLIDAY = "2008/11/26"; + private static final String SECOND_HOLIDAY = "2008/12/04"; + private static final String THIRD_HOLIDAY = "2009/01/21"; + private static final String RETROATIVE_HOLIDAY = "2008/09/29"; private static final OperationEvaluationContext EC = new OperationEvaluationContext(null, null, 1, 1, 1, null); + @Test public void testFailWhenNoArguments() { - assertEquals(VALUE_INVALID, WorkdayFunction.instance.evaluate(new ValueEval[0], null)); + ValueEval ve[] = new ValueEval[0]; + assertEquals(VALUE_INVALID, WorkdayFunction.instance.evaluate(ve, null)); } + @Test public void testFailWhenLessThan2Arguments() { - assertEquals(VALUE_INVALID, WorkdayFunction.instance.evaluate(new ValueEval[1], null)); + ValueEval ve[] = new ValueEval[1]; + assertEquals(VALUE_INVALID, WorkdayFunction.instance.evaluate(ve, null)); } + @Test public void testFailWhenMoreThan3Arguments() { - assertEquals(VALUE_INVALID, WorkdayFunction.instance.evaluate(new ValueEval[4], null)); + ValueEval ve[] = new ValueEval[4]; + assertEquals(VALUE_INVALID, WorkdayFunction.instance.evaluate(ve, null)); } + @Test public void testFailWhenArgumentsAreNotDatesNorNumbers() { - assertEquals(VALUE_INVALID, WorkdayFunction.instance.evaluate( - new ValueEval[]{ new StringEval("Potato"), new StringEval("Cucumber") }, EC)); + ValueEval ve[] = { new StringEval("Potato"), new StringEval("Cucumber") }; + assertEquals(VALUE_INVALID, WorkdayFunction.instance.evaluate(ve, EC)); } + @Test public void testReturnWorkdays() { - assertEquals(new Date(109, APRIL, 30), DateUtil.getJavaDate(((NumberEval) WorkdayFunction.instance.evaluate(new ValueEval[]{ - new StringEval(STARTING_DATE), new NumberEval(151) }, EC)).getNumberValue())); + Calendar expCal = LocaleUtil.getLocaleCalendar(2009, 3, 30); + Date expDate = expCal.getTime(); + ValueEval ve[] = { new StringEval(STARTING_DATE), new NumberEval(151) }; + Date actDate = DateUtil.getJavaDate(((NumberEval) WorkdayFunction.instance.evaluate(ve, EC)).getNumberValue()); + assertEquals(expDate, actDate); } + @Test public void testReturnWorkdaysSpanningAWeekendSubtractingDays() { - String startDate = "2013/09/30"; - int days = -1; - StringEval stringEval = new StringEval(startDate); - double numberValue = ((NumberEval) WorkdayFunction.instance.evaluate(new ValueEval[]{ - stringEval, new NumberEval(days) }, EC)).getNumberValue(); - assertEquals(41544.0, numberValue); + Calendar expCal = LocaleUtil.getLocaleCalendar(2013, 8, 27); + Date expDate = expCal.getTime(); + + ValueEval ve[] = { new StringEval("2013/09/30"), new NumberEval(-1) }; + double numberValue = ((NumberEval) WorkdayFunction.instance.evaluate(ve, EC)).getNumberValue(); + assertEquals(41544.0, numberValue, 0); - Date date = DateUtil.getJavaDate(numberValue); - assertEquals("Should be 2013/09/27", new Date(113, 8, 27), date); + Date actDate = DateUtil.getJavaDate(numberValue); + assertEquals(expDate, actDate); } + @Test public void testReturnWorkdaysSpanningAWeekendAddingDays() { - String startDate = "2013/09/27"; - int days = 1; - StringEval stringEval = new StringEval(startDate); - double numberValue = ((NumberEval) WorkdayFunction.instance.evaluate(new ValueEval[]{ - stringEval, new NumberEval(days) }, EC)).getNumberValue(); - assertEquals(41547.0, numberValue); + Calendar expCal = LocaleUtil.getLocaleCalendar(2013, 8, 30); + Date expDate = expCal.getTime(); + + ValueEval ve[] = { new StringEval("2013/09/27"), new NumberEval(1) }; + double numberValue = ((NumberEval) WorkdayFunction.instance.evaluate(ve, EC)).getNumberValue(); + assertEquals(41547.0, numberValue, 0); - Date date = DateUtil.getJavaDate(numberValue); - assertEquals("Should be 2013/09/30", new Date(113, 8, 30), date); + Date actDate = DateUtil.getJavaDate(numberValue); + assertEquals(expDate, actDate); } + @Test public void testReturnWorkdaysWhenStartIsWeekendAddingDays() { - String startDate = "2013/10/06"; - int days = 1; - StringEval stringEval = new StringEval(startDate); - double numberValue = ((NumberEval) WorkdayFunction.instance.evaluate(new ValueEval[]{ - stringEval, new NumberEval(days) }, EC)).getNumberValue(); - assertEquals(41554.0, numberValue); + Calendar expCal = LocaleUtil.getLocaleCalendar(2013, 9, 7); + Date expDate = expCal.getTime(); + + ValueEval ve[] = { new StringEval("2013/10/06"), new NumberEval(1) }; + double numberValue = ((NumberEval) WorkdayFunction.instance.evaluate(ve, EC)).getNumberValue(); + assertEquals(41554.0, numberValue, 0); - Date date = DateUtil.getJavaDate(numberValue); - assertEquals("Should be 2013/10/07", new Date(113, 9, 7), date); + Date actDate = DateUtil.getJavaDate(numberValue); + assertEquals(expDate, actDate); } + @Test public void testReturnWorkdaysWhenStartIsWeekendSubtractingDays() { - String startDate = "2013/10/06"; - int days = -1; - StringEval stringEval = new StringEval(startDate); - double numberValue = ((NumberEval) WorkdayFunction.instance.evaluate(new ValueEval[]{ - stringEval, new NumberEval(days) }, EC)).getNumberValue(); - assertEquals(41551.0, numberValue); + Calendar expCal = LocaleUtil.getLocaleCalendar(2013, 9, 4); + Date expDate = expCal.getTime(); + + ValueEval ve[] = { new StringEval("2013/10/06"), new NumberEval(-1) }; + double numberValue = ((NumberEval) WorkdayFunction.instance.evaluate(ve, EC)).getNumberValue(); + assertEquals(41551.0, numberValue, 0); - Date date = DateUtil.getJavaDate(numberValue); - assertEquals("Should be 2013/10/04", new Date(113, 9, 4), date); + Date actDate = DateUtil.getJavaDate(numberValue); + assertEquals(expDate, actDate); } + @Test public void testReturnWorkdaysWithDaysTruncated() { - assertEquals(new Date(109, APRIL, 30), DateUtil.getJavaDate(((NumberEval) WorkdayFunction.instance.evaluate(new ValueEval[]{ - new StringEval(STARTING_DATE), new NumberEval(151.99999) }, EC)).getNumberValue())); + Calendar expCal = LocaleUtil.getLocaleCalendar(2009, 3, 30); + Date expDate = expCal.getTime(); + + ValueEval ve[] = { new StringEval(STARTING_DATE), new NumberEval(151.99999) }; + double numberValue = ((NumberEval) WorkdayFunction.instance.evaluate(ve, EC)).getNumberValue(); + + Date actDate = DateUtil.getJavaDate(numberValue); + assertEquals(expDate, actDate); } + @Test public void testReturnRetroativeWorkday() { - assertEquals(new Date(108, SEPTEMBER, 23), DateUtil.getJavaDate(((NumberEval) WorkdayFunction.instance.evaluate(new ValueEval[]{ - new StringEval(STARTING_DATE), new NumberEval(-5), new StringEval(RETROATIVE_HOLIDAY) }, EC)) - .getNumberValue())); + Calendar expCal = LocaleUtil.getLocaleCalendar(2008, 8, 23); + Date expDate = expCal.getTime(); + + ValueEval ve[] = { new StringEval(STARTING_DATE), new NumberEval(-5), new StringEval(RETROATIVE_HOLIDAY) }; + double numberValue = ((NumberEval) WorkdayFunction.instance.evaluate(ve, EC)).getNumberValue(); + + Date actDate = DateUtil.getJavaDate(numberValue); + assertEquals(expDate, actDate); } + @Test public void testReturnNetworkdaysWithManyHolidays() { - assertEquals(new Date(109, MAY, 5), DateUtil.getJavaDate(((NumberEval) WorkdayFunction.instance.evaluate(new ValueEval[]{ - new StringEval(STARTING_DATE), new NumberEval(151), - new MockAreaEval(FIRST_HOLIDAY, SECOND_HOLIDAY, THIRD_HOLIDAY) }, EC)).getNumberValue())); + Calendar expCal = LocaleUtil.getLocaleCalendar(2009, 4, 5); + Date expDate = expCal.getTime(); + + ValueEval ve[] = { + new StringEval(STARTING_DATE), new NumberEval(151), + new MockAreaEval(FIRST_HOLIDAY, SECOND_HOLIDAY, THIRD_HOLIDAY) }; + double numberValue = ((NumberEval) WorkdayFunction.instance.evaluate(ve, EC)).getNumberValue(); + + Date actDate = DateUtil.getJavaDate(numberValue); + assertEquals(expDate, actDate); } private class MockAreaEval extends AreaEvalBase { diff --git a/src/testcases/org/apache/poi/ss/formula/atp/TestYearFracCalculator.java b/src/testcases/org/apache/poi/ss/formula/atp/TestYearFracCalculator.java index abd8ba2cc..6094d1860 100644 --- a/src/testcases/org/apache/poi/ss/formula/atp/TestYearFracCalculator.java +++ b/src/testcases/org/apache/poi/ss/formula/atp/TestYearFracCalculator.java @@ -17,20 +17,21 @@ package org.apache.poi.ss.formula.atp; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.Locale; +import static org.junit.Assert.assertEquals; -import junit.framework.TestCase; +import java.util.Calendar; import org.apache.poi.ss.formula.eval.EvaluationException; import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.util.LocaleUtil; +import org.junit.Test; /** * Specific test cases for YearFracCalculator */ -public final class TestYearFracCalculator extends TestCase { +public final class TestYearFracCalculator { + @Test public void testBasis1() { confirm(md(1999, 1, 1), md(1999, 4, 5), 1, 0.257534247); confirm(md(1999, 4, 1), md(1999, 4, 5), 1, 0.010958904); @@ -59,10 +60,7 @@ public final class TestYearFracCalculator extends TestCase { } private static double md(int year, int month, int day) { - Calendar c = new GregorianCalendar(Locale.ROOT); - - c.set(year, month-1, day, 0, 0, 0); - c.set(Calendar.MILLISECOND, 0); + Calendar c = LocaleUtil.getLocaleCalendar(year, month-1, day); return DateUtil.getExcelDate(c.getTime()); } } diff --git a/src/testcases/org/apache/poi/ss/formula/atp/TestYearFracCalculatorFromSpreadsheet.java b/src/testcases/org/apache/poi/ss/formula/atp/TestYearFracCalculatorFromSpreadsheet.java index d735fe8c2..4860d6b05 100644 --- a/src/testcases/org/apache/poi/ss/formula/atp/TestYearFracCalculatorFromSpreadsheet.java +++ b/src/testcases/org/apache/poi/ss/formula/atp/TestYearFracCalculatorFromSpreadsheet.java @@ -17,31 +17,29 @@ package org.apache.poi.ss.formula.atp; -import java.io.PrintStream; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import java.util.Calendar; -import java.util.GregorianCalendar; import java.util.Iterator; -import junit.framework.Assert; -import junit.framework.AssertionFailedError; -import junit.framework.ComparisonFailure; -import junit.framework.TestCase; - import org.apache.poi.hssf.HSSFTestDataSamples; -import org.apache.poi.ss.formula.eval.EvaluationException; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.formula.eval.EvaluationException; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.util.LocaleUtil; +import org.junit.Test; /** * Tests YearFracCalculator using test-cases listed in a sample spreadsheet - * - * @author Josh Micich */ -public final class TestYearFracCalculatorFromSpreadsheet extends TestCase { +public final class TestYearFracCalculatorFromSpreadsheet { private static final class SS { @@ -52,15 +50,14 @@ public final class TestYearFracCalculatorFromSpreadsheet extends TestCase { public static final int EXPECTED_RESULT_COLUMN = 13; // "N" } - public void testAll() { + @Test + public void testAll() throws Exception { HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("yearfracExamples.xls"); HSSFSheet sheet = wb.getSheetAt(0); HSSFFormulaEvaluator formulaEvaluator = new HSSFFormulaEvaluator(wb); int nSuccess = 0; - int nFailures = 0; - int nUnexpectedErrors = 0; - Iterator rowIterator = sheet.rowIterator(); + Iterator rowIterator = sheet.rowIterator(); while(rowIterator.hasNext()) { HSSFRow row = (HSSFRow) rowIterator.next(); @@ -68,28 +65,16 @@ public final class TestYearFracCalculatorFromSpreadsheet extends TestCase { if (cell == null || cell.getCellType() != HSSFCell.CELL_TYPE_FORMULA) { continue; } - try { - processRow(row, cell, formulaEvaluator); - nSuccess++; - } catch (RuntimeException e) { - nUnexpectedErrors ++; - printShortStackTrace(System.err, e); - } catch (AssertionFailedError e) { - nFailures ++; - printShortStackTrace(System.err, e); - } - } - if (nUnexpectedErrors + nFailures > 0) { - String msg = nFailures + " failures(s) and " + nUnexpectedErrors - + " unexpected errors(s) occurred. See stderr for details"; - throw new AssertionFailedError(msg); - } - if (nSuccess < 1) { - throw new RuntimeException("No test sample cases found"); + processRow(row, cell, formulaEvaluator); + nSuccess++; } + + assertTrue("No test sample cases found", nSuccess > 0); + wb.close(); } - private static void processRow(HSSFRow row, HSSFCell cell, HSSFFormulaEvaluator formulaEvaluator) { + private void processRow(HSSFRow row, HSSFCell cell, HSSFFormulaEvaluator formulaEvaluator) + throws EvaluationException { double startDate = makeDate(row, SS.START_YEAR_COLUMN); double endDate = makeDate(row, SS.END_YEAR_COLUMN); @@ -98,81 +83,33 @@ public final class TestYearFracCalculatorFromSpreadsheet extends TestCase { double expectedValue = getDoubleCell(row, SS.EXPECTED_RESULT_COLUMN); - double actualValue; - try { - actualValue = YearFracCalculator.calculate(startDate, endDate, basis); - } catch (EvaluationException e) { - throw new RuntimeException(e); - } - if (expectedValue != actualValue) { - throw new ComparisonFailure("Direct calculate failed - row " + (row.getRowNum()+1), - String.valueOf(expectedValue), String.valueOf(actualValue)); - } + double actualValue = YearFracCalculator.calculate(startDate, endDate, basis); + + String loc = " - row " + (row.getRowNum()+1); + assertEquals("Direct calculate failed"+loc, expectedValue, actualValue, 0); actualValue = formulaEvaluator.evaluate(cell).getNumberValue(); - if (expectedValue != actualValue) { - throw new ComparisonFailure("Formula evaluate failed - row " + (row.getRowNum()+1), - String.valueOf(expectedValue), String.valueOf(actualValue)); - } + assertEquals("Formula evaluate failed"+loc, expectedValue, actualValue, 0); } private static double makeDate(HSSFRow row, int yearColumn) { int year = getIntCell(row, yearColumn + 0); int month = getIntCell(row, yearColumn + 1); int day = getIntCell(row, yearColumn + 2); - Calendar c = new GregorianCalendar(year, month-1, day, 0, 0, 0); - c.set(Calendar.MILLISECOND, 0); + Calendar c = LocaleUtil.getLocaleCalendar(year, month-1, day); return HSSFDateUtil.getExcelDate(c.getTime()); } private static int getIntCell(HSSFRow row, int colIx) { double dVal = getDoubleCell(row, colIx); - if (Math.floor(dVal) != dVal) { - throw new RuntimeException("Non integer value (" + dVal - + ") cell found at column " + (char)('A' + colIx)); - } + String msg = "Non integer value (" + dVal + ") cell found at column " + (char)('A' + colIx); + assertEquals(msg, Math.floor(dVal), dVal, 0); return (int)dVal; } private static double getDoubleCell(HSSFRow row, int colIx) { HSSFCell cell = row.getCell(colIx); - if (cell == null) { - throw new RuntimeException("No cell found at column " + colIx); - } + assertNotNull("No cell found at column " + colIx, cell); double dVal = cell.getNumericCellValue(); return dVal; } - - /** - * Useful to keep output concise when expecting many failures to be reported by this test case - * TODO - refactor duplicates in other Test~FromSpreadsheet classes - */ - private static void printShortStackTrace(PrintStream ps, Throwable e) { - StackTraceElement[] stes = e.getStackTrace(); - - int startIx = 0; - // skip any top frames inside junit.framework.Assert - while(startIx= endIx) { - // something went wrong. just print the whole stack trace - e.printStackTrace(ps); - } - endIx -= 4; // skip 4 frames of reflection invocation - ps.println(e.toString()); - for(int i=startIx; i @@ -49,248 +51,166 @@ import junit.framework.TestCase; * exercised as well. Tests for bug fixes and specific/tricky behaviour can be found in the * corresponding test class (TestXxxx) of the target (Xxxx) implementor, * where execution can be observed more easily. - * - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > */ +@RunWith(Parameterized.class) public final class TestFormulasFromSpreadsheet { - private static final POILogger logger = POILogFactory.getLogger(TestFormulasFromSpreadsheet.class); - private static final class Result { - public static final int SOME_EVALUATIONS_FAILED = -1; - public static final int ALL_EVALUATIONS_SUCCEEDED = +1; - public static final int NO_EVALUATIONS_FOUND = 0; - } - - /** + private static HSSFWorkbook workbook; + private static Sheet sheet; + private static HSSFFormulaEvaluator evaluator; + private static Locale userLocale; + + /** * This class defines constants for navigating around the test data spreadsheet used for these tests. */ - private static final class SS { + private static interface SS { /** * Name of the test spreadsheet (found in the standard test data folder) */ - public final static String FILENAME = "FormulaEvalTestData.xls"; + String FILENAME = "FormulaEvalTestData.xls"; /** * Row (zero-based) in the test spreadsheet where the operator examples start. */ - public static final int START_OPERATORS_ROW_INDEX = 22; // Row '23' + int START_OPERATORS_ROW_INDEX = 22; // Row '23' /** * Row (zero-based) in the test spreadsheet where the function examples start. */ - public static final int START_FUNCTIONS_ROW_INDEX = 95; // Row '96' + int START_FUNCTIONS_ROW_INDEX = 95; // Row '96' /** * Index of the column that contains the function names */ - public static final int COLUMN_INDEX_FUNCTION_NAME = 1; // Column 'B' + int COLUMN_INDEX_FUNCTION_NAME = 1; // Column 'B' /** * Used to indicate when there are no more functions left */ - public static final String FUNCTION_NAMES_END_SENTINEL = ""; + String FUNCTION_NAMES_END_SENTINEL = ""; /** * Index of the column where the test values start (for each function) */ - public static final short COLUMN_INDEX_FIRST_TEST_VALUE = 3; // Column 'D' + short COLUMN_INDEX_FIRST_TEST_VALUE = 3; // Column 'D' /** * Each function takes 4 rows in the test spreadsheet */ - public static final int NUMBER_OF_ROWS_PER_FUNCTION = 4; + int NUMBER_OF_ROWS_PER_FUNCTION = 4; } - private HSSFWorkbook workbook; - private Sheet sheet; - // Note - multiple failures are aggregated before ending. - // If one or more functions fail, a single AssertionFailedError is thrown at the end - private int _functionFailureCount; - private int _functionSuccessCount; - private int _evaluationFailureCount; - private int _evaluationSuccessCount; + @Parameter(value = 0) + public String targetFunctionName; + @Parameter(value = 1) + public int formulasRowIdx; + @Parameter(value = 2) + public int expectedValuesRowIdx; - private static final Cell getExpectedValueCell(Row row, int columnIndex) { - if (row == null) { - return null; - } - return row.getCell(columnIndex); - } + @AfterClass + public static void closeResource() throws Exception { + LocaleUtil.setUserLocale(userLocale); + workbook.close(); + } + @Parameters(name="{0}") + public static Collection data() throws Exception { + // Function "Text" uses custom-formats which are locale specific + // can't set the locale on a per-testrun execution, as some settings have been + // already set, when we would try to change the locale by then + userLocale = LocaleUtil.getUserLocale(); + LocaleUtil.setUserLocale(Locale.ROOT); - private static void confirmExpectedResult(String msg, Cell expected, CellValue actual) { - assertNotNull(msg + " - Bad setup data expected value is null", expected); - assertNotNull(msg + " - actual value was null", actual); + workbook = HSSFTestDataSamples.openSampleWorkbook(SS.FILENAME); + sheet = workbook.getSheetAt( 0 ); + evaluator = new HSSFFormulaEvaluator(workbook); + + List data = new ArrayList(); + + processFunctionGroup(data, SS.START_OPERATORS_ROW_INDEX, null); + processFunctionGroup(data, SS.START_FUNCTIONS_ROW_INDEX, null); + // example for debugging individual functions/operators: + // processFunctionGroup(data, SS.START_OPERATORS_ROW_INDEX, "ConcatEval"); + // processFunctionGroup(data, SS.START_FUNCTIONS_ROW_INDEX, "Text"); - switch (expected.getCellType()) { - case Cell.CELL_TYPE_BLANK: - assertEquals(msg, Cell.CELL_TYPE_BLANK, actual.getCellType()); - break; - case Cell.CELL_TYPE_BOOLEAN: - assertEquals(msg, Cell.CELL_TYPE_BOOLEAN, actual.getCellType()); - assertEquals(msg, expected.getBooleanCellValue(), actual.getBooleanValue()); - break; - case Cell.CELL_TYPE_ERROR: - assertEquals(msg, Cell.CELL_TYPE_ERROR, actual.getCellType()); - assertEquals(msg, ErrorEval.getText(expected.getErrorCellValue()), ErrorEval.getText(actual.getErrorValue())); - break; - case Cell.CELL_TYPE_FORMULA: // will never be used, since we will call method after formula evaluation - fail("Cannot expect formula as result of formula evaluation: " + msg); - case Cell.CELL_TYPE_NUMERIC: - assertEquals(msg, Cell.CELL_TYPE_NUMERIC, actual.getCellType()); - TestMathX.assertEquals(msg, expected.getNumericCellValue(), actual.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR); - break; - case Cell.CELL_TYPE_STRING: - assertEquals(msg, Cell.CELL_TYPE_STRING, actual.getCellType()); - assertEquals(msg, expected.getRichStringCellValue().getString(), actual.getStringValue()); - break; - } - } - - @Before - protected void setUp() { - if (workbook == null) { - workbook = HSSFTestDataSamples.openSampleWorkbook(SS.FILENAME); - sheet = workbook.getSheetAt( 0 ); - } - _functionFailureCount = 0; - _functionSuccessCount = 0; - _evaluationFailureCount = 0; - _evaluationSuccessCount = 0; - } - - @Test - public void testFunctionsFromTestSpreadsheet() { - - processFunctionGroup(SS.START_OPERATORS_ROW_INDEX, null); - processFunctionGroup(SS.START_FUNCTIONS_ROW_INDEX, null); - // example for debugging individual functions/operators: -// processFunctionGroup(SS.START_OPERATORS_ROW_INDEX, "ConcatEval"); -// processFunctionGroup(SS.START_FUNCTIONS_ROW_INDEX, "AVERAGE"); - - // confirm results - String successMsg = "There were " - + _evaluationSuccessCount + " successful evaluation(s) and " - + _functionSuccessCount + " function(s) without error"; - String msg = _functionFailureCount + " function(s) failed in " - + _evaluationFailureCount + " evaluation(s). " + successMsg; - assertEquals(msg, _functionFailureCount, 0); - logger.log(POILogger.INFO, getClass().getName() + ": " + successMsg); - } - - /** - * @param startRowIndex row index in the spreadsheet where the first function/operator is found - * @param testFocusFunctionName name of a single function/operator to test alone. - * Typically pass null to test all functions - */ - private void processFunctionGroup(int startRowIndex, String testFocusFunctionName) { - HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(workbook); - Collection funcs = FunctionEval.getSupportedFunctionNames(); - - int rowIndex = startRowIndex; - while (true) { - Row r = sheet.getRow(rowIndex); - String targetFunctionName = getTargetFunctionName(r); - assertNotNull("Test spreadsheet cell empty on row (" + return data; + } + + /** + * @param startRowIndex row index in the spreadsheet where the first function/operator is found + * @param testFocusFunctionName name of a single function/operator to test alone. + * Typically pass null to test all functions + */ + private static void processFunctionGroup(List data, int startRowIndex, String testFocusFunctionName) { + for (int rowIndex = startRowIndex; true; rowIndex += SS.NUMBER_OF_ROWS_PER_FUNCTION) { + Row r = sheet.getRow(rowIndex); + String targetFunctionName = getTargetFunctionName(r); + assertNotNull("Test spreadsheet cell empty on row (" + (rowIndex+1) + "). Expected function name or '" + SS.FUNCTION_NAMES_END_SENTINEL + "'", targetFunctionName); - if(targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) { - // found end of functions list - break; - } - if(testFocusFunctionName == null || targetFunctionName.equalsIgnoreCase(testFocusFunctionName)) { + if(targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) { + // found end of functions list + break; + } + if(testFocusFunctionName == null || targetFunctionName.equalsIgnoreCase(testFocusFunctionName)) { - // expected results are on the row below - Row expectedValuesRow = sheet.getRow(rowIndex + 1); + // expected results are on the row below + Row expectedValuesRow = sheet.getRow(rowIndex + 1); int missingRowNum = rowIndex + 2; //+1 for 1-based, +1 for next row assertNotNull("Missing expected values row for function '" + targetFunctionName + " (row " + missingRowNum + ")", expectedValuesRow); - switch(processFunctionRow(evaluator, targetFunctionName, r, expectedValuesRow)) { - case Result.ALL_EVALUATIONS_SUCCEEDED: _functionSuccessCount++; break; - case Result.SOME_EVALUATIONS_FAILED: _functionFailureCount++; break; - default: - throw new RuntimeException("unexpected result"); - case Result.NO_EVALUATIONS_FOUND: // do nothing - String uname = targetFunctionName.toUpperCase(Locale.ROOT); - if(startRowIndex >= SS.START_FUNCTIONS_ROW_INDEX && - funcs.contains(uname)) { - logger.log(POILogger.WARN, uname + ": function is supported but missing test data"); - } - break; - } - } - rowIndex += SS.NUMBER_OF_ROWS_PER_FUNCTION; - } - } - /** - * - * @return a constant from the local Result class denoting whether there were any evaluation - * cases, and whether they all succeeded. - */ - private int processFunctionRow(HSSFFormulaEvaluator evaluator, String targetFunctionName, - Row formulasRow, Row expectedValuesRow) { + data.add(new Object[]{targetFunctionName, rowIndex, rowIndex + 1}); + } + } + } - int result = Result.NO_EVALUATIONS_FOUND; // so far - short endcolnum = formulasRow.getLastCellNum(); + @Test + public void processFunctionRow() { + Row formulasRow = sheet.getRow(formulasRowIdx); + Row expectedValuesRow = sheet.getRow(expectedValuesRowIdx); - // iterate across the row for all the evaluation cases - for (int colnum=SS.COLUMN_INDEX_FIRST_TEST_VALUE; colnum < endcolnum; colnum++) { - Cell c = formulasRow.getCell(colnum); - if (c == null || c.getCellType() != Cell.CELL_TYPE_FORMULA) { - continue; - } + short endcolnum = formulasRow.getLastCellNum(); - CellValue actualValue = evaluator.evaluate(c); + // iterate across the row for all the evaluation cases + for (int colnum=SS.COLUMN_INDEX_FIRST_TEST_VALUE; colnum < endcolnum; colnum++) { + Cell c = formulasRow.getCell(colnum); + if (c == null || c.getCellType() != Cell.CELL_TYPE_FORMULA) { + continue; + } - Cell expectedValueCell = getExpectedValueCell(expectedValuesRow, colnum); - try { - confirmExpectedResult("Function '" + targetFunctionName + "': Formula: " + c.getCellFormula() + " @ " + formulasRow.getRowNum() + ":" + colnum, - expectedValueCell, actualValue); - _evaluationSuccessCount ++; - if(result != Result.SOME_EVALUATIONS_FAILED) { - result = Result.ALL_EVALUATIONS_SUCCEEDED; - } - } catch (AssertionFailedError e) { - _evaluationFailureCount ++; - printShortStackTrace(System.err, e); - result = Result.SOME_EVALUATIONS_FAILED; - } - } - return result; - } + CellValue actValue = evaluator.evaluate(c); + Cell expValue = (expectedValuesRow == null) ? null : expectedValuesRow.getCell(colnum); - /** - * Useful to keep output concise when expecting many failures to be reported by this test case - */ - private static void printShortStackTrace(PrintStream ps, AssertionFailedError e) { - StackTraceElement[] stes = e.getStackTrace(); + String msg = String.format(Locale.ROOT, "Function '%s': Formula: %s @ %d:%d" + , targetFunctionName, c.getCellFormula(), formulasRow.getRowNum(), colnum); - int startIx = 0; - // skip any top frames inside junit.framework.Assert - while(startIx= endIx) { - // something went wrong. just print the whole stack trace - e.printStackTrace(ps); - } - endIx -= 4; // skip 4 frames of reflection invocation - ps.println(e.toString()); - for(int i=startIx; inull if cell is missing, empty or blank */ diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestDays360.java b/src/testcases/org/apache/poi/ss/formula/functions/TestDays360.java index 29fabef20..dbe41a883 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestDays360.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestDays360.java @@ -28,6 +28,7 @@ import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.ss.formula.eval.BoolEval; import org.apache.poi.ss.formula.eval.NumberEval; import org.apache.poi.ss.formula.eval.ValueEval; +import org.apache.poi.util.LocaleUtil; import org.junit.Test; public final class TestDays360 { @@ -36,14 +37,13 @@ public final class TestDays360 { * @param month 1-based */ private static Date makeDate(int year, int month, int day) { - Calendar cal = Calendar.getInstance(Locale.ROOT); - cal.set(year, month-1, day, 0, 0, 0); - cal.set(Calendar.MILLISECOND, 0); + Calendar cal = LocaleUtil.getLocaleCalendar(year, month-1, day); return cal.getTime(); } private static Date decrementDay(Date d) { - Calendar c = (Calendar)d.clone(); + Calendar c = LocaleUtil.getLocaleCalendar(); + c.setTime(d); c.add(Calendar.DAY_OF_MONTH, -1); return c.getTime(); } diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestEDate.java b/src/testcases/org/apache/poi/ss/formula/functions/TestEDate.java index 3917f44cb..e8eaf4c5f 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestEDate.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestEDate.java @@ -17,22 +17,24 @@ package org.apache.poi.ss.formula.functions; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import java.util.Calendar; import java.util.Date; -import junit.framework.TestCase; - -import org.apache.poi.ss.formula.eval.AreaEval; import org.apache.poi.ss.formula.eval.BlankEval; import org.apache.poi.ss.formula.eval.ErrorEval; import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.RefEval; import org.apache.poi.ss.formula.eval.ValueEval; import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.ErrorConstants; +import org.apache.poi.util.LocaleUtil; +import org.junit.Test; -public class TestEDate extends TestCase { +public class TestEDate { + @Test public void testEDateProperValues() { // verify some border-case combinations of startDate and month-increase checkValue(1000, 0, 1000d); @@ -49,71 +51,79 @@ public class TestEDate extends TestCase { private void checkValue(int startDate, int monthInc, double expectedResult) { EDate eDate = new EDate(); NumberEval result = (NumberEval) eDate.evaluate(new ValueEval[]{new NumberEval(startDate), new NumberEval(monthInc)}, null); - assertEquals(expectedResult, result.getNumberValue()); + assertEquals(expectedResult, result.getNumberValue(), 0); } + @Test public void testEDateInvalidValues() { EDate eDate = new EDate(); ErrorEval result = (ErrorEval) eDate.evaluate(new ValueEval[]{new NumberEval(1000)}, null); - assertEquals(ErrorConstants.ERROR_VALUE, result.getErrorCode()); + assertEquals(ErrorConstants.ERROR_VALUE, result.getErrorCode(), 0); } + @Test public void testEDateIncrease() { EDate eDate = new EDate(); Date startDate = new Date(); int offset = 2; NumberEval result = (NumberEval) eDate.evaluate(new ValueEval[]{new NumberEval(DateUtil.getExcelDate(startDate)), new NumberEval(offset)}, null); Date resultDate = DateUtil.getJavaDate(result.getNumberValue()); - Calendar instance = Calendar.getInstance(); + Calendar instance = LocaleUtil.getLocaleCalendar(); instance.setTime(startDate); instance.add(Calendar.MONTH, offset); assertEquals(resultDate, instance.getTime()); } + @Test public void testEDateDecrease() { EDate eDate = new EDate(); Date startDate = new Date(); int offset = -2; NumberEval result = (NumberEval) eDate.evaluate(new ValueEval[]{new NumberEval(DateUtil.getExcelDate(startDate)), new NumberEval(offset)}, null); Date resultDate = DateUtil.getJavaDate(result.getNumberValue()); - Calendar instance = Calendar.getInstance(); + Calendar instance = LocaleUtil.getLocaleCalendar(); instance.setTime(startDate); instance.add(Calendar.MONTH, offset); assertEquals(resultDate, instance.getTime()); } + @Test public void testBug56688() { EDate eDate = new EDate(); NumberEval result = (NumberEval) eDate.evaluate(new ValueEval[]{new NumberEval(1000), new RefEvalImplementation(new NumberEval(0))}, null); - assertEquals(1000d, result.getNumberValue()); + assertEquals(1000d, result.getNumberValue(), 0); } + @Test public void testRefEvalStartDate() { EDate eDate = new EDate(); NumberEval result = (NumberEval) eDate.evaluate(new ValueEval[]{new RefEvalImplementation(new NumberEval(1000)), new NumberEval(0)}, null); - assertEquals(1000d, result.getNumberValue()); + assertEquals(1000d, result.getNumberValue(), 0); } + @Test public void testEDateInvalidValueEval() { ValueEval evaluate = new EDate().evaluate(new ValueEval[]{new ValueEval() {}, new NumberEval(0)}, null); assertTrue(evaluate instanceof ErrorEval); assertEquals(ErrorEval.VALUE_INVALID, evaluate); } + @Test public void testEDateBlankValueEval() { NumberEval evaluate = (NumberEval) new EDate().evaluate(new ValueEval[]{BlankEval.instance, new NumberEval(0)}, null); - assertEquals(-1.0d, evaluate.getNumberValue()); + assertEquals(-1.0d, evaluate.getNumberValue(), 0); } + @Test public void testEDateBlankRefValueEval() { EDate eDate = new EDate(); NumberEval result = (NumberEval) eDate.evaluate(new ValueEval[]{new RefEvalImplementation(BlankEval.instance), new NumberEval(0)}, null); assertEquals("0 startDate triggers BAD_DATE currently, thus -1.0!", - -1.0d, result.getNumberValue()); + -1.0d, result.getNumberValue(), 0); result = (NumberEval) eDate.evaluate(new ValueEval[]{new NumberEval(1), new RefEvalImplementation(BlankEval.instance)}, null); assertEquals("Blank is handled as 0 otherwise", - 1.0d, result.getNumberValue()); + 1.0d, result.getNumberValue(), 0); } } diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestEOMonth.java b/src/testcases/org/apache/poi/ss/formula/functions/TestEOMonth.java index 55372b03a..1a15760a7 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestEOMonth.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestEOMonth.java @@ -17,12 +17,13 @@ package org.apache.poi.ss.formula.functions; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import java.util.Calendar; import java.util.Date; -import junit.framework.TestCase; import org.apache.poi.ss.formula.OperationEvaluationContext; - import org.apache.poi.ss.formula.eval.BlankEval; import org.apache.poi.ss.formula.eval.ErrorEval; import org.apache.poi.ss.formula.eval.NumberEval; @@ -30,8 +31,10 @@ import org.apache.poi.ss.formula.eval.StringEval; import org.apache.poi.ss.formula.eval.ValueEval; import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.ErrorConstants; +import org.apache.poi.util.LocaleUtil; +import org.junit.Test; -public class TestEOMonth extends TestCase{ +public class TestEOMonth { private static final double BAD_DATE = -1.0; @@ -47,6 +50,7 @@ public class TestEOMonth extends TestCase{ private final FreeRefFunction eOMonth = EOMonth.instance; private final OperationEvaluationContext ec = new OperationEvaluationContext(null, null, 0, 0, 0, null); + @Test public void testEOMonthProperValues() { // verify some border-case combinations of startDate and month-increase checkValue(DATE_1900_01_01, 0, DATE_1900_01_31); @@ -56,6 +60,7 @@ public class TestEOMonth extends TestCase{ checkValue(DATE_2034_06_09, 1, DATE_2034_07_31); } + @Test public void testEOMonthBadDateValues() { checkValue(0.0, -2, BAD_DATE); checkValue(0.0, -3, BAD_DATE); @@ -63,74 +68,85 @@ public class TestEOMonth extends TestCase{ } private void checkValue(double startDate, int monthInc, double expectedResult) { - NumberEval result = (NumberEval) eOMonth.evaluate(new ValueEval[] {new NumberEval(startDate), new NumberEval(monthInc)}, ec); - assertEquals(expectedResult, result.getNumberValue()); + ValueEval ve[] = {new NumberEval(startDate), new NumberEval(monthInc)}; + NumberEval result = (NumberEval) eOMonth.evaluate(ve, ec); + assertEquals(expectedResult, result.getNumberValue(), 0); } + @Test public void testEOMonthZeroDate() { NumberEval result = (NumberEval) eOMonth.evaluate(new ValueEval[] {new NumberEval(0), new NumberEval(0)}, ec); - assertEquals("0 startDate is 1900-01-00", DATE_1900_01_31, result.getNumberValue()); + assertEquals("0 startDate is 1900-01-00", DATE_1900_01_31, result.getNumberValue(), 0); result = (NumberEval) eOMonth.evaluate(new ValueEval[] {new NumberEval(0), new NumberEval(1)}, ec); - assertEquals("0 startDate is 1900-01-00", DATE_1900_02_28, result.getNumberValue()); + assertEquals("0 startDate is 1900-01-00", DATE_1900_02_28, result.getNumberValue(), 0); } + @Test public void testEOMonthInvalidArguments() { ValueEval result = eOMonth.evaluate(new ValueEval[] {new NumberEval(DATE_1902_09_26)}, ec); assertTrue(result instanceof ErrorEval); - assertEquals(ErrorConstants.ERROR_VALUE, ((ErrorEval) result).getErrorCode()); + assertEquals(ErrorConstants.ERROR_VALUE, ((ErrorEval) result).getErrorCode(), 0); result = eOMonth.evaluate(new ValueEval[] {new StringEval("a"), new StringEval("b")}, ec); assertTrue(result instanceof ErrorEval); - assertEquals(ErrorConstants.ERROR_VALUE, ((ErrorEval) result).getErrorCode()); + assertEquals(ErrorConstants.ERROR_VALUE, ((ErrorEval) result).getErrorCode(), 0); } - public void testEOMonthIncrease() { - checkOffset(new Date(), 2); - } - - public void testEOMonthDecrease() { - checkOffset(new Date(), -2); - } - - private void checkOffset(Date startDate, int offset) { - NumberEval result = (NumberEval) eOMonth.evaluate(new ValueEval[] {new NumberEval(DateUtil.getExcelDate(startDate)), new NumberEval(offset)}, ec); - Date resultDate = DateUtil.getJavaDate(result.getNumberValue()); - Calendar instance = Calendar.getInstance(); - instance.setTime(startDate); - instance.add(Calendar.MONTH, offset); - instance.add(Calendar.MONTH, 1); - instance.set(Calendar.DAY_OF_MONTH, 1); - instance.add(Calendar.DAY_OF_MONTH, -1); - instance.set(Calendar.HOUR_OF_DAY, 0); - instance.set(Calendar.MINUTE, 0); - instance.set(Calendar.SECOND, 0); - instance.set(Calendar.MILLISECOND, 0); - assertEquals(instance.getTime(), resultDate); + @Test + public void checkOffset() { + for (int offset=-12; offset<=12; offset++) { + Calendar cal = LocaleUtil.getLocaleCalendar(); + Date startDate = cal.getTime(); + + cal.add(Calendar.MONTH, offset); + cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); + cal.clear(Calendar.HOUR); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.clear(Calendar.MINUTE); + cal.clear(Calendar.SECOND); + cal.clear(Calendar.MILLISECOND); + Date expDate = cal.getTime(); + + ValueEval ve[] = { + new NumberEval(DateUtil.getExcelDate(startDate)), + new NumberEval(offset) + }; + NumberEval result = (NumberEval) eOMonth.evaluate(ve, ec); + Date actDate = DateUtil.getJavaDate(result.getNumberValue()); + + assertEquals(expDate, actDate); + } } + @Test public void testBug56688() { - NumberEval result = (NumberEval) eOMonth.evaluate(new ValueEval[] {new NumberEval(DATE_1902_09_26), new RefEvalImplementation(new NumberEval(0))}, ec); - assertEquals(DATE_1902_09_30, result.getNumberValue()); + ValueEval ve[] = {new NumberEval(DATE_1902_09_26), new RefEvalImplementation(new NumberEval(0))}; + NumberEval result = (NumberEval) eOMonth.evaluate(ve, ec); + assertEquals(DATE_1902_09_30, result.getNumberValue(), 0); } + @Test public void testRefEvalStartDate() { - NumberEval result = (NumberEval) eOMonth.evaluate(new ValueEval[] {new RefEvalImplementation(new NumberEval(DATE_1902_09_26)), new NumberEval(0)}, ec); - assertEquals(DATE_1902_09_30, result.getNumberValue()); + ValueEval ve[] = {new RefEvalImplementation(new NumberEval(DATE_1902_09_26)), new NumberEval(0)}; + NumberEval result = (NumberEval) eOMonth.evaluate(ve, ec); + assertEquals(DATE_1902_09_30, result.getNumberValue(), 0); } + @Test public void testEOMonthBlankValueEval() { NumberEval evaluate = (NumberEval) eOMonth.evaluate(new ValueEval[] {BlankEval.instance, new NumberEval(0)}, ec); - assertEquals("Blank is handled as 0", DATE_1900_01_31, evaluate.getNumberValue()); + assertEquals("Blank is handled as 0", DATE_1900_01_31, evaluate.getNumberValue(), 0); } + @Test public void testEOMonthBlankRefValueEval() { - NumberEval result = (NumberEval) eOMonth.evaluate(new ValueEval[] {new RefEvalImplementation(BlankEval.instance), new NumberEval(1)}, ec); - assertEquals("Blank is handled as 0", - DATE_1900_02_28, result.getNumberValue()); + ValueEval[] ve1 = {new RefEvalImplementation(BlankEval.instance), new NumberEval(1)}; + NumberEval result = (NumberEval) eOMonth.evaluate(ve1, ec); + assertEquals("Blank is handled as 0", DATE_1900_02_28, result.getNumberValue(), 0); - result = (NumberEval) eOMonth.evaluate(new ValueEval[] {new NumberEval(1), new RefEvalImplementation(BlankEval.instance)}, ec); - assertEquals("Blank is handled as 0", - DATE_1900_01_31, result.getNumberValue()); + ValueEval[] ve2 = {new NumberEval(1), new RefEvalImplementation(BlankEval.instance)}; + result = (NumberEval) eOMonth.evaluate(ve2, ec); + assertEquals("Blank is handled as 0", DATE_1900_01_31, result.getNumberValue(), 0); } } diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestText.java b/src/testcases/org/apache/poi/ss/formula/functions/TestText.java index 9b330ca42..4249de677 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestText.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestText.java @@ -17,21 +17,25 @@ package org.apache.poi.ss.formula.functions; +import static org.junit.Assert.assertEquals; + +import java.text.DateFormatSymbols; import java.text.DecimalFormatSymbols; import java.text.SimpleDateFormat; -import java.util.GregorianCalendar; -import java.util.Locale; +import java.util.TimeZone; -import junit.framework.TestCase; import org.apache.poi.ss.formula.eval.ErrorEval; import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.ValueEval; import org.apache.poi.ss.formula.eval.StringEval; +import org.apache.poi.ss.formula.eval.ValueEval; +import org.apache.poi.util.LocaleUtil; +import org.junit.Test; /** * Test case for TEXT() */ -public final class TestText extends TestCase { +public final class TestText { + @Test public void testTextWithStringFirstArg() { ValueEval strArg = new StringEval("abc"); ValueEval formatArg = new StringEval("abc"); @@ -40,13 +44,14 @@ public final class TestText extends TestCase { assertEquals(ErrorEval.VALUE_INVALID, result); } + @Test public void testTextWithDeciamlFormatSecondArg() { ValueEval numArg = new NumberEval(321321.321); ValueEval formatArg = new StringEval("#,###.00000"); ValueEval[] args = { numArg, formatArg }; ValueEval result = TextFunction.TEXT.evaluate(args, -1, (short)-1); - char groupSeparator = new DecimalFormatSymbols(Locale.getDefault()).getGroupingSeparator(); - char decimalSeparator = new DecimalFormatSymbols(Locale.getDefault()).getDecimalSeparator(); + char groupSeparator = new DecimalFormatSymbols(LocaleUtil.getUserLocale()).getGroupingSeparator(); + char decimalSeparator = new DecimalFormatSymbols(LocaleUtil.getUserLocale()).getDecimalSeparator(); ValueEval testResult = new StringEval("321" + groupSeparator + "321" + decimalSeparator + "32100"); assertEquals(testResult.toString(), result.toString()); numArg = new NumberEval(321.321); @@ -64,6 +69,7 @@ public final class TestText extends TestCase { assertEquals(testResult.toString(), result.toString()); } + @Test public void testTextWithFractionFormatSecondArg() { ValueEval numArg = new NumberEval(321.321); ValueEval formatArg = new StringEval("# #/#"); @@ -85,37 +91,47 @@ public final class TestText extends TestCase { assertEquals(testResult.toString(), result.toString()); } + @Test public void testTextWithDateFormatSecondArg() { - // Test with Java style M=Month - ValueEval numArg = new NumberEval(321.321); - ValueEval formatArg = new StringEval("dd:MM:yyyy hh:mm:ss"); - ValueEval[] args = { numArg, formatArg }; - ValueEval result = TextFunction.TEXT.evaluate(args, -1, (short)-1); - ValueEval testResult = new StringEval("16:11:1900 07:42:14"); - assertEquals(testResult.toString(), result.toString()); - - // Excel also supports "m before h is month" - formatArg = new StringEval("dd:mm:yyyy hh:mm:ss"); - args[1] = formatArg; - result = TextFunction.TEXT.evaluate(args, -1, (short)-1); - testResult = new StringEval("16:11:1900 07:42:14"); - assertEquals(testResult.toString(), result.toString()); - - // this line is intended to compute how "November" would look like in the current locale - String november = new SimpleDateFormat("MMMM").format(new GregorianCalendar(2010,10,15).getTime()); - - // Again with Java style - formatArg = new StringEval("MMMM dd, yyyy"); - args[1] = formatArg; - result = TextFunction.TEXT.evaluate(args, -1, (short)-1); - testResult = new StringEval(november + " 16, 1900"); - assertEquals(testResult.toString(), result.toString()); - - // And Excel style - formatArg = new StringEval("mmmm dd, yyyy"); - args[1] = formatArg; - result = TextFunction.TEXT.evaluate(args, -1, (short)-1); - testResult = new StringEval(november + " 16, 1900"); - assertEquals(testResult.toString(), result.toString()); + TimeZone userTZ = LocaleUtil.getUserTimeZone(); + LocaleUtil.setUserTimeZone(TimeZone.getTimeZone("CET")); + try { + // Test with Java style M=Month + ValueEval numArg = new NumberEval(321.321); + ValueEval formatArg = new StringEval("dd:MM:yyyy hh:mm:ss"); + ValueEval[] args = { numArg, formatArg }; + ValueEval result = TextFunction.TEXT.evaluate(args, -1, (short)-1); + ValueEval testResult = new StringEval("16:11:1900 07:42:14"); + assertEquals(testResult.toString(), result.toString()); + + // Excel also supports "m before h is month" + formatArg = new StringEval("dd:mm:yyyy hh:mm:ss"); + args[1] = formatArg; + result = TextFunction.TEXT.evaluate(args, -1, (short)-1); + testResult = new StringEval("16:11:1900 07:42:14"); + assertEquals(testResult.toString(), result.toString()); + + // this line is intended to compute how "November" would look like in the current locale + // update: now the locale will be (if not set otherwise) always Locale.getDefault() (see LocaleUtil) + DateFormatSymbols dfs = DateFormatSymbols.getInstance(LocaleUtil.getUserLocale()); + SimpleDateFormat sdf = new SimpleDateFormat("MMMM", dfs); + String november = sdf.format(LocaleUtil.getLocaleCalendar(2015,10,1).getTime()); + + // Again with Java style + formatArg = new StringEval("MMMM dd, yyyy"); + args[1] = formatArg; + result = TextFunction.TEXT.evaluate(args, -1, (short)-1); + testResult = new StringEval(november + " 16, 1900"); + assertEquals(testResult.toString(), result.toString()); + + // And Excel style + formatArg = new StringEval("mmmm dd, yyyy"); + args[1] = formatArg; + result = TextFunction.TEXT.evaluate(args, -1, (short)-1); + testResult = new StringEval(november + " 16, 1900"); + assertEquals(testResult.toString(), result.toString()); + } finally { + LocaleUtil.setUserTimeZone(userTZ); + } } } diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestTime.java b/src/testcases/org/apache/poi/ss/formula/functions/TestTime.java index a1f89ff79..7f12c136a 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestTime.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestTime.java @@ -17,9 +17,9 @@ package org.apache.poi.ss.formula.functions; -import java.util.regex.Pattern; +import static org.junit.Assert.assertEquals; -import junit.framework.TestCase; +import java.util.regex.Pattern; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; @@ -28,13 +28,13 @@ import org.apache.poi.hssf.usermodel.HSSFDataFormatter; import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.junit.Before; +import org.junit.Test; /** * Tests for {@link TimeFunc} - * - * @author @author Steven Butler (sebutler @ gmail dot com) */ -public final class TestTime extends TestCase { +public final class TestTime { private static final int SECONDS_PER_MINUTE = 60; private static final int SECONDS_PER_HOUR = 60 * SECONDS_PER_MINUTE; @@ -44,7 +44,8 @@ public final class TestTime extends TestCase { private HSSFWorkbook wb; private HSSFDataFormatter form; private HSSFCellStyle style; - + + @Before public void setUp() { wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet("new sheet"); @@ -58,11 +59,13 @@ public final class TestTime extends TestCase { evaluator = new HSSFFormulaEvaluator(wb); } + @Test public void testSomeArgumentsMissing() { confirm("00:00:00", "TIME(, 0, 0)"); confirm("12:00:00", "TIME(12, , )"); } + @Test public void testValid() { confirm("00:00:01", 0, 0, 1); confirm("00:01:00", 0, 1, 0); @@ -101,7 +104,6 @@ public final class TestTime extends TestCase { } private void confirm(String expectedTimeStr, String formulaText) { -// System.out.println("=" + formulaText); String[] parts = Pattern.compile(":").split(expectedTimeStr); int expH = Integer.parseInt(parts[0]); int expM = Integer.parseInt(parts[1]); diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java index e54eef87c..4d6b31497 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java @@ -17,23 +17,31 @@ package org.apache.poi.ss.usermodel; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import java.io.IOException; import java.util.Calendar; import java.util.Locale; import java.util.TimeZone; -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; - import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.ITestDataProvider; import org.apache.poi.ss.SpreadsheetVersion; +import org.apache.poi.util.LocaleUtil; +import org.junit.Test; + +import junit.framework.AssertionFailedError; /** * Common superclass for testing implementations of * {@link org.apache.poi.ss.usermodel.Cell} */ -public abstract class BaseTestCell extends TestCase { +public abstract class BaseTestCell { protected final ITestDataProvider _testDataProvider; @@ -44,6 +52,7 @@ public abstract class BaseTestCell extends TestCase { _testDataProvider = testDataProvider; } + @Test public void testSetValues() { Workbook book = _testDataProvider.createWorkbook(); Sheet sheet = book.createSheet("test"); @@ -80,7 +89,7 @@ public abstract class BaseTestCell extends TestCase { assertProhibitedValueAccess(cell, Cell.CELL_TYPE_NUMERIC, Cell.CELL_TYPE_BOOLEAN, Cell.CELL_TYPE_FORMULA, Cell.CELL_TYPE_ERROR); - Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ROOT); + Calendar c = LocaleUtil.getLocaleCalendar(); c.setTimeInMillis(123456789); cell.setCellValue(c.getTime()); assertEquals(c.getTime().getTime(), cell.getDateCellValue().getTime()); @@ -132,6 +141,7 @@ public abstract class BaseTestCell extends TestCase { /** * test that Boolean and Error types (BoolErrRecord) are supported properly. */ + @Test public void testBoolErr() { Workbook wb = _testDataProvider.createWorkbook(); @@ -173,6 +183,7 @@ public abstract class BaseTestCell extends TestCase { /** * test that Cell Styles being applied to formulas remain intact */ + @Test public void testFormulaStyle() { Workbook wb = _testDataProvider.createWorkbook(); @@ -214,6 +225,7 @@ public abstract class BaseTestCell extends TestCase { } /**tests the toString() method of HSSFCell*/ + @Test public void testToString() { Workbook wb = _testDataProvider.createWorkbook(); Row r = wb.createSheet("Sheet1").createRow(0); @@ -245,6 +257,7 @@ public abstract class BaseTestCell extends TestCase { /** * Test that setting cached formula result keeps the cell type */ + @Test public void testSetFormulaValue() { Workbook wb = _testDataProvider.createWorkbook(); Sheet s = wb.createSheet(); @@ -278,7 +291,7 @@ public abstract class BaseTestCell extends TestCase { return _testDataProvider.createWorkbook().createSheet("Sheet1").createRow(0).createCell(0); } - + @Test public void testChangeTypeStringToBool() { Cell cell = createACell(); @@ -305,6 +318,7 @@ public abstract class BaseTestCell extends TestCase { assertEquals("FALSE", cell.getRichStringCellValue().getString()); } + @Test public void testChangeTypeBoolToString() { Cell cell = createACell(); @@ -321,6 +335,7 @@ public abstract class BaseTestCell extends TestCase { assertEquals("TRUE", cell.getRichStringCellValue().getString()); } + @Test public void testChangeTypeErrorToNumber() { Cell cell = createACell(); cell.setCellErrorValue((byte)ErrorConstants.ERROR_NAME); @@ -332,6 +347,7 @@ public abstract class BaseTestCell extends TestCase { assertEquals(2.5, cell.getNumericCellValue(), 0.0); } + @Test public void testChangeTypeErrorToBoolean() { Cell cell = createACell(); cell.setCellErrorValue((byte)ErrorConstants.ERROR_NAME); @@ -353,6 +369,7 @@ public abstract class BaseTestCell extends TestCase { * {@link FormulaEvaluator#evaluateInCell(Cell)} with a * string result type. */ + @Test public void testConvertStringFormulaCell() { Cell cellA1 = createACell(); cellA1.setCellFormula("\"abc\""); @@ -371,10 +388,12 @@ public abstract class BaseTestCell extends TestCase { } assertEquals("abc", cellA1.getStringCellValue()); } + /** * similar to {@link #testConvertStringFormulaCell()} but checks at a * lower level that {#link {@link Cell#setCellType(int)} works properly */ + @Test public void testSetTypeStringOnFormulaCell() { Cell cellA1 = createACell(); FormulaEvaluator fe = cellA1.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator(); @@ -418,6 +437,7 @@ public abstract class BaseTestCell extends TestCase { /** * Test for bug in convertCellValueToBoolean to make sure that formula results get converted */ + @Test public void testChangeTypeFormulaToBoolean() { Cell cell = createACell(); cell.setCellFormula("1=1"); @@ -433,6 +453,7 @@ public abstract class BaseTestCell extends TestCase { * Bug 40296: HSSFCell.setCellFormula throws * ClassCastException if cell is created using HSSFRow.createCell(short column, int type) */ + @Test public void test40296() { Workbook wb = _testDataProvider.createWorkbook(); Sheet workSheet = wb.createSheet("Sheet1"); @@ -470,6 +491,7 @@ public abstract class BaseTestCell extends TestCase { assertEquals("SUM(A1:B1)", cell.getCellFormula()); } + @Test public void testSetStringInFormulaCell_bug44606() { Workbook wb = _testDataProvider.createWorkbook(); Cell cell = wb.createSheet("Sheet1").createRow(0).createCell(0); @@ -484,7 +506,8 @@ public abstract class BaseTestCell extends TestCase { /** * Make sure that cell.setCellType(Cell.CELL_TYPE_BLANK) preserves the cell style */ - public void testSetBlank_bug47028() { + @Test + public void testSetBlank_bug47028() { Workbook wb = _testDataProvider.createWorkbook(); CellStyle style = wb.createCellStyle(); Cell cell = wb.createSheet("Sheet1").createRow(0).createCell(0); @@ -514,7 +537,8 @@ public abstract class BaseTestCell extends TestCase { *
  • * */ - public void testNanAndInfinity() { + @Test + public void testNanAndInfinity() { Workbook wb = _testDataProvider.createWorkbook(); Sheet workSheet = wb.createSheet("Sheet1"); Row row = workSheet.createRow(0); @@ -550,7 +574,8 @@ public abstract class BaseTestCell extends TestCase { assertEquals(ErrorConstants.ERROR_DIV_0, cell2.getErrorCellValue()); } - public void testDefaultStyleProperties() { + @Test + public void testDefaultStyleProperties() { Workbook wb = _testDataProvider.createWorkbook(); Cell cell = wb.createSheet("Sheet1").createRow(0).createCell(0); @@ -584,7 +609,8 @@ public abstract class BaseTestCell extends TestCase { assertFalse(style2.getHidden()); } - public void testBug55658SetNumericValue(){ + @Test + public void testBug55658SetNumericValue(){ Workbook wb = _testDataProvider.createWorkbook(); Sheet sh = wb.createSheet(); Row row = sh.createRow(0); @@ -604,7 +630,8 @@ public abstract class BaseTestCell extends TestCase { assertEquals("24", wb.getSheetAt(0).getRow(0).getCell(1).getStringCellValue()); } - public void testRemoveHyperlink(){ + @Test + public void testRemoveHyperlink(){ Workbook wb = _testDataProvider.createWorkbook(); Sheet sh = wb.createSheet("test"); Row row = sh.createRow(0); @@ -646,7 +673,8 @@ public abstract class BaseTestCell extends TestCase { * an problem that cell could not return error value form formula cell). * @throws IOException */ - public void testGetErrorCellValueFromFormulaCell() throws IOException { + @Test + public void testGetErrorCellValueFromFormulaCell() throws IOException { Workbook wb = _testDataProvider.createWorkbook(); try { Sheet sheet = wb.createSheet(); @@ -660,7 +688,8 @@ public abstract class BaseTestCell extends TestCase { } } - public void testSetRemoveStyle() throws Exception { + @Test + public void testSetRemoveStyle() throws Exception { Workbook wb = _testDataProvider.createWorkbook(); Sheet sheet = wb.createSheet(); Row row = sheet.createRow(0); @@ -699,6 +728,7 @@ public abstract class BaseTestCell extends TestCase { wb.close(); } + @Test public void test57008() throws IOException { Workbook wb = _testDataProvider.createWorkbook(); Sheet sheet = wb.createSheet(); @@ -740,6 +770,7 @@ public abstract class BaseTestCell extends TestCase { * The maximum length of cell contents (text) is 32,767 characters. * @throws IOException */ + @Test public void testMaxTextLength() throws IOException{ Workbook wb = _testDataProvider.createWorkbook(); Sheet sheet = wb.createSheet(); diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetAutosizeColumn.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetAutosizeColumn.java index b1aeb637c..997d825ed 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetAutosizeColumn.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetAutosizeColumn.java @@ -17,15 +17,20 @@ package org.apache.poi.ss.usermodel; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Calendar; +import java.util.Locale; import org.apache.poi.ss.ITestDataProvider; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.util.JvmBugs; +import org.apache.poi.util.LocaleUtil; +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; -import java.util.Calendar; - /** * Common superclass for testing automatic sizing of sheet columns * @@ -35,12 +40,25 @@ public abstract class BaseTestSheetAutosizeColumn { private final ITestDataProvider _testDataProvider; + private static Locale userLocale; + + @BeforeClass + public static void initLocale() { + userLocale = LocaleUtil.getUserLocale(); + LocaleUtil.setUserLocale(Locale.ROOT); + } + + @AfterClass + public static void resetLocale() { + LocaleUtil.setUserLocale(userLocale); + } + protected BaseTestSheetAutosizeColumn(ITestDataProvider testDataProvider) { _testDataProvider = testDataProvider; } @Test - public void numericCells(){ + public void numericCells() throws Exception { Workbook workbook = _testDataProvider.createWorkbook(); fixFonts(workbook); DataFormat df = workbook.getCreationHelper().createDataFormat(); @@ -77,10 +95,12 @@ public abstract class BaseTestSheetAutosizeColumn { assertEquals(sheet.getColumnWidth(1), sheet.getColumnWidth(2)); // columns 1, 2 and 3 should have the same width assertEquals(sheet.getColumnWidth(2), sheet.getColumnWidth(3)); // columns 1, 2 and 3 should have the same width assertEquals(sheet.getColumnWidth(4), sheet.getColumnWidth(5)); // 10.0000 and '10.0000' + + workbook.close(); } @Test - public void booleanCells(){ + public void booleanCells() throws Exception { Workbook workbook = _testDataProvider.createWorkbook(); fixFonts(workbook); Sheet sheet = workbook.createSheet(); @@ -106,10 +126,12 @@ public abstract class BaseTestSheetAutosizeColumn { assertTrue(sheet.getColumnWidth(1) > sheet.getColumnWidth(0)); // 'true' is wider than '0' assertEquals(sheet.getColumnWidth(1), sheet.getColumnWidth(2)); // columns 1, 2 and 3 should have the same width assertEquals(sheet.getColumnWidth(2), sheet.getColumnWidth(3)); // columns 1, 2 and 3 should have the same width + + workbook.close(); } @Test - public void dateCells(){ + public void dateCells() throws Exception { Workbook workbook = _testDataProvider.createWorkbook(); fixFonts(workbook); Sheet sheet = workbook.createSheet(); @@ -124,8 +146,7 @@ public abstract class BaseTestSheetAutosizeColumn { CellStyle style5 = workbook.createCellStyle(); //rotated text style5.setDataFormat(df.getFormat("mmm/dd/yyyy")); - Calendar calendar = Calendar.getInstance(); - calendar.set(2010, 0, 1); // Jan 1 2010 + Calendar calendar = LocaleUtil.getLocaleCalendar(2010, 0, 1); // Jan 1 2010 Row row = sheet.createRow(0); row.createCell(0).setCellValue(DateUtil.getJavaDate(0)); //default date @@ -172,10 +193,12 @@ public abstract class BaseTestSheetAutosizeColumn { assertTrue(sheet.getColumnWidth(5) > sheet.getColumnWidth(3)); // 'mmm/dd/yyyy' is wider than 'mmm' assertEquals(sheet.getColumnWidth(6), sheet.getColumnWidth(5)); // date formatted as 'mmm/dd/yyyy' assertEquals(sheet.getColumnWidth(4), sheet.getColumnWidth(7)); // date formula formatted as 'mmm' + + workbook.close(); } @Test - public void stringCells(){ + public void stringCells() throws Exception { Workbook workbook = _testDataProvider.createWorkbook(); fixFonts(workbook); Sheet sheet = workbook.createSheet(); @@ -205,10 +228,12 @@ public abstract class BaseTestSheetAutosizeColumn { assertEquals(sheet.getColumnWidth(4), sheet.getColumnWidth(3)); boolean ignoreFontSizeX2 = JvmBugs.hasLineBreakMeasurerBug(); assertTrue(ignoreFontSizeX2 || sheet.getColumnWidth(5) > sheet.getColumnWidth(4)); //larger font results in a wider column width + + workbook.close(); } @Test - public void rotatedText(){ + public void rotatedText() throws Exception { Workbook workbook = _testDataProvider.createWorkbook(); fixFonts(workbook); Sheet sheet = workbook.createSheet(); @@ -230,10 +255,12 @@ public abstract class BaseTestSheetAutosizeColumn { int w1 = sheet.getColumnWidth(1); assertTrue(w0*5 < w1); // rotated text occupies at least five times less horizontal space than normal text + + workbook.close(); } @Test - public void mergedCells(){ + public void mergedCells() throws Exception { Workbook workbook = _testDataProvider.createWorkbook(); fixFonts(workbook); Sheet sheet = workbook.createSheet(); @@ -251,6 +278,8 @@ public abstract class BaseTestSheetAutosizeColumn { sheet.autoSizeColumn(0, true); assertTrue(sheet.getColumnWidth(0) > defaulWidth); + + workbook.close(); } @@ -293,6 +322,8 @@ public abstract class BaseTestSheetAutosizeColumn { Row r60708 = sheet.createRow(60708); r60708.createCell(0).setCellValue("Near the end"); sheet.autoSizeColumn(0); + + workbook.close(); } // TODO should we have this stuff in the FormulaEvaluator? diff --git a/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java b/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java index 08f21a590..1251f1e8b 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java +++ b/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java @@ -21,16 +21,22 @@ package org.apache.poi.ss.usermodel; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import java.io.IOException; import java.text.DateFormat; import java.util.Calendar; import java.util.Date; import java.util.Locale; -import junit.framework.TestCase; - import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.TestHSSFDataFormatter; +import org.apache.poi.util.LocaleUtil; +import org.junit.Ignore; +import org.junit.Test; /** * Tests of {@link DataFormatter} @@ -38,13 +44,14 @@ import org.apache.poi.hssf.usermodel.TestHSSFDataFormatter; * See {@link TestHSSFDataFormatter} too for * more tests. */ -public class TestDataFormatter extends TestCase { +public class TestDataFormatter { private static final double _15_MINUTES = 0.041666667; /** * Test that we use the specified locale when deciding * how to format normal numbers */ + @Test public void testLocale() { DataFormatter dfUS = new DataFormatter(Locale.US); DataFormatter dfFR = new DataFormatter(Locale.FRENCH); @@ -61,6 +68,7 @@ public class TestDataFormatter extends TestCase { * a specific locale, but we should format things as if * the locale (eg '[$-1010409]') isn't there */ + @Test public void testLocaleBasedFormats() { DataFormatter dfUS = new DataFormatter(Locale.US); @@ -78,6 +86,7 @@ public class TestDataFormatter extends TestCase { * Ensure that colours get correctly * zapped from within the format strings */ + @Test public void testColours() { DataFormatter dfUS = new DataFormatter(Locale.US); @@ -105,6 +114,7 @@ public class TestDataFormatter extends TestCase { assertEquals("[ab]12.34[x]", dfUS.formatRawCellContents(12.343, -1, "[ab]##.##[x]")); } + @Test public void testColoursAndBrackets() { DataFormatter dfUS = new DataFormatter(Locale.US); @@ -149,6 +159,7 @@ public class TestDataFormatter extends TestCase { * and Excel differ, and workarounds are not * yet in place for all of these */ + @Test public void testNegativeZero() { DataFormatter dfUS = new DataFormatter(Locale.US); @@ -193,6 +204,7 @@ public class TestDataFormatter extends TestCase { * Test that we correctly handle fractions in the * format string, eg # #/# */ + @Test public void testFractions() { DataFormatter dfUS = new DataFormatter(Locale.US); @@ -262,6 +274,7 @@ public class TestDataFormatter extends TestCase { * and *x (fill to the column width with "x"s) are * correctly ignored by us. */ + @Test public void testPaddingSpaces() { DataFormatter dfUS = new DataFormatter(Locale.US); assertEquals("12.34", dfUS.formatRawCellContents(12.343, -1, "##.##_ ")); @@ -278,6 +291,7 @@ public class TestDataFormatter extends TestCase { /** * DataFormatter is the CSV mode preserves spaces */ + @Test public void testPaddingSpacesCSV() { DataFormatter dfUS = new DataFormatter(Locale.US, true); assertEquals("12.34 ", dfUS.formatRawCellContents(12.343, -1, "##.##_ ")); @@ -311,12 +325,11 @@ public class TestDataFormatter extends TestCase { * Test that the special Excel month format MMMMM * gets turned into the first letter of the month */ + @Test public void testMMMMM() { DataFormatter dfUS = new DataFormatter(Locale.US); - Calendar c = Calendar.getInstance(); - c.set(Calendar.MILLISECOND, 0); - c.set(2010, 5, 1, 2, 0, 0); + Calendar c = LocaleUtil.getLocaleCalendar(2010, 5, 1, 2, 0, 0); assertEquals("2010-J-1 2:00:00", dfUS.formatRawCellContents( DateUtil.getExcelDate(c, false), -1, "YYYY-MMMMM-D h:mm:ss" @@ -326,6 +339,7 @@ public class TestDataFormatter extends TestCase { /** * Tests that we do AM/PM handling properly */ + @Test public void testAMPM() { DataFormatter dfUS = new DataFormatter(Locale.US); @@ -343,6 +357,7 @@ public class TestDataFormatter extends TestCase { * Test that we can handle elapsed time, * eg formatting 1 day 4 hours as 28 hours */ + @Test public void testElapsedTime() { DataFormatter dfUS = new DataFormatter(Locale.US); @@ -447,6 +462,7 @@ public class TestDataFormatter extends TestCase { } } + @Test public void testDateWindowing() { DataFormatter dfUS = new DataFormatter(Locale.US); @@ -455,6 +471,7 @@ public class TestDataFormatter extends TestCase { assertEquals("1904-01-01 00:00:00", dfUS.formatRawCellContents(0.0, -1, "yyyy-mm-dd hh:mm:ss", true)); } + @Test public void testScientificNotation() { DataFormatter dfUS = new DataFormatter(Locale.US); @@ -463,6 +480,7 @@ public class TestDataFormatter extends TestCase { assertEquals("0.00E+00", dfUS.formatRawCellContents(0.0, -1, "0.00E+00")); } + @Test public void testInvalidDate() { DataFormatter df1 = new DataFormatter(Locale.US); assertEquals("-1.0", df1.formatRawCellContents(-1, -1, "mm/dd/yyyy")); @@ -472,6 +490,7 @@ public class TestDataFormatter extends TestCase { df2.formatRawCellContents(-1, -1, "mm/dd/yyyy")); } + @Test public void testEscapes() { DataFormatter dfUS = new DataFormatter(Locale.US); @@ -485,6 +504,7 @@ public class TestDataFormatter extends TestCase { assertEquals("1901/01/01", dfUS.formatRawCellContents(367.0, -1, "yyyy\\/mm\\/dd")); } + @Test public void testOther() { DataFormatter dfUS = new DataFormatter(Locale.US, true); @@ -494,6 +514,7 @@ public class TestDataFormatter extends TestCase { assertEquals(" $- ", dfUS.formatRawCellContents(0.0, -1, "_-$* #,##0.00_-;-$* #,##0.00_-;_-$* \"-\"??_-;_-@_-")); } + @Test public void testErrors() throws IOException { DataFormatter dfUS = new DataFormatter(Locale.US, true); @@ -519,6 +540,7 @@ public class TestDataFormatter extends TestCase { * the start of a format string to format it differently, we * should at least handle it as it if wasn't there */ + @Test public void testDatesWithLocales() { DataFormatter dfUS = new DataFormatter(Locale.US, true); @@ -543,7 +565,9 @@ public class TestDataFormatter extends TestCase { /** * TODO Fix these so that they work */ - public void DISABLEDtestCustomFormats() { + @Test + @Ignore + public void testCustomFormats() { DataFormatter dfUS = new DataFormatter(Locale.US, true); String fmt; @@ -560,6 +584,7 @@ public class TestDataFormatter extends TestCase { /** * ExcelStyleDateFormatter should work for Milliseconds too */ + @Test public void testExcelStyleDateFormatterStringOnMillis() { // Test directly with the .000 style DateFormat formatter1 = new ExcelStyleDateFormatter("ss.000"); @@ -589,7 +614,8 @@ public class TestDataFormatter extends TestCase { assertEquals("01.010", dfUS.formatRawCellContents(0.0000116898, -1, "ss.000")); } - public void testBug54786() { + @Test + public void testBug54786() { DataFormatter formatter = new DataFormatter(); String format = "[h]\"\"h\"\" m\"\"m\"\""; assertTrue(DateUtil.isADateFormat(-1,format)); @@ -613,7 +639,8 @@ public class TestDataFormatter extends TestCase { } } - public void testIsADateFormat() { + @Test + public void testIsADateFormat() { // first check some cases that should not be a date, also call multiple times to ensure the cache is used assertFalse(DateUtil.isADateFormat(-1, null)); assertFalse(DateUtil.isADateFormat(-1, null)); diff --git a/src/testcases/org/apache/poi/ss/usermodel/TestDateUtil.java b/src/testcases/org/apache/poi/ss/usermodel/TestDateUtil.java index 870cd9cb3..3f0ef4b7c 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/TestDateUtil.java +++ b/src/testcases/org/apache/poi/ss/usermodel/TestDateUtil.java @@ -23,6 +23,7 @@ import java.util.Calendar; import java.util.Date; import java.util.TimeZone; +import org.apache.poi.util.LocaleUtil; import org.junit.Test; public class TestDateUtil { @@ -30,7 +31,7 @@ public class TestDateUtil { @Test public void getJavaDate_InvalidValue() { double dateValue = -1; - TimeZone tz = TimeZone.getDefault(); + TimeZone tz = LocaleUtil.getUserTimeZone(); boolean use1904windowing = false; boolean roundSeconds = false; @@ -44,13 +45,11 @@ public class TestDateUtil { @Test public void getJavaDate_ValidValue() { double dateValue = 0; - TimeZone tz = TimeZone.getDefault(); + TimeZone tz = LocaleUtil.getUserTimeZone(); boolean use1904windowing = false; boolean roundSeconds = false; - Calendar calendar = Calendar.getInstance(tz); - calendar.set(1900, 0, 0, 0, 0, 0); - calendar.set(Calendar.MILLISECOND, 0); + Calendar calendar = LocaleUtil.getLocaleCalendar(1900, 0, 0); Date date = calendar.getTime(); assertEquals(date, DateUtil.getJavaDate(dateValue)); @@ -63,7 +62,7 @@ public class TestDateUtil { @Test public void getJavaCalendar_InvalidValue() { double dateValue = -1; - TimeZone tz = TimeZone.getDefault(); + TimeZone tz = LocaleUtil.getUserTimeZone(); boolean use1904windowing = false; boolean roundSeconds = false; @@ -76,17 +75,21 @@ public class TestDateUtil { @Test public void getJavaCalendar_ValidValue() { double dateValue = 0; - TimeZone tz = TimeZone.getDefault(); + TimeZone tz = LocaleUtil.getUserTimeZone(); boolean use1904windowing = false; boolean roundSeconds = false; - Calendar calendar = Calendar.getInstance(tz); - calendar.set(1900, 0, 0, 0, 0, 0); - calendar.set(Calendar.MILLISECOND, 0); + Calendar expCal = LocaleUtil.getLocaleCalendar(1900, 0, 0); - assertEquals(calendar, DateUtil.getJavaCalendar(dateValue)); - assertEquals(calendar, DateUtil.getJavaCalendar(dateValue, use1904windowing)); - assertEquals(calendar, DateUtil.getJavaCalendar(dateValue, use1904windowing, tz)); - assertEquals(calendar, DateUtil.getJavaCalendar(dateValue, use1904windowing, tz, roundSeconds)); + Calendar actCal[] = { + DateUtil.getJavaCalendar(dateValue), + DateUtil.getJavaCalendar(dateValue, use1904windowing), + DateUtil.getJavaCalendar(dateValue, use1904windowing, tz), + DateUtil.getJavaCalendar(dateValue, use1904windowing, tz, roundSeconds) + }; + assertEquals(expCal, actCal[0]); + assertEquals(expCal, actCal[1]); + assertEquals(expCal, actCal[2]); + assertEquals(expCal, actCal[3]); } } diff --git a/src/testcases/org/apache/poi/ss/util/TestDateFormatConverter.java b/src/testcases/org/apache/poi/ss/util/TestDateFormatConverter.java index 418070f16..2b6e6e312 100644 --- a/src/testcases/org/apache/poi/ss/util/TestDateFormatConverter.java +++ b/src/testcases/org/apache/poi/ss/util/TestDateFormatConverter.java @@ -69,7 +69,7 @@ public final class TestDateFormatConverter extends TestCase { Row row = sheet.createRow(rowNum++); row.createCell(0).setCellValue(locale.toString()); - row.createCell(1).setCellValue(locale.getDisplayName()); + row.createCell(1).setCellValue(locale.getDisplayName(Locale.ROOT)); DateFormat dateFormat; if( dates ) { diff --git a/src/testcases/org/apache/poi/util/TestHexDump.java b/src/testcases/org/apache/poi/util/TestHexDump.java index 11cd4cb9a..f6e149e75 100644 --- a/src/testcases/org/apache/poi/util/TestHexDump.java +++ b/src/testcases/org/apache/poi/util/TestHexDump.java @@ -134,7 +134,7 @@ public final class TestHexDump { obj[17] = chrs.toString(); format.append("%18$s"+HexDump.EOL); - String str = String.format(format.toString(), obj); + String str = String.format(LocaleUtil.getUserLocale(), format.toString(), obj); strExp.append(str); } byte bytesExp[] = strExp.toString().getBytes(HexDump.UTF8); diff --git a/src/testcases/org/apache/poi/util/TestStringUtil.java b/src/testcases/org/apache/poi/util/TestStringUtil.java index 04c03d93e..fcef5bd17 100644 --- a/src/testcases/org/apache/poi/util/TestStringUtil.java +++ b/src/testcases/org/apache/poi/util/TestStringUtil.java @@ -144,7 +144,7 @@ public final class TestStringUtil extends TestCase { } private static String fmt(double num, int minIntDigits, int maxFracDigitis) { - NumberFormat nf = NumberFormat.getInstance(); + NumberFormat nf = NumberFormat.getInstance(LocaleUtil.getUserLocale()); if (minIntDigits != -1) { nf.setMinimumIntegerDigits(minIntDigits);