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);