Merged revisions 638786-638802,638805-638811,638813-638814,638816-639230,639233-639241,639243-639253,639255-639486,639488-639601,639603-639835,639837-639917,639919-640056,640058-640710,640712-641156,641158-641184,641186-641795,641797-641798,641800-641933,641935-641963,641965-641966,641968-641995,641997-642230,642232-642562,642564-642565,642568-642570,642572-642573,642576-642736,642739-642877,642879,642881-642890,642892-642903,642905-642945,642947-643624,643626-643653,643655-643669,643671,643673-643830,643832-643833,643835-644342,644344-644472,644474-644508,644510-645347,645349-645351,645353-645559,645561-645565,645568-645951,645953-646193,646195-646311,646313-646404,646406-646665,646667-646853,646855-646869,646871-647151,647153-647185,647187-647277,647279-647566,647568-647573,647575,647578-647711,647714-647737,647739-647823,647825-648155,648157-648202,648204-648273,648275,648277-648302,648304-648333,648335-648588,648590-648622,648625-648673,648675-649141,649144,649146-649556,649558-649795,649799,649801-649910,649912-649913,649915-650128,650131-650132,650134-650137,650140-650914,650916-651991,651993-652284,652286-652287,652289,652291,652293-652297,652299-652328,652330-652425,652427-652445,652447-652560,652562-652933,652935,652937-652993,652995-653116,653118-653124,653126-653483,653487-653519,653522-653550,653552-653607,653609-653667,653669-653674,653676-653814,653817-653830,653832-653891,653893-653944,653946-654055,654057-654355,654357-654365,654367-654648,654651-655215,655217-655277,655279-655281,655283-655911,655913-656212,656214,656216-656251,656253-656698,656700-656756,656758-656892,656894-657135,657137-657165,657168-657179,657181-657354,657356-657357,657359-657701,657703-657874,657876-658032,658034-658284,658286,658288-658301,658303-658307,658309-658321,658323-658335,658337-658348,658351,658353-658832,658834-658983,658985,658987-659066,659068-659402,659404-659428,659430-659451,659453-659454,659456-659461,659463-659477,659479-659524,659526-659571,659574,659576-660255,660257-660262,660264-660279,660281-660343,660345-660473,660475-660827,660829-660833,660835-660888,660890-663321,663323-663435,663437-663764,663766-663854,663856-664219,664221-664489,664494-664514,664516-668013,668015-668142,668144-668152,668154,668156-668256,668258,668260-669139,669141-669455,669457-669657,669659-669808,669810-670189,670191-671321,671323-672229,672231-672549,672551-672552,672554-672561,672563-672566,672568,672571-673049,673051-673852,673854-673862,673864-673986,673988-673996,673998-674347,674349-674890,674892-674910,674912-674936,674938-674952,674954-675078,675080-675085,675087-675217,675219-675660,675662-675670,675672-675716,675718-675726,675728-675733,675735-675775,675777-675782,675784,675786-675791,675794-675852,675854-676200,676202,676204,676206-676220,676222-676309,676311-676456,676458-676994,676996-677027,677030-677040,677042-677056,677058-677375,677377-677968,677970-677971,677973,677975-677994,677996-678286,678288-680505 via svnmerge from

https://svn.apache.org:443/repos/asf/poi/trunk

........
  r678539 | nick | 2008-07-21 20:35:47 +0100 (Mon, 21 Jul 2008) | 1 line
  
  Fix bug #45437 - Detect encrypted word documents, and throw an EncryptedDocumentException instead of a OOM
........
  r680394 | nick | 2008-07-28 17:41:47 +0100 (Mon, 28 Jul 2008) | 1 line
  
  Fix for DataFormatter on some JVMs
........
  r680470 | josh | 2008-07-28 21:08:15 +0100 (Mon, 28 Jul 2008) | 1 line
  
  More tweaks for bug 45404.  Fixes for JDK 1.4, improved member scoping and formatting.
........


git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@680509 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2008-07-28 21:27:16 +00:00
parent ea48f23d55
commit 5d95d3f082
10 changed files with 564 additions and 543 deletions

View File

@ -51,6 +51,7 @@
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
</release>
<release version="3.1.1-alpha1" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="fix">45437 - Detect encrypted word documents, and throw an EncryptedDocumentException instead of a OOM</action>
<action dev="POI-DEVELOPERS" type="add">45404 - New class, hssf.usermodel.HSSFDataFormatter, for formatting numbers and dates in the same way that Excel does</action>
<action dev="POI-DEVELOPERS" type="fix">45414 - Don't add too many UncalcedRecords to sheets with charts in them</action>
<action dev="POI-DEVELOPERS" type="fix">45398 - Support detecting date formats containing "am/pm" as date times</action>

View File

@ -48,6 +48,7 @@
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
</release>
<release version="3.1.1-alpha1" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="fix">45437 - Detect encrypted word documents, and throw an EncryptedDocumentException instead of a OOM</action>
<action dev="POI-DEVELOPERS" type="add">45404 - New class, hssf.usermodel.HSSFDataFormatter, for formatting numbers and dates in the same way that Excel does</action>
<action dev="POI-DEVELOPERS" type="fix">45414 - Don't add too many UncalcedRecords to sheets with charts in them</action>
<action dev="POI-DEVELOPERS" type="fix">45398 - Support detecting date formats containing "am/pm" as date times</action>

View File

@ -0,0 +1,24 @@
/* ====================================================================
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;
public class EncryptedDocumentException extends IllegalStateException
{
public EncryptedDocumentException(String s) {
super(s);
}
}

View File

@ -73,69 +73,55 @@ import java.util.regex.Pattern;
* @author James May (james dot may at fmr dot com)
*
*/
public class HSSFDataFormatter {
public final class HSSFDataFormatter {
/** Pattern to find a number format: "0" or "#" */
protected Pattern numPattern;
private static final Pattern numPattern = Pattern.compile("[0#]+");
/** Pattern to find days of week as text "ddd...." */
protected Pattern daysAsText;
private static final Pattern daysAsText = Pattern.compile("([d]{3,})", Pattern.CASE_INSENSITIVE);
/** Pattern to find "AM/PM" marker */
protected Pattern amPmPattern;
private static final Pattern amPmPattern = Pattern.compile("((A|P)[M/P]*)", Pattern.CASE_INSENSITIVE);
/** A regex to find patterns like [$$-1009] and [$<24>-452]. */
protected Pattern specialPatternGroup;
private static final Pattern specialPatternGroup = Pattern.compile("(\\[\\$[^-\\]]*-[0-9A-Z]+\\])");
/** <em>General</em> format for whole numbers. */
protected Format generalWholeNumFormat;
private static final Format generalWholeNumFormat = new DecimalFormat("#");
/** <em>General</em> format for decimal numbers. */
protected Format generalDecimalNumFormat;
private static final Format generalDecimalNumFormat = new DecimalFormat("#.##########");
/** A default format to use when a number pattern cannot be parsed. */
protected Format defaultNumFormat;
private Format defaultNumFormat;
/**
* A map to cache formats.
* Map<String,Format> formats
*/
protected Map formats;
private final Map formats;
/**
* Constructor
*/
public HSSFDataFormatter() {
numPattern = Pattern.compile("[0#]+");
daysAsText = Pattern.compile("([d]{3,})", Pattern.CASE_INSENSITIVE);
amPmPattern = Pattern.compile("((A|P)[M/P]*)", Pattern.CASE_INSENSITIVE);
specialPatternGroup = Pattern.compile("(\\[\\$[^-\\]]*-[0-9A-Z]+\\])");
generalWholeNumFormat = new DecimalFormat("#");
generalDecimalNumFormat = new DecimalFormat("#.##########");
formats = new HashMap();
// init built-in formats
init();
}
/**
* Initialize the formatter. Called after construction.
*/
protected void init() {
ZipPlusFourFormat zipFormat = new ZipPlusFourFormat();
Format zipFormat = ZipPlusFourFormat.instance;
addFormat("00000\\-0000", zipFormat);
addFormat("00000-0000", zipFormat);
PhoneFormat phoneFormat = new PhoneFormat();
Format phoneFormat = PhoneFormat.instance;
// allow for format string variations
addFormat("[<=9999999]###\\-####;\\(###\\)\\ ###\\-####", phoneFormat);
addFormat("[<=9999999]###-####;(###) ###-####", phoneFormat);
addFormat("###\\-####;\\(###\\)\\ ###\\-####", phoneFormat);
addFormat("###-####;(###) ###-####", phoneFormat);
SSNFormat ssnFormat = new SSNFormat();
Format ssnFormat = SSNFormat.instance;
addFormat("000\\-00\\-0000", ssnFormat);
addFormat("000-00-0000", ssnFormat);
}
@ -153,7 +139,7 @@ public class HSSFDataFormatter {
* @param cell The cell to retrieve a Format for
* @return A Format for the format String
*/
protected Format getFormat(HSSFCell cell) {
private Format getFormat(HSSFCell cell) {
if ( cell.getCellStyle() == null) {
return null;
}
@ -170,18 +156,17 @@ public class HSSFDataFormatter {
Format format = (Format)formats.get(formatStr);
if (format != null) {
return format;
} else if (formatStr.equals("General")) {
}
if (formatStr.equals("General")) {
if (HSSFDataFormatter.isWholeNumber(cellValue)) {
return generalWholeNumFormat;
} else {
}
return generalDecimalNumFormat;
}
} else {
format = createFormat(cellValue, formatIndex, formatStr);
formats.put(formatStr, format);
return format;
}
}
/**
* Create and return a Format based on the format string from a cell's
@ -190,8 +175,7 @@ public class HSSFDataFormatter {
* @param cell The Excel cell
* @return A Format representing the excel format. May return null.
*/
protected Format createFormat(HSSFCell cell) {
String sFormat = cell.getCellStyle().getDataFormatString();
public Format createFormat(HSSFCell cell) {
int formatIndex = cell.getCellStyle().getDataFormat();
String formatStr = cell.getCellStyle().getDataFormatString();
@ -204,7 +188,6 @@ public class HSSFDataFormatter {
// try to extract special characters like currency
Matcher m = specialPatternGroup.matcher(formatStr);
try {
while(m.find()) {
String match = m.group();
String symbol = match.substring(match.indexOf('$') + 1, match.indexOf('-'));
@ -216,20 +199,27 @@ public class HSSFDataFormatter {
symbol = sb.toString();
}
formatStr = m.replaceAll(symbol);
}
} catch (Exception e) {
return getDefaultFormat(cellValue);
m = specialPatternGroup.matcher(formatStr);
}
if(formatStr == null || formatStr.trim().length() == 0) {
return getDefaultFormat(cellValue);
}
Format returnVal = null;
StringBuffer sb = null;
if(HSSFDateUtil.isADateFormat(formatIndex,formatStr) &&
HSSFDateUtil.isValidExcelDate(cellValue)) {
return createDateFormat(formatStr, cellValue);
}
if (numPattern.matcher(formatStr).find()) {
return createNumberFormat(formatStr, cellValue);
}
// TODO - when does this occur?
return null;
}
private Format createDateFormat(String pFormatStr, double cellValue) {
String formatStr = pFormatStr;
formatStr = formatStr.replaceAll("\\\\-","-");
formatStr = formatStr.replaceAll("\\\\,",",");
formatStr = formatStr.replaceAll("\\\\ "," ");
@ -237,9 +227,12 @@ public class HSSFDataFormatter {
boolean hasAmPm = false;
Matcher amPmMatcher = amPmPattern.matcher(formatStr);
while (amPmMatcher.find()) {
formatStr = amPmMatcher.replaceAll("a");
formatStr = amPmMatcher.replaceAll("@");
hasAmPm = true;
amPmMatcher = amPmPattern.matcher(formatStr);
}
formatStr = formatStr.replaceAll("@", "a");
Matcher dateMatcher = daysAsText.matcher(formatStr);
if (dateMatcher.find()) {
@ -256,7 +249,7 @@ public class HSSFDataFormatter {
Excel displays the month instead of minutes."
*/
sb = new StringBuffer();
StringBuffer sb = new StringBuffer();
char[] chars = formatStr.toCharArray();
boolean mIsMonth = true;
List ms = new ArrayList();
@ -312,7 +305,7 @@ public class HSSFDataFormatter {
formatStr = sb.toString();
try {
returnVal = new SimpleDateFormat(formatStr);
return new SimpleDateFormat(formatStr);
} catch(IllegalArgumentException iae) {
// the pattern could not be parsed correctly,
@ -320,8 +313,10 @@ public class HSSFDataFormatter {
return getDefaultFormat(cellValue);
}
} else if (numPattern.matcher(formatStr).find()) {
sb = new StringBuffer(formatStr);
}
private Format createNumberFormat(String formatStr, double cellValue) {
StringBuffer sb = new StringBuffer(formatStr);
for (int i = 0; i < sb.length(); i++) {
char c = sb.charAt(i);
//handle (#,##0_);
@ -348,9 +343,9 @@ public class HSSFDataFormatter {
i--;
}
}
formatStr = sb.toString();
try {
returnVal = new DecimalFormat(formatStr);
return new DecimalFormat(sb.toString());
} catch(IllegalArgumentException iae) {
// the pattern could not be parsed correctly,
@ -358,13 +353,11 @@ public class HSSFDataFormatter {
return getDefaultFormat(cellValue);
}
}
return returnVal;
}
/**
* Return true if the double value represents a whole number
* @param d the double value to check
* @return true if d is a whole number
* @return <code>true</code> if d is a whole number
*/
private static boolean isWholeNumber(double d) {
return d == Math.floor(d);
@ -375,7 +368,7 @@ public class HSSFDataFormatter {
* @param cell The cell
* @return a default format
*/
protected Format getDefaultFormat(HSSFCell cell) {
public Format getDefaultFormat(HSSFCell cell) {
return getDefaultFormat(cell.getNumericCellValue());
}
private Format getDefaultFormat(double cellValue) {
@ -384,11 +377,11 @@ public class HSSFDataFormatter {
return defaultNumFormat;
// otherwise use general format
} else if (isWholeNumber(cellValue)){
return generalWholeNumFormat;
} else {
return generalDecimalNumFormat;
}
if (isWholeNumber(cellValue)){
return generalWholeNumFormat;
}
return generalDecimalNumFormat;
}
/**
@ -399,14 +392,13 @@ public class HSSFDataFormatter {
* @param cell The cell
* @return a formatted date string
*/
protected String getFormattedDateString(HSSFCell cell) {
private String getFormattedDateString(HSSFCell cell) {
Format dateFormat = getFormat(cell);
Date d = cell.getDateCellValue();
if (dateFormat != null) {
return dateFormat.format(d);
} else {
return d.toString();
}
return d.toString();
}
/**
@ -418,15 +410,14 @@ public class HSSFDataFormatter {
* @param cell The cell
* @return a formatted number string
*/
protected String getFormattedNumberString(HSSFCell cell) {
private String getFormattedNumberString(HSSFCell cell) {
Format numberFormat = getFormat(cell);
double d = cell.getNumericCellValue();
if (numberFormat != null) {
return numberFormat.format(new Double(d));
} else {
if (numberFormat == null) {
return String.valueOf(d);
}
return numberFormat.format(new Double(d));
}
/**
@ -441,20 +432,17 @@ public class HSSFDataFormatter {
Format dateFormat = getFormat(value, formatIndex, formatString);
Date d = HSSFDateUtil.getJavaDate(value);
if (dateFormat != null) {
return dateFormat.format(d);
} else {
if (dateFormat == null) {
return d.toString();
}
} else {
// Number
return dateFormat.format(d);
}
// else Number
Format numberFormat = getFormat(value, formatIndex, formatString);
if (numberFormat != null) {
return numberFormat.format(new Double(value));
} else {
if (numberFormat == null) {
return String.valueOf(value);
}
}
return numberFormat.format(new Double(value));
}
/**
@ -484,58 +472,51 @@ public class HSSFDataFormatter {
* String (""). Formula cells will be evaluated using the given
* {@link HSSFFormulaEvaluator} if the evaluator is non-null. If the
* evaluator is null, then the formula String will be returned. The caller
* is responsible for setting the currentRow on the evaluator, otherwise an
* IllegalArgumentException may be thrown.
* is responsible for setting the currentRow on the evaluator
*</p>
*
* @param cell The cell
* @param cell The cell (can be null)
* @param evaluator The HSSFFormulaEvaluator (can be null)
* @return a string value of the cell
* @throws IllegalArgumentException if cell type is <code>
* HSSFCell.CELL_TYPE_FORMULA</code> <b>and</b> evaluator is not null
* <b>and</b> the evlaluator's currentRow has not been set.
*/
public String formatCellValue(HSSFCell cell,
HSSFFormulaEvaluator evaluator) throws IllegalArgumentException {
String value = "";
if (cell == null) {
return value;
return "";
}
int cellType = cell.getCellType();
if (evaluator != null && cellType == HSSFCell.CELL_TYPE_FORMULA) {
try {
cellType = evaluator.evaluateFormulaCell(cell);
} catch (Throwable t) {
throw new IllegalArgumentException("Did you forget to set the current" +
" row on the HSSFFormulaEvaluator?", t);
} catch (RuntimeException e) {
throw new RuntimeException("Did you forget to set the current" +
" row on the HSSFFormulaEvaluator?", e);
}
}
switch (cellType)
{
case HSSFCell.CELL_TYPE_FORMULA :
// should only occur if evaluator is null
value = cell.getCellFormula();
break;
return cell.getCellFormula();
case HSSFCell.CELL_TYPE_NUMERIC :
if (HSSFDateUtil.isCellDateFormatted(cell)) {
value = getFormattedDateString(cell);
} else {
value = getFormattedNumberString(cell);
return getFormattedDateString(cell);
}
break;
return getFormattedNumberString(cell);
case HSSFCell.CELL_TYPE_STRING :
value = cell.getRichStringCellValue().getString();
break;
return cell.getRichStringCellValue().getString();
case HSSFCell.CELL_TYPE_BOOLEAN :
value = String.valueOf(cell.getBooleanCellValue());
return String.valueOf(cell.getBooleanCellValue());
case HSSFCell.CELL_TYPE_BLANK :
return "";
}
return value;
throw new RuntimeException("Unexpected celltype (" + cellType + ")");
}
@ -585,23 +566,29 @@ public class HSSFDataFormatter {
// Some custom formats
/**
* @return a <tt>DecimalFormat</tt> with parseIntegerOnly set <code>true</code>
*/
/* package */ static DecimalFormat createIntegerOnlyFormat(String fmt) {
DecimalFormat result = new DecimalFormat(fmt);
result.setParseIntegerOnly(true);
return result;
}
/**
* Format class for Excel's SSN format. This class mimics Excel's built-in
* SSN formatting.
*
* @author James May
*/
static class SSNFormat extends Format {
private DecimalFormat df;
/** Constructor */
public SSNFormat() {
df = new DecimalFormat("000000000");
df.setParseIntegerOnly(true);
private static final class SSNFormat extends Format {
public static final Format instance = new SSNFormat();
private static final DecimalFormat df = createIntegerOnlyFormat("000000000");
private SSNFormat() {
// enforce singleton
}
/** Format a number as an SSN */
public String format(Number num) {
public static String format(Number num) {
String result = df.format(num);
StringBuffer sb = new StringBuffer();
sb.append(result.substring(0, 3)).append('-');
@ -610,8 +597,7 @@ public class HSSFDataFormatter {
return sb.toString();
}
public StringBuffer format(Object obj, StringBuffer toAppendTo,
FieldPosition pos) {
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
return toAppendTo.append(format((Number)obj));
}
@ -625,17 +611,15 @@ public class HSSFDataFormatter {
* built-in formatting for Zip + 4.
* @author James May
*/
static class ZipPlusFourFormat extends Format {
private DecimalFormat df;
/** Constructor */
public ZipPlusFourFormat() {
df = new DecimalFormat("000000000");
df.setParseIntegerOnly(true);
private static final class ZipPlusFourFormat extends Format {
public static final Format instance = new ZipPlusFourFormat();
private static final DecimalFormat df = createIntegerOnlyFormat("000000000");
private ZipPlusFourFormat() {
// enforce singleton
}
/** Format a number as Zip + 4 */
public String format(Number num) {
public static String format(Number num) {
String result = df.format(num);
StringBuffer sb = new StringBuffer();
sb.append(result.substring(0, 5)).append('-');
@ -643,8 +627,7 @@ public class HSSFDataFormatter {
return sb.toString();
}
public StringBuffer format(Object obj, StringBuffer toAppendTo,
FieldPosition pos) {
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
return toAppendTo.append(format((Number)obj));
}
@ -658,17 +641,15 @@ public class HSSFDataFormatter {
* built-in phone number formatting.
* @author James May
*/
static class PhoneFormat extends Format {
private DecimalFormat df;
/** Constructor */
public PhoneFormat() {
df = new DecimalFormat("##########");
df.setParseIntegerOnly(true);
private static final class PhoneFormat extends Format {
public static final Format instance = new PhoneFormat();
private static final DecimalFormat df = createIntegerOnlyFormat("##########");
private PhoneFormat() {
// enforce singleton
}
/** Format a number as a phone number */
public String format(Number num) {
public static String format(Number num) {
String result = df.format(num);
StringBuffer sb = new StringBuffer();
String seg1, seg2, seg3;
@ -691,8 +672,7 @@ public class HSSFDataFormatter {
return sb.toString();
}
public StringBuffer format(Object obj, StringBuffer toAppendTo,
FieldPosition pos) {
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
return toAppendTo.append(format((Number)obj));
}

View File

@ -1,4 +1,3 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
@ -15,19 +14,15 @@
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.hslf.exceptions;
import org.apache.poi.EncryptedDocumentException;
/**
* This exception is thrown when we try to open a PowerPoint file, and
* discover that it is encrypted
*
* @author Nick Burch
*/
public class EncryptedPowerPointFileException extends IllegalStateException
public class EncryptedPowerPointFileException extends EncryptedDocumentException
{
public EncryptedPowerPointFileException(String s) {
super(s);

View File

@ -28,6 +28,7 @@ import java.io.ByteArrayInputStream;
import java.util.Iterator;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.POIDocument;
import org.apache.poi.poifs.filesystem.DirectoryNode;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
@ -174,9 +175,13 @@ public class HWPFDocument extends POIDocument
directory.createDocumentInputStream("WordDocument").read(_mainStream);
// use the fib to determine the name of the table stream.
// Create our FIB, and check for the doc being encrypted
_fib = new FileInformationBlock(_mainStream);
if(_fib.isFEncrypted()) {
throw new EncryptedDocumentException("Cannot process encrypted word files!");
}
// use the fib to determine the name of the table stream.
String name = "0Table";
if (_fib.isFWhichTblStm())
{

View File

@ -22,6 +22,7 @@ import java.io.FileOutputStream;
import junit.framework.TestCase;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.model.StyleSheet;
@ -138,4 +139,18 @@ public class TestProblems extends TestCase {
assertEquals(newLength, totalLength - deletedLength);
}
/**
* With an encrypted file, we should give a suitable
* exception, and not OOM
*/
public void testEncryptedFile() throws Exception {
try {
new HWPFDocument(new FileInputStream(
new File(dirname, "PasswordProtected.doc")));
fail();
} catch(EncryptedDocumentException e) {
// Good
}
}
}

View File

@ -44,6 +44,7 @@ public class AllUserModelTests {
result.addTestSuite(TestHSSFClientAnchor.class);
result.addTestSuite(TestHSSFComment.class);
result.addTestSuite(TestHSSFConditionalFormatting.class);
result.addTestSuite(TestHSSFDataFormatter.class);
result.addTestSuite(TestHSSFDateUtil.class);
result.addTestSuite(TestHSSFHeaderFooter.class);
result.addTestSuite(TestHSSFHyperlink.class);

View File

@ -29,10 +29,10 @@ import junit.framework.TestCase;
* @author James May (james dot may at fmr dot com)
*
*/
public class TestHSSFDataFormatter extends TestCase {
public final class TestHSSFDataFormatter extends TestCase {
HSSFDataFormatter formatter;
HSSFWorkbook wb;
private final HSSFDataFormatter formatter;
private final HSSFWorkbook wb;
public TestHSSFDataFormatter() {
// create the formatter to test
@ -44,13 +44,13 @@ public class TestHSSFDataFormatter extends TestCase {
HSSFDataFormat format = wb.createDataFormat();
// create a row and put some cells in it
HSSFRow row = sheet.createRow((short)0);
HSSFRow row = sheet.createRow(0);
// date value for July 8 1901 1:19 PM
double dateNum = 555.555;
//valid date formats -- all should have "Jul" in output
String[] goodDatePatterns = new String[] {
String[] goodDatePatterns ={
"[$-F800]dddd\\,\\ mmmm\\ dd\\,\\ yyyy",
"mmm/d/yy\\ h:mm PM;@",
"mmmm/d/yy\\ h:mm;@",
@ -72,7 +72,7 @@ public class TestHSSFDataFormatter extends TestCase {
};
// valid number formats
String[] goodNumPatterns = new String[] {
String[] goodNumPatterns = {
"#,##0.0000",
"#,##0;[Red]#,##0",
"(#,##0.00_);(#,##0.00)",
@ -86,7 +86,7 @@ public class TestHSSFDataFormatter extends TestCase {
};
// invalid date formats -- will throw exception in DecimalFormat ctor
String[] badNumPatterns = new String[] {
String[] badNumPatterns = {
"#,#$'#0.0000",
"'#','#ABC#0;##,##0",
"000 '123 4'5'6 000",
@ -169,10 +169,10 @@ public class TestHSSFDataFormatter extends TestCase {
// Valid date formats -- cell values should be date formatted & not "555.555"
HSSFRow row = wb.getSheetAt(0).getRow(0);
Iterator it = row.cellIterator();
System.out.println("==== VALID DATE FORMATS ====");
log("==== VALID DATE FORMATS ====");
while (it.hasNext()) {
HSSFCell cell = (HSSFCell) it.next();
System.out.println(formatter.formatCellValue(cell));
log(formatter.formatCellValue(cell));
// should not be equal to "555.555"
assertTrue( ! "555.555".equals(formatter.formatCellValue(cell)));
@ -184,10 +184,10 @@ public class TestHSSFDataFormatter extends TestCase {
// test number formats
row = wb.getSheetAt(0).getRow(1);
it = row.cellIterator();
System.out.println("\n==== VALID NUMBER FORMATS ====");
log("\n==== VALID NUMBER FORMATS ====");
while (it.hasNext()) {
HSSFCell cell = (HSSFCell) it.next();
System.out.println(formatter.formatCellValue(cell));
log(formatter.formatCellValue(cell));
// should not be equal to "1234567890.12345"
assertTrue( ! "1234567890.12345".equals(formatter.formatCellValue(cell)));
@ -196,10 +196,10 @@ public class TestHSSFDataFormatter extends TestCase {
// test bad number formats
row = wb.getSheetAt(0).getRow(2);
it = row.cellIterator();
System.out.println("\n==== INVALID NUMBER FORMATS ====");
log("\n==== INVALID NUMBER FORMATS ====");
while (it.hasNext()) {
HSSFCell cell = (HSSFCell) it.next();
System.out.println(formatter.formatCellValue(cell));
log(formatter.formatCellValue(cell));
// should be equal to "1234567890.12345"
assertEquals("1234567890.12345", formatter.formatCellValue(cell));
}
@ -207,22 +207,22 @@ public class TestHSSFDataFormatter extends TestCase {
// test Zip+4 format
row = wb.getSheetAt(0).getRow(3);
HSSFCell cell = row.getCell(0);
System.out.println("\n==== ZIP FORMAT ====");
System.out.println(formatter.formatCellValue(cell));
log("\n==== ZIP FORMAT ====");
log(formatter.formatCellValue(cell));
assertEquals("12345-6789", formatter.formatCellValue(cell));
// test phone number format
row = wb.getSheetAt(0).getRow(4);
cell = row.getCell(0);
System.out.println("\n==== PHONE FORMAT ====");
System.out.println(formatter.formatCellValue(cell));
log("\n==== PHONE FORMAT ====");
log(formatter.formatCellValue(cell));
assertEquals("(555) 123-4567", formatter.formatCellValue(cell));
// test SSN format
row = wb.getSheetAt(0).getRow(5);
cell = row.getCell(0);
System.out.println("\n==== SSN FORMAT ====");
System.out.println(formatter.formatCellValue(cell));
log("\n==== SSN FORMAT ====");
log(formatter.formatCellValue(cell));
assertEquals("444-55-1234", formatter.formatCellValue(cell));
// null test-- null cell should result in empty String
@ -237,17 +237,17 @@ public class TestHSSFDataFormatter extends TestCase {
// test formula format
HSSFRow row = wb.getSheetAt(0).getRow(6);
HSSFCell cell = row.getCell(0);
System.out.println("\n==== FORMULA CELL ====");
log("\n==== FORMULA CELL ====");
// first without a formula evaluator
System.out.println(formatter.formatCellValue(cell) + "\t (without evaluator)");
log(formatter.formatCellValue(cell) + "\t (without evaluator)");
assertEquals("SUM(12.25,12.25)/100", formatter.formatCellValue(cell));
// now with a formula evaluator
HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb.getSheetAt(0), wb);
//! must set current row !
evaluator.setCurrentRow(row);
System.out.println(formatter.formatCellValue(cell, evaluator) + "\t\t\t (with evaluator)");
log(formatter.formatCellValue(cell, evaluator) + "\t\t\t (with evaluator)");
assertEquals("24.50%", formatter.formatCellValue(cell,evaluator));
}
@ -263,20 +263,19 @@ public class TestHSSFDataFormatter extends TestCase {
Format defaultFormat = new DecimalFormat("Balance $#,#00.00 USD;Balance -$#,#00.00 USD");
formatter.setDefaultNumberFormat(defaultFormat);
double value = 10d;
System.out.println("\n==== DEFAULT NUMBER FORMAT ====");
log("\n==== DEFAULT NUMBER FORMAT ====");
while (it.hasNext()) {
HSSFCell cell = (HSSFCell) it.next();
cell.setCellValue(cell.getNumericCellValue() * Math.random() / 1000000 - 1000);
System.out.println(formatter.formatCellValue(cell));
log(formatter.formatCellValue(cell));
assertTrue(formatter.formatCellValue(cell).startsWith("Balance "));
assertTrue(formatter.formatCellValue(cell).endsWith(" USD"));
}
}
public static void main(String [] args) {
System.out
.println("Testing org.apache.poi.hssf.usermodel.TestHSSFDataFormatter");
junit.textui.TestRunner.run(TestHSSFDataFormatter.class);
private static void log(String msg) {
if (false) { // successful tests should be silent
System.out.println(msg);
}
}
}