From a86686846b4ddf8efc5571228ab8211e40a8324b Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Sun, 24 Jul 2016 11:38:50 +0000 Subject: [PATCH 001/157] Bug 59634: Clarify and refine JavaDoc of various close() methods to consistently state that close() invalidates the object git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1753912 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/hssf/usermodel/HSSFWorkbook.java | 13 ++++++------- src/java/org/apache/poi/ss/usermodel/Workbook.java | 8 +++++--- src/ooxml/java/org/apache/poi/POIXMLDocument.java | 8 ++++++-- .../apache/poi/xssf/streaming/SXSSFWorkbook.java | 7 +++++-- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index 123d8d332..35f986211 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -548,7 +548,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss * the 'active' sheet (which is the sheet with focus). * Unselects sheets that are not in indexes. * - * @param indexes + * @param indexes Array of sheets to select, the index is 0-based. */ public void setSelectedTabs(int[] indexes) { Collection list = new ArrayList(indexes.length); @@ -563,7 +563,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss * the 'active' sheet (which is the sheet with focus). * Unselects sheets that are not in indexes. * - * @param indexes + * @param indexes Collection of sheets to select, the index is 0-based. */ public void setSelectedTabs(Collection indexes) { @@ -893,8 +893,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss */ @Override public Iterator sheetIterator() { - Iterator result = new SheetIterator(); - return result; + return new SheetIterator(); } /** @@ -1280,9 +1279,9 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss /** * Closes the underlying {@link NPOIFSFileSystem} from which - * the Workbook was read, if any. Has no effect on Workbooks - * opened from an InputStream, or newly created ones. - *

Once {@link #close()} has been called, no further + * the Workbook was read, if any. + * + *

Once this has been called, no further * operations, updates or reads should be performed on the * Workbook. */ diff --git a/src/java/org/apache/poi/ss/usermodel/Workbook.java b/src/java/org/apache/poi/ss/usermodel/Workbook.java index 1fcc29a3e..f1f1a4cd2 100644 --- a/src/java/org/apache/poi/ss/usermodel/Workbook.java +++ b/src/java/org/apache/poi/ss/usermodel/Workbook.java @@ -341,9 +341,11 @@ public interface Workbook extends Closeable, Iterable { /** * Close the underlying input resource (File or Stream), - * from which the Workbook was read. After closing, the - * Workbook should no longer be used. - *

This will have no effect newly created Workbooks. + * from which the Workbook was read. + * + *

Once this has been called, no further + * operations, updates or reads should be performed on the + * Workbook. */ @Override void close() throws IOException; diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocument.java b/src/ooxml/java/org/apache/poi/POIXMLDocument.java index 55b1a4d18..4ec3d442e 100644 --- a/src/ooxml/java/org/apache/poi/POIXMLDocument.java +++ b/src/ooxml/java/org/apache/poi/POIXMLDocument.java @@ -193,8 +193,12 @@ public abstract class POIXMLDocument extends POIXMLDocumentPart implements Close /** * Closes the underlying {@link OPCPackage} from which this * document was read, if there is one - * - * @throws IOException for writable packages, if an IO exception occur during the saving process. + * + *

Once this has been called, no further + * operations, updates or reads should be performed on the + * document. + * + * @throws IOException for writable packages, if an IO exception occur during the saving process. */ @Override public void close() throws IOException { diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java index 6993579cc..58e16c772 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java @@ -893,8 +893,11 @@ public class SXSSFWorkbook implements Workbook { /** * Closes the underlying {@link XSSFWorkbook} and {@link OPCPackage} - * on which this Workbook is based, if any. Has no effect on Workbooks - * created from scratch. + * on which this Workbook is based, if any. + * + *

Once this has been called, no further + * operations, updates or reads should be performed on the + * Workbook. */ @Override public void close() throws IOException { From 2beb904e868c6a7005f5e7dfdfe5b02988e31bc5 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Tue, 26 Jul 2016 10:58:08 +0000 Subject: [PATCH 002/157] HWPFDocument.write(File) support and tests #57919 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754108 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/org/apache/poi/hwpf/HWPFDocument.java | 38 +++++++-- .../poi/hwpf/usermodel/TestHWPFWrite.java | 81 +++++++++++++++++++ 2 files changed, 111 insertions(+), 8 deletions(-) create mode 100644 src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestHWPFWrite.java diff --git a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java index f9d53dcbd..fe22c03ef 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java @@ -571,20 +571,39 @@ public final class HWPFDocument extends HWPFDocumentCore { return _fields; } + /** + * Warning - not currently implemented for HWPF! + */ @Override public void write() throws IOException { + // TODO Implement throw new IllegalStateException("Coming soon!"); } + + /** + * Writes out the word file that is represented by an instance of this class. + * + * If the {@link File} exists, it will be replaced, otherwise a new one + * will be created + * + * @param newFile The File to write to. + * @throws IOException If there is an unexpected IOException from writing + * to the File. + * + * @since 3.15 beta 3 + */ @Override public void write(File newFile) throws IOException { - throw new IllegalStateException("Coming soon!"); + NPOIFSFileSystem pfs = POIFSFileSystem.create(newFile); + write(pfs, true); + pfs.writeFilesystem(); } /** * Writes out the word file that is represented by an instance of this class. * - * If {@code stream} is a {@link java.io.FileOutputStream} on a networked drive - * or has a high cost/latency associated with each written byte, + * For better performance when writing to files, use {@link #write(File)}. + * If {@code stream} has a high cost/latency associated with each written byte, * consider wrapping the OutputStream in a {@link java.io.BufferedOutputStream} * to improve write performance. * @@ -592,9 +611,12 @@ public final class HWPFDocument extends HWPFDocumentCore { * @throws IOException If there is an unexpected IOException from the passed * in OutputStream. */ - public void write(OutputStream out) - throws IOException - { + public void write(OutputStream out) throws IOException { + NPOIFSFileSystem pfs = new NPOIFSFileSystem(); + write(pfs, true); + pfs.writeFilesystem( out ); + } + private void write(NPOIFSFileSystem pfs, boolean copyOtherEntries) throws IOException { // initialize our streams for writing. HWPFFileSystem docSys = new HWPFFileSystem(); HWPFOutputStream wordDocumentStream = docSys.getStream(STREAM_WORD_DOCUMENT); @@ -891,7 +913,8 @@ public final class HWPFDocument extends HWPFDocumentCore { } // create new document preserving order of entries - NPOIFSFileSystem pfs = new NPOIFSFileSystem(); + // TODO Check "copyOtherEntries" and tweak behaviour based on that + // TODO That's needed for in-place write boolean docWritten = false; boolean dataWritten = false; boolean objectPoolWritten = false; @@ -967,7 +990,6 @@ public final class HWPFDocument extends HWPFDocumentCore { if ( !objectPoolWritten ) _objectPool.writeTo( pfs.getRoot() ); - pfs.writeFilesystem( out ); this.directory = pfs.getRoot(); /* diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestHWPFWrite.java b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestHWPFWrite.java new file mode 100644 index 000000000..95d7919e3 --- /dev/null +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestHWPFWrite.java @@ -0,0 +1,81 @@ +/* ==================================================================== + 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.hwpf.usermodel; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; + +import org.apache.poi.hwpf.HWPFDocument; +import org.apache.poi.hwpf.HWPFTestCase; +import org.apache.poi.hwpf.HWPFTestDataSamples; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.util.TempFile; + +/** + * Test various write situations + */ +public final class TestHWPFWrite extends HWPFTestCase { + /** + * Write to a stream + */ + public void testWriteStream() throws Exception { + HWPFDocument doc = HWPFTestDataSamples.openSampleFile("SampleDoc.doc"); + + Range r = doc.getRange(); + assertEquals("I am a test document\r", r.getParagraph(0).text()); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + doc.write(baos); + doc.close(); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + + doc = new HWPFDocument(bais); + r = doc.getRange(); + assertEquals("I am a test document\r", r.getParagraph(0).text()); + doc.close(); + } + + /** + * Write to a new file + */ + public void testWriteNewFile() throws Exception { + HWPFDocument doc = HWPFTestDataSamples.openSampleFile("SampleDoc.doc"); + + Range r = doc.getRange(); + assertEquals("I am a test document\r", r.getParagraph(0).text()); + + File file = TempFile.createTempFile("TestDocument", ".doc"); + doc.write(file); + doc.close(); + + // Check reading from File and Stream + doc = new HWPFDocument(new FileInputStream(file)); + r = doc.getRange(); + assertEquals("I am a test document\r", r.getParagraph(0).text()); + doc.close(); + + doc = new HWPFDocument(new POIFSFileSystem(file)); + r = doc.getRange(); + assertEquals("I am a test document\r", r.getParagraph(0).text()); + doc.close(); + } + + // TODO In-place write positive and negative checks +} From fa249495207b19593937d427193fc91bb2b0b046 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Wed, 27 Jul 2016 18:15:54 +0000 Subject: [PATCH 003/157] Bug 55384: Handle setting pre-evaluation string correctly in SXSSF as well git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754328 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/xssf/streaming/SXSSFCell.java | 12 ++- .../ss/usermodel/BaseTestBugzillaIssues.java | 79 ++++++++++++++++++- 2 files changed, 89 insertions(+), 2 deletions(-) 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 6c6574443..e6994b8de 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java @@ -338,7 +338,11 @@ public class SXSSFCell implements Cell { } if(_value.getType()==CellType.FORMULA) - ((StringFormulaValue)_value).setPreEvaluatedValue(value); + if(_value instanceof NumericFormulaValue) { + ((NumericFormulaValue) _value).setPreEvaluatedValue(Double.parseDouble(value)); + } else { + ((StringFormulaValue) _value).setPreEvaluatedValue(value); + } else ((PlainStringValue)_value).setValue(value); } else { @@ -956,6 +960,7 @@ public class SXSSFCell implements Cell { } /*package*/ void setFormulaType(CellType type) { + Value prevValue = _value; switch(type) { case NUMERIC: @@ -983,6 +988,11 @@ public class SXSSFCell implements Cell { throw new IllegalArgumentException("Illegal type " + type); } } + + // if we had a Formula before, we should copy over the _value of the formula + if(prevValue instanceof FormulaValue) { + ((FormulaValue)_value)._value = ((FormulaValue)prevValue)._value; + } } //TODO: implement this correctly @NotImplemented diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java index a832635c1..bdd09bfd6 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java @@ -33,9 +33,12 @@ import java.awt.font.FontRenderContext; import java.awt.font.TextAttribute; import java.awt.font.TextLayout; import java.awt.geom.Rectangle2D; +import java.io.FileInputStream; import java.io.IOException; import java.text.AttributedString; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import static org.junit.Assert.*; @@ -1606,4 +1609,78 @@ public abstract class BaseTestBugzillaIssues { assertNull("Sheet0 after write", wb2.getPrintArea(0)); // CURRENTLY FAILS with "Sheet0!$A$1:$C$6" assertEquals("Sheet1 after write", "Sheet1!$A$1:$A$1", wb2.getPrintArea(1)); } -} + + + @Test + public void test55384() throws Exception { + Workbook wb = _testDataProvider.createWorkbook(); + try { + Sheet sh = wb.createSheet(); + for (int rownum = 0; rownum < 10; rownum++) { + org.apache.poi.ss.usermodel.Row row = sh.createRow(rownum); + for (int cellnum = 0; cellnum < 3; cellnum++) { + Cell cell = row.createCell(cellnum); + cell.setCellValue(rownum + cellnum); + } + } + Row row = sh.createRow(10); + // setting no precalculated value works just fine. + Cell cell1 = row.createCell(0); + cell1.setCellFormula("SUM(A1:A10)"); + + // but setting a precalculated STRING value fails totally in SXSSF + Cell cell2 = row.createCell(1); + cell2.setCellFormula("SUM(B1:B10)"); + cell2.setCellValue("55"); + + // setting a precalculated int value works as expected + Cell cell3 = row.createCell(2); + cell3.setCellFormula("SUM(C1:C10)"); + cell3.setCellValue(65); + + assertEquals(CellType.FORMULA, cell1.getCellTypeEnum()); + assertEquals(CellType.FORMULA, cell2.getCellTypeEnum()); + assertEquals(CellType.FORMULA, cell3.getCellTypeEnum()); + + assertEquals("SUM(A1:A10)", cell1.getCellFormula()); + assertEquals("SUM(B1:B10)", cell2.getCellFormula()); + assertEquals("SUM(C1:C10)", cell3.getCellFormula()); + + /*String name = wb.getClass().getCanonicalName(); + String ext = (wb instanceof HSSFWorkbook) ? ".xls" : ".xlsx"; + OutputStream output = new FileOutputStream("/tmp" + name + ext); + try { + wb.write(output); + } finally { + output.close(); + }*/ + + Workbook wbBack = _testDataProvider.writeOutAndReadBack(wb); + checkFormulaPreevaluatedString(wbBack); + wbBack.close(); + } finally { + wb.close(); + } + } + + private void checkFormulaPreevaluatedString(Workbook readFile) { + Sheet sheet = readFile.getSheetAt(0); + Row row = sheet.getRow(sheet.getLastRowNum()); + assertEquals(10, row.getRowNum()); + + for (Cell cell : row) { + String cellValue = null; + switch (cell.getCellTypeEnum()) { + case STRING: + cellValue = cell.getRichStringCellValue().getString(); + break; + case FORMULA: + cellValue = cell.getCellFormula(); + break; + } + assertNotNull(cellValue); + cellValue = cellValue.isEmpty() ? null : cellValue; + assertNotNull(cellValue); + } + } +} \ No newline at end of file From e5877bd8e02785389d784fecdd6efb77444b64e1 Mon Sep 17 00:00:00 2001 From: David North Date: Fri, 29 Jul 2016 13:24:00 +0000 Subject: [PATCH 004/157] Introduce name-based methods for access to named ranges in a workbook, and deprecate the old index-based methods. Re-organise internally to use a map so that lookup is O(1) rather than O(n ranges). Add a dependency on commons collections 4, also ASL licensed so no problem. https://bz.apache.org/bugzilla/show_bug.cgi?id=59734 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754521 13f79535-47bb-0310-9956-ffa450edef68 --- .classpath | 15 +- build.xml | 9 +- maven/poi-ooxml.pom | 5 + .../poi/hssf/usermodel/HSSFWorkbook.java | 11 +- .../org/apache/poi/ss/usermodel/Workbook.java | 14 ++ .../poi/xssf/streaming/SXSSFWorkbook.java | 36 +++- .../usermodel/BaseXSSFEvaluationWorkbook.java | 2 +- .../apache/poi/xssf/usermodel/XSSFName.java | 11 +- .../poi/xssf/usermodel/XSSFWorkbook.java | 176 ++++++++++++------ .../usermodel/helpers/XSSFFormulaUtils.java | 4 +- .../usermodel/helpers/XSSFRowShifter.java | 4 +- .../poi/xssf/usermodel/TestXSSFBugs.java | 26 +-- .../poi/xssf/usermodel/TestXSSFName.java | 42 ++++- .../poi/xssf/usermodel/TestXSSFWorkbook.java | 40 ++++ .../poi/ss/usermodel/BaseTestNamedRange.java | 20 +- .../ss/usermodel/BaseTestSheetShiftRows.java | 8 +- 16 files changed, 311 insertions(+), 112 deletions(-) diff --git a/.classpath b/.classpath index ae3f06128..3b3ff5b64 100644 --- a/.classpath +++ b/.classpath @@ -18,18 +18,19 @@ - + - - + + - + - - - + + + + diff --git a/build.xml b/build.xml index 0285acae3..55abab1f2 100644 --- a/build.xml +++ b/build.xml @@ -184,6 +184,9 @@ under the License. + + @@ -326,6 +329,7 @@ under the License. + @@ -623,6 +627,7 @@ under the License. + @@ -633,6 +638,7 @@ under the License. + @@ -1874,7 +1880,7 @@ under the License. - + @@ -2116,6 +2122,7 @@ under the License. + diff --git a/maven/poi-ooxml.pom b/maven/poi-ooxml.pom index 0f3cdb1d5..2f4c286bc 100644 --- a/maven/poi-ooxml.pom +++ b/maven/poi-ooxml.pom @@ -74,5 +74,10 @@ curvesapi 1.04 + + org.apache.commons + commons-collections4 + 4.1 + diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index 35f986211..ba015a9f1 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -92,6 +92,7 @@ import org.apache.poi.ss.formula.SheetNameFormatter; import org.apache.poi.ss.formula.udf.AggregatingUDFFinder; import org.apache.poi.ss.formula.udf.IndexedUDFFinder; import org.apache.poi.ss.formula.udf.UDFFinder; +import org.apache.poi.ss.usermodel.Name; import org.apache.poi.ss.usermodel.Row.MissingCellPolicy; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; @@ -1530,6 +1531,11 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss return names.get(nameIndex); } + @Override + public List getAllNames() { + return Collections.unmodifiableList(names); + } + public NameRecord getNameRecord(int nameIndex) { return getWorkbook().getNameRecord(nameIndex); } @@ -1701,8 +1707,9 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss * * @param name the name to remove. */ - void removeName(HSSFName name) { - int index = getNameIndex(name); + @Override + public void removeName(Name name) { + int index = getNameIndex((HSSFName) name); removeName(index); } diff --git a/src/java/org/apache/poi/ss/usermodel/Workbook.java b/src/java/org/apache/poi/ss/usermodel/Workbook.java index f1f1a4cd2..e52615fb1 100644 --- a/src/java/org/apache/poi/ss/usermodel/Workbook.java +++ b/src/java/org/apache/poi/ss/usermodel/Workbook.java @@ -369,6 +369,13 @@ public interface Workbook extends Closeable, Iterable { */ List getNames(String name); + /** + * Returns all defined names. + * + * @return a list of the defined names. An empty list is returned if none is found. + */ + List getAllNames(); + /** * @param nameIndex position of the named range (0-based) * @return the defined name at the specified index @@ -407,6 +414,13 @@ public interface Workbook extends Closeable, Iterable { */ void removeName(String name); + /** + * Remove a defined name + * + * @param name the name of the defined name + */ + void removeName(Name name); + /** * Adds the linking required to allow formulas referencing * the specified external workbook to be added to this one. diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java index 58e16c772..331ad9a0f 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java @@ -1006,12 +1006,25 @@ public class SXSSFWorkbook implements Workbook { return _wb.getNames(name); } + /** + * Returns all defined names + * + * @return all defined names + */ + @Override + public List getAllNames() + { + return _wb.getAllNames(); + } + /** * @param nameIndex position of the named range (0-based) * @return the defined name at the specified index * @throws IllegalArgumentException if the supplied index is invalid + * @deprecated 3.16. New projects should avoid accessing named ranges by index. */ @Override + @Deprecated public Name getNameAt(int nameIndex) { return _wb.getNameAt(nameIndex); @@ -1036,8 +1049,12 @@ public class SXSSFWorkbook implements Workbook { * * @param name the name of the defined name * @return zero based index of the defined name. -1 if not found. + * + * @deprecated 3.16. New projects should avoid accessing named ranges by index. + * Use {@link #getName(String)} instead. */ @Override + @Deprecated public int getNameIndex(String name) { return _wb.getNameIndex(name); @@ -1047,8 +1064,11 @@ public class SXSSFWorkbook implements Workbook { * Remove the defined name at the specified index * * @param index named range index (0 based) + * + * @deprecated 3.16. New projects should use {@link #removeName(Name)}. */ @Override + @Deprecated public void removeName(int index) { _wb.removeName(index); @@ -1057,10 +1077,24 @@ public class SXSSFWorkbook implements Workbook { /** * Remove a defined name by name * - * @param name the name of the defined name + * @param name the name of the defined name + * + * @deprecated 3.16. New projects should use {@link #removeName(Name)}. */ @Override + @Deprecated public void removeName(String name) + { + _wb.removeName(name); + } + + /** + * Remove the given defined name + * + * @param name the name to remove + */ + @Override + public void removeName(Name name) { _wb.removeName(name); } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFEvaluationWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFEvaluationWorkbook.java index f3c6bc267..9c5e6ffb1 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFEvaluationWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFEvaluationWorkbook.java @@ -232,7 +232,7 @@ public abstract class BaseXSSFEvaluationWorkbook implements FormulaRenderingWork // Otherwise, try it as a named range if (sheet == null) { - if (_uBook.getNameIndex(name) > -1) { + if (!_uBook.getNames(name).isEmpty()) { return new NameXPxg(null, name); } return null; diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFName.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFName.java index 462bd6517..071062620 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFName.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFName.java @@ -167,19 +167,18 @@ public final class XSSFName implements Name { public void setNameName(String name) { validateName(name); + String oldName = getNameName(); int sheetIndex = getSheetIndex(); - int numberOfNames = _workbook.getNumberOfNames(); //Check to ensure no other names have the same case-insensitive name at the same scope - for (int i = 0; i < numberOfNames; i++) { - XSSFName nm = _workbook.getNameAt(i); - if ((nm != this) - && name.equalsIgnoreCase(nm.getNameName()) - && (sheetIndex == nm.getSheetIndex())) { + for (XSSFName foundName : _workbook.getNames(name)) { + if (foundName.getSheetIndex() == sheetIndex && foundName != this) { String msg = "The "+(sheetIndex == -1 ? "workbook" : "sheet")+" already contains this name: " + name; throw new IllegalArgumentException(msg); } } _ctName.setName(name); + //Need to update the name -> named ranges map + _workbook.updateName(this, oldName); } public String getRefersToFormula() { diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java index 1e9b3d6ce..bcc2ed27d 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java @@ -29,16 +29,20 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.NoSuchElementException; import java.util.regex.Pattern; import javax.xml.namespace.QName; +import org.apache.commons.collections4.ListValuedMap; +import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.apache.poi.POIXMLDocument; import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.POIXMLException; @@ -59,6 +63,7 @@ import org.apache.poi.ss.formula.SheetNameFormatter; import org.apache.poi.ss.formula.udf.AggregatingUDFFinder; import org.apache.poi.ss.formula.udf.IndexedUDFFinder; import org.apache.poi.ss.formula.udf.UDFFinder; +import org.apache.poi.ss.usermodel.Name; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row.MissingCellPolicy; import org.apache.poi.ss.usermodel.Sheet; @@ -140,6 +145,11 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { */ private List sheets; + /** + * this holds the XSSFName objects attached to this workbook, keyed by lower-case name + */ + private ListValuedMap namedRangesByName; + /** * this holds the XSSFName objects attached to this workbook */ @@ -442,6 +452,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { stylesSource.setWorkbook(this); namedRanges = new ArrayList(); + namedRangesByName = new ArrayListValuedHashMap(); sheets = new ArrayList(); pivotTables = new ArrayList(); } @@ -733,8 +744,13 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { public XSSFName createName() { CTDefinedName ctName = CTDefinedName.Factory.newInstance(); ctName.setName(""); + return createAndStoreName(ctName); + } + + private XSSFName createAndStoreName(CTDefinedName ctName) { XSSFName name = new XSSFName(ctName, this); namedRanges.add(name); + namedRangesByName.put(ctName.getName().toLowerCase(Locale.ENGLISH), name); return name; } @@ -938,28 +954,47 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { return stylesSource.getFontAt(idx); } + /** + * Get the first named range with the given name. + * + * Note: names of named ranges are not unique as they are scoped by sheet. + * {@link #getNames(String name)} returns all named ranges with the given name. + * + * @param name named range name + * @return XSSFName with the given name. null is returned no named range could be found. + */ @Override public XSSFName getName(String name) { - int nameIndex = getNameIndex(name); - if (nameIndex < 0) { + Collection list = getNames(name); + if (list.isEmpty()) { return null; } - return namedRanges.get(nameIndex); + return list.iterator().next(); } + /** + * Get the named ranges with the given name. + * Note:Excel named ranges are case-insensitive and + * this method performs a case-insensitive search. + * + * @param name named range name + * @return list of XSSFNames with the given name. An empty list if no named ranges could be found + */ @Override public List getNames(String name) { - List names = new ArrayList(); - for(XSSFName nr : namedRanges) { - if(nr.getNameName().equals(name)) { - names.add(nr); - } - } - - return names; + return Collections.unmodifiableList(namedRangesByName.get(name.toLowerCase(Locale.ENGLISH))); } + /** + * Get the named range at the given index. + * + * @param nameIndex the index of the named range + * @return the XSSFName at the given index + * + * @deprecated 3.16. New projects should avoid accessing named ranges by index. + */ @Override + @Deprecated public XSSFName getNameAt(int nameIndex) { int nNames = namedRanges.size(); if (nNames < 1) { @@ -973,21 +1008,30 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { } /** - * Gets the named range index by his name - * Note:Excel named ranges are case-insensitive and - * this method performs a case-insensitive search. + * Get a list of all the named ranges in the workbook. * - * @param name named range name - * @return named range index + * @return list of XSSFNames in the workbook */ @Override + public List getAllNames() { + return Collections.unmodifiableList(namedRanges); + } + + /** + * Gets the named range index by name. + * + * @param name named range name + * @return named range index. -1 is returned if no named ranges could be found. + * + * @deprecated 3.16. New projects should avoid accessing named ranges by index. + * Use {@link #getName(String)} instead. + */ + @Override + @Deprecated public int getNameIndex(String name) { - int i = 0; - for(XSSFName nr : namedRanges) { - if(nr.getNameName().equals(name)) { - return i; - } - i++; + XSSFName nm = getName(name); + if (nm != null) { + return namedRanges.indexOf(nm); } return -1; } @@ -1258,22 +1302,40 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { return getPackagePart().getContentType().equals(XSSFRelation.MACROS_WORKBOOK.getContentType()); } + /** + * Remove the named range at the given index. + * + * @param index the index of the named range name to remove + * + * @deprecated 3.16. New projects should use {@link #removeName(Name)}. + */ @Override + @Deprecated public void removeName(int nameIndex) { - namedRanges.remove(nameIndex); + removeName(getNameAt(nameIndex)); } + /** + * Remove the first named range found with the given name. + * + * Note: names of named ranges are not unique (name + sheet + * index is unique), so {@link #removeName(Name)} should + * be used if possible. + * + * @param name the named range name to remove + * + * @throws IllegalArgumentException if no named range could be found + * + * @deprecated 3.16. New projects should use {@link #removeName(Name)}. + */ @Override + @Deprecated public void removeName(String name) { - int idx = 0; - for (XSSFName nm : namedRanges) { - if(nm.getNameName().equalsIgnoreCase(name)) { - removeName(idx); - return; - } - idx++; + List names = namedRangesByName.get(name.toLowerCase(Locale.ENGLISH)); + if (names.isEmpty()) { + throw new IllegalArgumentException("Named range was not found: " + name); } - throw new IllegalArgumentException("Named range was not found: " + name); + removeName(names.get(0)); } @@ -1282,13 +1344,24 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { * (name + sheet index is unique), this method is more accurate. * * @param name the name to remove. + * + * @throws IllegalArgumentException if the named range is not a part of this XSSFWorkbook */ - void removeName(XSSFName name) { - if (!namedRanges.remove(name)) { + @Override + public void removeName(Name name) { + if (!namedRangesByName.removeMapping(name.getNameName().toLowerCase(Locale.ENGLISH), name) + || !namedRanges.remove(name)) { throw new IllegalArgumentException("Name was not found: " + name); } } + void updateName(XSSFName name, String oldName) { + if (!namedRangesByName.removeMapping(oldName.toLowerCase(Locale.ENGLISH), name)) { + throw new IllegalArgumentException("Name was not found: " + name); + } + namedRangesByName.put(name.getNameName().toLowerCase(Locale.ENGLISH), name); + } + /** * Delete the printarea for the sheet specified @@ -1297,13 +1370,9 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { */ @Override public void removePrintArea(int sheetIndex) { - int cont = 0; - for (XSSFName name : namedRanges) { - if (name.getNameName().equals(XSSFName.BUILTIN_PRINT_AREA) && name.getSheetIndex() == sheetIndex) { - namedRanges.remove(cont); - break; - } - cont++; + XSSFName name = getBuiltInName(XSSFName.BUILTIN_PRINT_AREA, sheetIndex); + if (name != null) { + removeName(name); } } @@ -1369,17 +1438,20 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { } //adjust indices of names ranges - for (Iterator it = namedRanges.iterator(); it.hasNext();) { - XSSFName nm = it.next(); + List toRemove = new ArrayList(); + for (XSSFName nm : namedRanges) { CTDefinedName ct = nm.getCTName(); if(!ct.isSetLocalSheetId()) continue; if (ct.getLocalSheetId() == index) { - it.remove(); + toRemove.add(nm); } else if (ct.getLocalSheetId() > index){ // Bump down by one, so still points at the same sheet ct.setLocalSheetId(ct.getLocalSheetId()-1); } } + for (XSSFName nm : toRemove) { + removeName(nm); + } } /** @@ -1514,8 +1586,8 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { } XSSFName getBuiltInName(String builtInCode, int sheetNumber) { - for (XSSFName name : namedRanges) { - if (name.getNameName().equalsIgnoreCase(builtInCode) && name.getSheetIndex() == sheetNumber) { + for (XSSFName name : namedRangesByName.get(builtInCode.toLowerCase(Locale.ENGLISH))) { + if (name.getSheetIndex() == sheetNumber) { return name; } } @@ -1537,15 +1609,12 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { nameRecord.setName(builtInName); nameRecord.setLocalSheetId(sheetNumber); - XSSFName name = new XSSFName(nameRecord, this); - for (XSSFName nr : namedRanges) { - if (nr.equals(name)) - throw new POIXMLException("Builtin (" + builtInName - + ") already exists for sheet (" + sheetNumber + ")"); + if (getBuiltInName(builtInName, sheetNumber) != null) { + throw new POIXMLException("Builtin (" + builtInName + + ") already exists for sheet (" + sheetNumber + ")"); } - namedRanges.add(name); - return name; + return createAndStoreName(nameRecord); } /** @@ -1665,10 +1734,11 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { } private void reprocessNamedRanges() { + namedRangesByName = new ArrayListValuedHashMap(); namedRanges = new ArrayList(); if(workbook.isSetDefinedNames()) { for(CTDefinedName ctName : workbook.getDefinedNames().getDefinedNameArray()) { - namedRanges.add(new XSSFName(ctName, this)); + createAndStoreName(ctName); } } } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFFormulaUtils.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFFormulaUtils.java index 1d146c09c..ef0c5ea63 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFFormulaUtils.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFFormulaUtils.java @@ -65,9 +65,7 @@ public final class XSSFFormulaUtils { */ public void updateSheetName(final int sheetIndex, final String oldName, final String newName) { // update named ranges - final int numberOfNames = _wb.getNumberOfNames(); - for (int i = 0; i < numberOfNames; i++) { - XSSFName nm = _wb.getNameAt(i); + for (XSSFName nm : _wb.getAllNames()) { if (nm.getSheetIndex() == -1 || nm.getSheetIndex() == sheetIndex) { updateName(nm, oldName, newName); } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java index 63104dd9e..d11ed1fa8 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java @@ -83,9 +83,7 @@ public final class XSSFRowShifter extends RowShifter { public void updateNamedRanges(FormulaShifter shifter) { Workbook wb = sheet.getWorkbook(); XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create((XSSFWorkbook) wb); - final int numberOfNames = wb.getNumberOfNames(); - for (int i = 0; i < numberOfNames; i++) { - Name name = wb.getNameAt(i); + for (Name name : wb.getAllNames()) { String formula = name.getRefersToFormula(); int sheetIndex = name.getSheetIndex(); final int rowIndex = -1; //don't care, named ranges are not allowed to include structured references 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 3280a9121..2be21e830 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java @@ -115,25 +115,25 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertFalse(wb.isMacroEnabled()); assertEquals(3, wb.getNumberOfNames()); - assertEquals(0, wb.getNameAt(0).getCTName().getLocalSheetId()); - assertFalse(wb.getNameAt(0).getCTName().isSetLocalSheetId()); - assertEquals("SheetA!$A$1", wb.getNameAt(0).getRefersToFormula()); - assertEquals("SheetA", wb.getNameAt(0).getSheetName()); + assertEquals(0, wb.getName("SheetAA1").getCTName().getLocalSheetId()); + assertFalse(wb.getName("SheetAA1").getCTName().isSetLocalSheetId()); + assertEquals("SheetA!$A$1", wb.getName("SheetAA1").getRefersToFormula()); + assertEquals("SheetA", wb.getName("SheetAA1").getSheetName()); - assertEquals(0, wb.getNameAt(1).getCTName().getLocalSheetId()); - assertFalse(wb.getNameAt(1).getCTName().isSetLocalSheetId()); - assertEquals("SheetB!$A$1", wb.getNameAt(1).getRefersToFormula()); - assertEquals("SheetB", wb.getNameAt(1).getSheetName()); + assertEquals(0, wb.getName("SheetBA1").getCTName().getLocalSheetId()); + assertFalse(wb.getName("SheetBA1").getCTName().isSetLocalSheetId()); + assertEquals("SheetB!$A$1", wb.getName("SheetBA1").getRefersToFormula()); + assertEquals("SheetB", wb.getName("SheetBA1").getSheetName()); - assertEquals(0, wb.getNameAt(2).getCTName().getLocalSheetId()); - assertFalse(wb.getNameAt(2).getCTName().isSetLocalSheetId()); - assertEquals("SheetC!$A$1", wb.getNameAt(2).getRefersToFormula()); - assertEquals("SheetC", wb.getNameAt(2).getSheetName()); + assertEquals(0, wb.getName("SheetCA1").getCTName().getLocalSheetId()); + assertFalse(wb.getName("SheetCA1").getCTName().isSetLocalSheetId()); + assertEquals("SheetC!$A$1", wb.getName("SheetCA1").getRefersToFormula()); + assertEquals("SheetC", wb.getName("SheetCA1").getSheetName()); // Save and re-load, still there XSSFWorkbook nwb = XSSFTestDataSamples.writeOutAndReadBack(wb); assertEquals(3, nwb.getNumberOfNames()); - assertEquals("SheetA!$A$1", nwb.getNameAt(0).getRefersToFormula()); + assertEquals("SheetA!$A$1", nwb.getName("SheetAA1").getRefersToFormula()); nwb.close(); wb.close(); diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFName.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFName.java index 3e0f0b165..a188a11ed 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFName.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFName.java @@ -53,9 +53,8 @@ public final class TestXSSFName extends BaseTestNamedRange { //sheet.createFreezePane(0, 3); } assertEquals(1, wb.getNumberOfNames()); - XSSFName nr1 = wb.getNameAt(0); + XSSFName nr1 = wb.getName(XSSFName.BUILTIN_PRINT_TITLE); - assertEquals(XSSFName.BUILTIN_PRINT_TITLE, nr1.getNameName()); assertEquals("'First Sheet'!$A:$A,'First Sheet'!$1:$4", nr1.getRefersToFormula()); //remove the columns part @@ -77,9 +76,8 @@ public final class TestXSSFName extends BaseTestNamedRange { wb.close(); assertEquals(1, nwb.getNumberOfNames()); - nr1 = nwb.getNameAt(0); + nr1 = nwb.getName(XSSFName.BUILTIN_PRINT_TITLE); - assertEquals(XSSFName.BUILTIN_PRINT_TITLE, nr1.getNameName()); assertEquals("'First Sheet'!$A:$A,'First Sheet'!$1:$4", nr1.getRefersToFormula()); // check that setting RR&C on a second sheet causes a new Print_Titles built-in @@ -89,7 +87,7 @@ public final class TestXSSFName extends BaseTestNamedRange { sheet2.setRepeatingColumns(CellRangeAddress.valueOf("B:C")); assertEquals(2, nwb.getNumberOfNames()); - XSSFName nr2 = nwb.getNameAt(1); + XSSFName nr2 = nwb.getNames(XSSFName.BUILTIN_PRINT_TITLE).get(1); assertEquals(XSSFName.BUILTIN_PRINT_TITLE, nr2.getNameName()); assertEquals("SecondSheet!$B:$C,SecondSheet!$1:$1", nr2.getRefersToFormula()); @@ -98,4 +96,38 @@ public final class TestXSSFName extends BaseTestNamedRange { sheet2.setRepeatingColumns(null); nwb.close(); } + + @Test + public void testSetNameName() throws Exception { + // Test that renaming named ranges doesn't break our new named range map + XSSFWorkbook wb = new XSSFWorkbook(); + wb.createSheet("First Sheet"); + + // Two named ranges called "name1", one scoped to sheet1 and one globally + XSSFName nameSheet1 = wb.createName(); + nameSheet1.setNameName("name1"); + nameSheet1.setRefersToFormula("'First Sheet'!$A$1"); + nameSheet1.setSheetIndex(0); + + XSSFName nameGlobal = wb.createName(); + nameGlobal.setNameName("name1"); + nameGlobal.setRefersToFormula("'First Sheet'!$B$1"); + + // Rename sheet-scoped name to "name2", check everything is updated properly + // and that the other name is unaffected + nameSheet1.setNameName("name2"); + assertEquals(1, wb.getNames("name1").size()); + assertEquals(1, wb.getNames("name2").size()); + assertEquals(nameGlobal, wb.getName("name1")); + assertEquals(nameSheet1, wb.getName("name2")); + + // Rename the other name to "name" and check everything again + nameGlobal.setNameName("name2"); + assertEquals(0, wb.getNames("name1").size()); + assertEquals(2, wb.getNames("name2").size()); + assertTrue(wb.getNames("name2").contains(nameGlobal)); + assertTrue(wb.getNames("name2").contains(nameSheet1)); + + wb.close(); + } } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java index c3420c780..7f832c4d9 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java @@ -1140,4 +1140,44 @@ public final class TestXSSFWorkbook extends BaseTestXWorkbook { wb.close(); } + + @Test + public void testRemoveSheet() throws IOException { + // Test removing a sheet maintains the named ranges correctly + XSSFWorkbook wb = new XSSFWorkbook(); + wb.createSheet("Sheet1"); + wb.createSheet("Sheet2"); + + XSSFName sheet1Name = wb.createName(); + sheet1Name.setNameName("name1"); + sheet1Name.setSheetIndex(0); + sheet1Name.setRefersToFormula("Sheet1!$A$1"); + + XSSFName sheet2Name = wb.createName(); + sheet2Name.setNameName("name1"); + sheet2Name.setSheetIndex(1); + sheet2Name.setRefersToFormula("Sheet2!$A$1"); + + assertTrue(wb.getAllNames().contains(sheet1Name)); + assertTrue(wb.getAllNames().contains(sheet2Name)); + + assertEquals(2, wb.getNames("name1").size()); + assertEquals(sheet1Name, wb.getNames("name1").get(0)); + assertEquals(sheet2Name, wb.getNames("name1").get(1)); + + // Remove sheet1, we should only have sheet2Name now + wb.removeSheetAt(0); + + assertFalse(wb.getAllNames().contains(sheet1Name)); + assertTrue(wb.getAllNames().contains(sheet2Name)); + assertEquals(1, wb.getNames("name1").size()); + assertEquals(sheet2Name, wb.getNames("name1").get(0)); + + // Check by index as well for sanity + assertEquals(1, wb.getNumberOfNames()); + assertEquals(0, wb.getNameIndex("name1")); + assertEquals(sheet2Name, wb.getNameAt(0)); + + wb.close(); + } } diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestNamedRange.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestNamedRange.java index 75fb77e82..92e362df5 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestNamedRange.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestNamedRange.java @@ -201,11 +201,7 @@ public abstract class BaseTestNamedRange { assertEquals("The sheet already contains this name: aaa", e.getMessage()); } - int cnt = 0; - for (int i = 0; i < wb.getNumberOfNames(); i++) { - if("aaa".equals(wb.getNameAt(i).getNameName())) cnt++; - } - assertEquals(3, cnt); + assertEquals(3, wb.getNames("aaa").size()); wb.close(); } @@ -250,11 +246,11 @@ public abstract class BaseTestNamedRange { // Write the workbook to a file // Read the Excel file and verify its content Workbook wb2 = _testDataProvider.writeOutAndReadBack(wb1); - Name nm1 = wb2.getNameAt(wb2.getNameIndex("RangeTest1")); + Name nm1 = wb2.getName("RangeTest1"); assertTrue("Name is "+nm1.getNameName(),"RangeTest1".equals(nm1.getNameName())); assertTrue("Reference is "+nm1.getRefersToFormula(),(wb2.getSheetName(0)+"!$A$1:$L$41").equals(nm1.getRefersToFormula())); - Name nm2 = wb2.getNameAt(wb2.getNameIndex("RangeTest2")); + Name nm2 = wb2.getName("RangeTest2"); assertTrue("Name is "+nm2.getNameName(),"RangeTest2".equals(nm2.getNameName())); assertTrue("Reference is "+nm2.getRefersToFormula(),(wb2.getSheetName(1)+"!$A$1:$O$21").equals(nm2.getRefersToFormula())); @@ -466,11 +462,11 @@ public abstract class BaseTestNamedRange { wb1.getNameAt(0); Workbook wb2 = _testDataProvider.writeOutAndReadBack(wb1); - Name nm =wb2.getNameAt(wb2.getNameIndex("RangeTest")); + Name nm =wb2.getName("RangeTest"); assertTrue("Name is "+nm.getNameName(),"RangeTest".equals(nm.getNameName())); assertTrue("Reference is "+nm.getRefersToFormula(),(wb2.getSheetName(0)+"!$D$4:$E$8").equals(nm.getRefersToFormula())); - nm = wb2.getNameAt(wb2.getNameIndex("AnotherTest")); + nm = wb2.getName("AnotherTest"); assertTrue("Name is "+nm.getNameName(),"AnotherTest".equals(nm.getNameName())); assertTrue("Reference is "+nm.getRefersToFormula(),newNamedRange2.getRefersToFormula().equals(nm.getRefersToFormula())); @@ -499,8 +495,7 @@ public abstract class BaseTestNamedRange { namedCell.setRefersToFormula(reference); // retrieve the newly created named range - int namedCellIdx = wb.getNameIndex(cellName); - Name aNamedCell = wb.getNameAt(namedCellIdx); + Name aNamedCell = wb.getName(cellName); assertNotNull(aNamedCell); // retrieve the cell at the named range and test its contents @@ -540,8 +535,7 @@ public abstract class BaseTestNamedRange { namedCell.setRefersToFormula(reference); // retrieve the newly created named range - int namedCellIdx = wb.getNameIndex(cname); - Name aNamedCell = wb.getNameAt(namedCellIdx); + Name aNamedCell = wb.getName(cname); assertNotNull(aNamedCell); // retrieve the cell at the named range and test its contents diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java index 3f8febb11..efae0d80c 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java @@ -261,17 +261,17 @@ public abstract class BaseTestSheetShiftRows { name4.setSheetIndex(1); sheet1.shiftRows(0, 1, 2); //shift down the top row on Sheet1. - name1 = wb.getNameAt(0); + name1 = wb.getName("name1"); assertEquals("Sheet1!$A$3+Sheet1!$B$3", name1.getRefersToFormula()); - name2 = wb.getNameAt(1); + name2 = wb.getName("name2"); assertEquals("Sheet1!$A$3", name2.getRefersToFormula()); //name3 and name4 refer to Sheet2 and should not be affected - name3 = wb.getNameAt(2); + name3 = wb.getName("name3"); assertEquals("Sheet2!$A$1", name3.getRefersToFormula()); - name4 = wb.getNameAt(3); + name4 = wb.getName("name4"); assertEquals("A1", name4.getRefersToFormula()); wb.close(); From dfcf57bfbf41b3dd58a3af416f8b6911460e67f6 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Fri, 29 Jul 2016 14:03:28 +0000 Subject: [PATCH 005/157] Javadoc fix git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754530 13f79535-47bb-0310-9956-ffa450edef68 --- src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java index bcc2ed27d..f3a5879db 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java @@ -1305,7 +1305,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { /** * Remove the named range at the given index. * - * @param index the index of the named range name to remove + * @param nameIndex the index of the named range name to remove * * @deprecated 3.16. New projects should use {@link #removeName(Name)}. */ From 299af644b8ec43fdf8008562ebca580bf38af7be Mon Sep 17 00:00:00 2001 From: David North Date: Fri, 29 Jul 2016 18:48:07 +0000 Subject: [PATCH 006/157] As Nick suspected, the dependency is actually from HSSF too so commons collections 4 needs adding to the main POM https://bz.apache.org/bugzilla/show_bug.cgi?id=59734 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754563 13f79535-47bb-0310-9956-ffa450edef68 --- maven/poi-ooxml.pom | 5 ----- maven/poi.pom | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/maven/poi-ooxml.pom b/maven/poi-ooxml.pom index 2f4c286bc..0f3cdb1d5 100644 --- a/maven/poi-ooxml.pom +++ b/maven/poi-ooxml.pom @@ -74,10 +74,5 @@ curvesapi 1.04 - - org.apache.commons - commons-collections4 - 4.1 - diff --git a/maven/poi.pom b/maven/poi.pom index 7c1b4cf84..efd24cfe0 100644 --- a/maven/poi.pom +++ b/maven/poi.pom @@ -91,6 +91,11 @@ test 4.12 + + org.apache.commons + commons-collections4 + 4.1 + From 7d5e62fd8c36537168f26d81f2771ded06ad0dd5 Mon Sep 17 00:00:00 2001 From: David North Date: Sat, 30 Jul 2016 08:54:50 +0000 Subject: [PATCH 007/157] Move commons collections 4 dependency to main https://bz.apache.org/bugzilla/show_bug.cgi?id=59734 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754602 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build.xml b/build.xml index 55abab1f2..7904466a9 100644 --- a/build.xml +++ b/build.xml @@ -169,6 +169,9 @@ under the License. + + @@ -184,9 +187,6 @@ under the License. - - @@ -313,6 +313,7 @@ under the License. + @@ -329,7 +330,6 @@ under the License. - @@ -591,6 +591,7 @@ under the License. + @@ -609,6 +610,7 @@ under the License. + @@ -627,7 +629,6 @@ under the License. - @@ -638,7 +639,6 @@ under the License. - From 45772fed96eaba6b34fde921606e96f88c2d5132 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Sat, 30 Jul 2016 12:39:16 +0000 Subject: [PATCH 008/157] Sonar wants to know about the new commons collections dependency too! git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754620 13f79535-47bb-0310-9956-ffa450edef68 --- sonar/main/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sonar/main/pom.xml b/sonar/main/pom.xml index 72c3eebfc..ffc9499d9 100644 --- a/sonar/main/pom.xml +++ b/sonar/main/pom.xml @@ -110,6 +110,11 @@ + + org.apache.commons + commons-collections4 + 4.1 + commons-codec commons-codec From 3ba5f7fd73abab8f90cf8c930b8de03d8be3eaa9 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Sun, 31 Jul 2016 17:19:05 +0000 Subject: [PATCH 009/157] Adjust build: * Use "skipexisting" in Get from Ant 1.8 * Do not always re-run ooxml-lite * Findbugs does not require src- and javadocs-jars, so depend on "jar" instead of "assemble" git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754672 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/build.xml b/build.xml index 7904466a9..beab59292 100644 --- a/build.xml +++ b/build.xml @@ -133,6 +133,7 @@ under the License. + @@ -502,9 +503,7 @@ under the License. - - - - + @@ -1509,7 +1508,20 @@ under the License. - + + + + + + + + + + + + + @@ -1535,6 +1547,8 @@ under the License. + + @@ -2089,7 +2103,7 @@ under the License. - + @@ -2114,6 +2128,7 @@ under the License. + From 5e0612eabdb40360e2bbbd3488e949f11e13163e Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Sun, 31 Jul 2016 17:19:17 +0000 Subject: [PATCH 010/157] IDE warnings and fix a few places where we do not close resources in tests git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754673 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/openxml4j/opc/OPCPackage.java | 8 ++-- .../opc/internal/ContentTypeManager.java | 7 +-- .../poi/xslf/usermodel/XSLFGroupShape.java | 6 +-- .../poi/xssf/extractor/XSSFExportToXml.java | 47 ++++++------------- .../apache/poi/xssf/streaming/SXSSFCell.java | 1 + .../opc/internal/TestContentTypeManager.java | 24 ++++++---- .../poi/sl/usermodel/BaseTestSlideShow.java | 22 +++++---- .../apache/poi/ss/util/BaseTestCellUtil.java | 29 +++++++----- 8 files changed, 68 insertions(+), 76 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java index a438c061f..e029d7dec 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java @@ -382,8 +382,7 @@ public abstract class OPCPackage implements RelationshipSource, Closeable { } // Creates a new package - OPCPackage pkg = null; - pkg = new ZipPackage(); + OPCPackage pkg = new ZipPackage(); pkg.originalPackagePath = file.getAbsolutePath(); configurePackage(pkg); @@ -391,8 +390,7 @@ public abstract class OPCPackage implements RelationshipSource, Closeable { } public static OPCPackage create(OutputStream output) { - OPCPackage pkg = null; - pkg = new ZipPackage(); + OPCPackage pkg = new ZipPackage(); pkg.originalPackagePath = null; pkg.output = output; @@ -542,7 +540,7 @@ public abstract class OPCPackage implements RelationshipSource, Closeable { // Create the thumbnail part name String contentType = ContentTypes .getContentTypeFromFileExtension(filename); - PackagePartName thumbnailPartName = null; + PackagePartName thumbnailPartName; try { thumbnailPartName = PackagingURIHelper.createPartName("/docProps/" + filename); diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java index 537dd15e9..750f9cd71 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java @@ -29,10 +29,7 @@ import java.util.TreeMap; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidOperationException; import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackagePartName; -import org.apache.poi.openxml4j.opc.PackagingURIHelper; +import org.apache.poi.openxml4j.opc.*; import org.apache.poi.util.DocumentHelper; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -54,7 +51,7 @@ public abstract class ContentTypeManager { /** * Content type namespace */ - public static final String TYPES_NAMESPACE_URI = "http://schemas.openxmlformats.org/package/2006/content-types"; + public static final String TYPES_NAMESPACE_URI = PackageNamespaces.CONTENT_TYPES; /* Xml elements in content type part */ diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java index 3652b89b1..08022e976 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java @@ -304,13 +304,13 @@ implements XSLFShapeContainer, GroupShape { @Override public boolean getFlipHorizontal(){ CTGroupTransform2D xfrm = getXfrm(); - return (xfrm == null || !xfrm.isSetFlipH()) ? false : xfrm.getFlipH(); + return !(xfrm == null || !xfrm.isSetFlipH()) && xfrm.getFlipH(); } @Override public boolean getFlipVertical(){ CTGroupTransform2D xfrm = getXfrm(); - return (xfrm == null || !xfrm.isSetFlipV()) ? false : xfrm.getFlipV(); + return !(xfrm == null || !xfrm.isSetFlipV()) && xfrm.getFlipV(); } @Override @@ -333,7 +333,7 @@ implements XSLFShapeContainer, GroupShape { // recursively update each shape for(XSLFShape shape : gr.getShapes()) { - XSLFShape newShape = null; + XSLFShape newShape; if (shape instanceof XSLFTextBox) { newShape = createTextBox(); } else if (shape instanceof XSLFAutoShape) { 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 abba81430..2277d600a 100644 --- a/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java +++ b/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java @@ -41,7 +41,6 @@ import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.util.DocumentHelper; @@ -55,7 +54,6 @@ import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFTable; import org.apache.poi.xssf.usermodel.helpers.XSSFSingleXmlCell; import org.apache.poi.xssf.usermodel.helpers.XSSFXmlColumnPr; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STXmlDataType; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; @@ -117,8 +115,7 @@ public class XSSFExportToXml implements Comparator{ * @param validate if true, validates the XML againts the XML Schema * @throws SAXException * @throws ParserConfigurationException - * @throws TransformerException - * @throws InvalidFormatException + * @throws TransformerException */ public void exportToXML(OutputStream os, String encoding, boolean validate) throws SAXException, ParserConfigurationException, TransformerException{ List singleXMLCells = map.getRelatedSingleXMLCell(); @@ -128,10 +125,10 @@ public class XSSFExportToXml implements Comparator{ Document doc = DocumentHelper.createDocument(); - Element root = null; + final Element root; if (isNamespaceDeclared()) { - root=doc.createElementNS(getNamespace(),rootElement); + root = doc.createElementNS(getNamespace(),rootElement); } else { root = doc.createElementNS("", rootElement); } @@ -152,7 +149,6 @@ public class XSSFExportToXml implements Comparator{ tableMappings.put(commonXPath, table); } - Collections.sort(xpaths,this); for(String xpath : xpaths) { @@ -167,8 +163,7 @@ public class XSSFExportToXml implements Comparator{ XSSFCell cell = simpleXmlCell.getReferencedCell(); if (cell!=null) { Node currentNode = getNodeByXPath(xpath,doc.getFirstChild(),doc,false); - STXmlDataType.Enum dataType = simpleXmlCell.getXmlDataType(); - mapCellOnNode(cell,currentNode,dataType); + mapCellOnNode(cell,currentNode); //remove nodes which are empty in order to keep the output xml valid if("".equals(currentNode.getTextContent()) && currentNode.getParentNode() != null) { @@ -202,22 +197,15 @@ public class XSSFExportToXml implements Comparator{ XSSFXmlColumnPr pointer = tableColumns.get(j-startColumnIndex); String localXPath = pointer.getLocalXPath(); Node currentNode = getNodeByXPath(localXPath,tableRootNode,doc,false); - STXmlDataType.Enum dataType = pointer.getXmlDataType(); - - mapCellOnNode(cell,currentNode,dataType); + mapCellOnNode(cell,currentNode); } - } - } - - - } - } else { + } /*else { // TODO: implement filtering management in xpath - } + }*/ } boolean isValid = true; @@ -225,8 +213,6 @@ public class XSSFExportToXml implements Comparator{ isValid =isValid(doc); } - - if (isValid) { ///////////////// @@ -275,7 +261,7 @@ public class XSSFExportToXml implements Comparator{ } - private void mapCellOnNode(XSSFCell cell, Node node, STXmlDataType.Enum outputDataType) { + private void mapCellOnNode(XSSFCell cell, Node node) { String value =""; switch (cell.getCellTypeEnum()) { @@ -349,11 +335,7 @@ public class XSSFExportToXml implements Comparator{ } currentNode = selectedNode; } else { - - - Node attribute = createAttribute(doc, currentNode, axisName); - - currentNode = attribute; + currentNode = createAttribute(doc, currentNode, axisName); } } return currentNode; @@ -421,12 +403,11 @@ public class XSSFExportToXml implements Comparator{ for(int i =1;i { }if ( leftIndex > rightIndex) { return 1; } - } else { + } /*else { // NOTE: the xpath doesn't match correctly in the schema - } + }*/ } } @@ -483,7 +464,7 @@ public class XSSFExportToXml implements Comparator{ // Note: we expect that all the complex types are defined at root level Node complexTypeNode = null; if (!"".equals(complexTypeName)) { - complexTypeNode = getComplexTypeNodeFromSchemaChildren(xmlSchema, complexTypeNode, complexTypeName); + complexTypeNode = getComplexTypeNodeFromSchemaChildren(xmlSchema, null, complexTypeName); } return complexTypeNode; 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 e6994b8de..6174af54b 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java @@ -994,6 +994,7 @@ public class SXSSFCell implements Cell { ((FormulaValue)_value)._value = ((FormulaValue)prevValue)._value; } } + //TODO: implement this correctly @NotImplemented /*package*/ CellType computeTypeFromFormula(String formula) diff --git a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/internal/TestContentTypeManager.java b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/internal/TestContentTypeManager.java index 9acf0d10b..936d0f9e8 100644 --- a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/internal/TestContentTypeManager.java +++ b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/internal/TestContentTypeManager.java @@ -18,6 +18,7 @@ package org.apache.poi.openxml4j.opc.internal; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; @@ -44,16 +45,21 @@ public final class TestContentTypeManager { // Retrieves core properties part OPCPackage p = OPCPackage.open(filepath, PackageAccess.READ); - PackageRelationshipCollection rels = p.getRelationshipsByType(PackageRelationshipTypes.CORE_PROPERTIES); - PackageRelationship corePropertiesRelationship = rels.getRelationship(0); - PackagePart coreDocument = p.getPart(corePropertiesRelationship); - - assertEquals("application/vnd.openxmlformats-package.core-properties+xml", coreDocument.getContentType()); + try { + PackageRelationshipCollection rels = p.getRelationshipsByType(PackageRelationshipTypes.CORE_PROPERTIES); + PackageRelationship corePropertiesRelationship = rels.getRelationship(0); + PackagePart coreDocument = p.getPart(corePropertiesRelationship); - // TODO - finish writing this test - assumeTrue("finish writing this test", false); - - ContentTypeManager ctm = new ZipContentTypeManager(coreDocument.getInputStream(), p); + assertEquals("application/vnd.openxmlformats-package.core-properties+xml", coreDocument.getContentType()); + + // TODO - finish writing this test + assumeTrue("finish writing this test", false); + + ContentTypeManager ctm = new ZipContentTypeManager(coreDocument.getInputStream(), p); + assertNotNull(ctm); + } finally { + p.close(); + } } /** diff --git a/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShow.java b/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShow.java index 404e0da07..e02260844 100644 --- a/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShow.java +++ b/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShow.java @@ -50,14 +50,20 @@ public abstract class BaseTestSlideShow { @Test public void addPicture_Stream() throws IOException { SlideShow show = createSlideShow(); - InputStream stream = slTests.openResourceAsStream("clock.jpg"); - - assertEquals(0, show.getPictureData().size()); - PictureData picture = show.addPicture(stream, PictureType.JPEG); - assertEquals(1, show.getPictureData().size()); - assertSame(picture, show.getPictureData().get(0)); - - show.close(); + try { + InputStream stream = slTests.openResourceAsStream("clock.jpg"); + try { + assertEquals(0, show.getPictureData().size()); + PictureData picture = show.addPicture(stream, PictureType.JPEG); + assertEquals(1, show.getPictureData().size()); + assertSame(picture, show.getPictureData().get(0)); + + } finally { + stream.close(); + } + } finally { + show.close(); + } } @Test diff --git a/src/testcases/org/apache/poi/ss/util/BaseTestCellUtil.java b/src/testcases/org/apache/poi/ss/util/BaseTestCellUtil.java index ed0c1da7e..a63ce5a60 100644 --- a/src/testcases/org/apache/poi/ss/util/BaseTestCellUtil.java +++ b/src/testcases/org/apache/poi/ss/util/BaseTestCellUtil.java @@ -78,14 +78,16 @@ public class BaseTestCellUtil { @Test(expected=RuntimeException.class) public void setCellStylePropertyWithInvalidValue() throws IOException { Workbook wb = _testDataProvider.createWorkbook(); - Sheet s = wb.createSheet(); - Row r = s.createRow(0); - Cell c = r.createCell(0); + try { + Sheet s = wb.createSheet(); + Row r = s.createRow(0); + Cell c = r.createCell(0); - // An invalid BorderStyle constant - CellUtil.setCellStyleProperty(c, CellUtil.BORDER_BOTTOM, 42); - - wb.close(); + // An invalid BorderStyle constant + CellUtil.setCellStyleProperty(c, CellUtil.BORDER_BOTTOM, 42); + } finally { + wb.close(); + } } @Test() @@ -352,10 +354,8 @@ public class BaseTestCellUtil { CellUtil.setFont(A1, font2); fail("setFont not allowed if font belongs to a different workbook"); } catch (final IllegalArgumentException e) { - if (e.getMessage().startsWith("Font does not belong to this workbook")) { - // expected - } - else { + // one specific message is expected + if (!e.getMessage().startsWith("Font does not belong to this workbook")) { throw e; } } finally { @@ -371,7 +371,7 @@ public class BaseTestCellUtil { */ // bug 55555 @Test - public void setFillForegroundColorBeforeFillBackgroundColor() { + public void setFillForegroundColorBeforeFillBackgroundColor() throws IOException { Workbook wb1 = _testDataProvider.createWorkbook(); Cell A1 = wb1.createSheet().createRow(0).createCell(0); Map properties = new HashMap(); @@ -386,13 +386,14 @@ public class BaseTestCellUtil { assertEquals("fill pattern", CellStyle.BRICKS, style.getFillPattern()); assertEquals("fill foreground color", IndexedColors.BLUE, IndexedColors.fromInt(style.getFillForegroundColor())); assertEquals("fill background color", IndexedColors.RED, IndexedColors.fromInt(style.getFillBackgroundColor())); + wb1.close(); } /** * bug 55555 * @since POI 3.15 beta 3 */ @Test - public void setFillForegroundColorBeforeFillBackgroundColorEnum() { + public void setFillForegroundColorBeforeFillBackgroundColorEnum() throws IOException { Workbook wb1 = _testDataProvider.createWorkbook(); Cell A1 = wb1.createSheet().createRow(0).createCell(0); Map properties = new HashMap(); @@ -407,5 +408,7 @@ public class BaseTestCellUtil { assertEquals("fill pattern", FillPatternType.BRICKS, style.getFillPatternEnum()); assertEquals("fill foreground color", IndexedColors.BLUE, IndexedColors.fromInt(style.getFillForegroundColor())); assertEquals("fill background color", IndexedColors.RED, IndexedColors.fromInt(style.getFillBackgroundColor())); + + wb1.close(); } } From bbfb783a57e7a244ec81f0c9734c85355823b263 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Sun, 31 Jul 2016 17:19:27 +0000 Subject: [PATCH 011/157] Bug 59736: Incorrect evaluation of SUBTOTAL with composite interval git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754674 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/ss/formula/LazyRefEval.java | 19 ++-- .../poi/ss/formula/functions/Subtotal.java | 30 +++++- .../usermodel/TestXSSFFormulaEvaluation.java | 24 ++++- .../ss/formula/functions/TestSubtotal.java | 97 ++++++++++++++++-- test-data/spreadsheet/59736.xlsx | Bin 0 -> 8752 bytes 5 files changed, 148 insertions(+), 22 deletions(-) create mode 100644 test-data/spreadsheet/59736.xlsx diff --git a/src/java/org/apache/poi/ss/formula/LazyRefEval.java b/src/java/org/apache/poi/ss/formula/LazyRefEval.java index e0b5e19f9..c71b0e977 100644 --- a/src/java/org/apache/poi/ss/formula/LazyRefEval.java +++ b/src/java/org/apache/poi/ss/formula/LazyRefEval.java @@ -27,7 +27,7 @@ import org.apache.poi.ss.util.CellReference; /** * Provides Lazy Evaluation to a 3D Reference */ -final class LazyRefEval extends RefEvalBase { +public final class LazyRefEval extends RefEvalBase { private final SheetRangeEvaluator _evaluator; public LazyRefEval(int rowIndex, int columnIndex, SheetRangeEvaluator sre) { @@ -47,14 +47,17 @@ final class LazyRefEval extends RefEvalBase { return new LazyAreaEval(area, _evaluator); } + public boolean isSubTotal() { + SheetRefEvaluator sheetEvaluator = _evaluator.getSheetEvaluator(getFirstSheetIndex()); + return sheetEvaluator.isSubTotal(getRow(), getColumn()); + } + public String toString() { CellReference cr = new CellReference(getRow(), getColumn()); - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getName()).append("["); - sb.append(_evaluator.getSheetNameRange()); - sb.append('!'); - sb.append(cr.formatAsString()); - sb.append("]"); - return sb.toString(); + return getClass().getName() + "[" + + _evaluator.getSheetNameRange() + + '!' + + cr.formatAsString() + + "]"; } } diff --git a/src/java/org/apache/poi/ss/formula/functions/Subtotal.java b/src/java/org/apache/poi/ss/formula/functions/Subtotal.java index fca55c502..f3b24cd1c 100644 --- a/src/java/org/apache/poi/ss/formula/functions/Subtotal.java +++ b/src/java/org/apache/poi/ss/formula/functions/Subtotal.java @@ -19,6 +19,7 @@ package org.apache.poi.ss.formula.functions; import static org.apache.poi.ss.formula.functions.AggregateFunction.subtotalInstance; +import org.apache.poi.ss.formula.LazyRefEval; import org.apache.poi.ss.formula.eval.ErrorEval; import org.apache.poi.ss.formula.eval.EvaluationException; import org.apache.poi.ss.formula.eval.NotImplementedException; @@ -26,6 +27,11 @@ import org.apache.poi.ss.formula.eval.NotImplementedFunctionException; import org.apache.poi.ss.formula.eval.OperandResolver; import org.apache.poi.ss.formula.eval.ValueEval; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + /** * Implementation for the Excel function SUBTOTAL

* @@ -61,7 +67,6 @@ import org.apache.poi.ss.formula.eval.ValueEval; public class Subtotal implements Function { private static Function findFunction(int functionCode) throws EvaluationException { - Function func; switch (functionCode) { case 1: return subtotalInstance(AggregateFunction.AVERAGE); case 2: return Count.subtotalInstance(); @@ -87,7 +92,7 @@ public class Subtotal implements Function { return ErrorEval.VALUE_INVALID; } - Function innerFunc; + final Function innerFunc; try { ValueEval ve = OperandResolver.getSingleValue(args[0], srcRowIndex, srcColumnIndex); int functionCode = OperandResolver.coerceValueToInt(ve); @@ -96,9 +101,24 @@ public class Subtotal implements Function { return e.getErrorEval(); } - ValueEval[] innerArgs = new ValueEval[nInnerArgs]; - System.arraycopy(args, 1, innerArgs, 0, nInnerArgs); + // ignore the first arg, this is the function-type, we check for the length above + final List list = new ArrayList(Arrays.asList(args).subList(1, args.length)); - return innerFunc.evaluate(innerArgs, srcRowIndex, srcColumnIndex); + Iterator it = list.iterator(); + + // See https://support.office.com/en-us/article/SUBTOTAL-function-7b027003-f060-4ade-9040-e478765b9939 + // "If there are other subtotals within ref1, ref2,... (or nested subtotals), these nested subtotals are ignored to avoid double counting." + // For array references it is handled in other evaluation steps, but we need to handle this here for references to subtotal-functions + while(it.hasNext()) { + ValueEval eval = it.next(); + if(eval instanceof LazyRefEval) { + LazyRefEval lazyRefEval = (LazyRefEval) eval; + if(lazyRefEval.isSubTotal()) { + it.remove(); + } + } + } + + return innerFunc.evaluate(list.toArray(new ValueEval[list.size()]), srcRowIndex, srcColumnIndex); } } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java index 566944d18..9885fd886 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java @@ -154,7 +154,9 @@ public final class TestXSSFFormulaEvaluation extends BaseTestFormulaEvaluator { evaluator.evaluate(cXSL_cell); fail("Without a fix for #56752, shouldn't be able to evaluate a " + "reference to a non-provided linked workbook"); - } catch(Exception e) {} + } catch(Exception e) { + // expected here + } // Setup the environment Map evaluators = new HashMap(); @@ -196,7 +198,9 @@ public final class TestXSSFFormulaEvaluation extends BaseTestFormulaEvaluator { try { cXSLX_nw_cell.setCellFormula("[alt.xlsx]Sheet1!$A$1"); fail("New workbook not linked, shouldn't be able to add"); - } catch (Exception e) {} + } catch (Exception e) { + // expected here + } // Link and re-try Workbook alt = new XSSFWorkbook(); @@ -651,4 +655,20 @@ public final class TestXSSFFormulaEvaluation extends BaseTestFormulaEvaluator { private Cell getCell(Sheet sheet, int rowNo, int column) { return sheet.getRow(rowNo).getCell(column); } + + @Test + public void test59736() { + Workbook wb = XSSFTestDataSamples.openSampleWorkbook("59736.xlsx"); + FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); + Cell cell = wb.getSheetAt(0).getRow(0).getCell(0); + assertEquals(1, cell.getNumericCellValue(), 0.001); + + cell = wb.getSheetAt(0).getRow(1).getCell(0); + CellValue value = evaluator.evaluate(cell); + assertEquals(1, value.getNumberValue(), 0.001); + + cell = wb.getSheetAt(0).getRow(2).getCell(0); + value = evaluator.evaluate(cell); + assertEquals(1, value.getNumberValue(), 0.001); + } } diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestSubtotal.java b/src/testcases/org/apache/poi/ss/formula/functions/TestSubtotal.java index 7b63eaf79..f2750b591 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestSubtotal.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestSubtotal.java @@ -20,9 +20,8 @@ package org.apache.poi.ss.formula.functions; import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.formula.eval.AreaEval; -import org.apache.poi.ss.formula.eval.NumberEval; -import org.apache.poi.ss.formula.eval.ValueEval; +import org.apache.poi.ss.formula.FormulaParseException; +import org.apache.poi.ss.formula.eval.*; import junit.framework.TestCase; import org.apache.poi.ss.usermodel.*; @@ -75,7 +74,6 @@ public final class TestSubtotal extends TestCase { } public void testAvg(){ - Workbook wb = new HSSFWorkbook(); FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator(); @@ -95,16 +93,18 @@ public final class TestSubtotal extends TestCase { a6.setCellFormula("SUBTOTAL(1,B2:B6)*2 + 2"); Cell a7 = sh.createRow(7).createCell(1); a7.setCellFormula("SUBTOTAL(1,B2:B7)"); + Cell a8 = sh.createRow(8).createCell(1); + a8.setCellFormula("SUBTOTAL(1,B2,B3,B4,B5,B6,B7,B8)"); fe.evaluateAll(); assertEquals(2.0, a3.getNumericCellValue()); assertEquals(8.0, a6.getNumericCellValue()); assertEquals(3.0, a7.getNumericCellValue()); + assertEquals(3.0, a8.getNumericCellValue()); } public void testSum(){ - Workbook wb = new HSSFWorkbook(); FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator(); @@ -124,12 +124,15 @@ public final class TestSubtotal extends TestCase { a6.setCellFormula("SUBTOTAL(9,B2:B6)*2 + 2"); Cell a7 = sh.createRow(7).createCell(1); a7.setCellFormula("SUBTOTAL(9,B2:B7)"); + Cell a8 = sh.createRow(8).createCell(1); + a8.setCellFormula("SUBTOTAL(9,B2,B3,B4,B5,B6,B7,B8)"); fe.evaluateAll(); assertEquals(4.0, a3.getNumericCellValue()); assertEquals(26.0, a6.getNumericCellValue()); assertEquals(12.0, a7.getNumericCellValue()); + assertEquals(12.0, a8.getNumericCellValue()); } public void testCount(){ @@ -147,18 +150,21 @@ public final class TestSubtotal extends TestCase { a3.setCellFormula("SUBTOTAL(2,B2:B3)"); Cell a4 = sh.createRow(4).createCell(1); a4.setCellValue("POI"); // A4 is string and not counted - Cell a5 = sh.createRow(5).createCell(1); // A5 is blank and not counted + /*Cell a5 =*/ sh.createRow(5).createCell(1); // A5 is blank and not counted Cell a6 = sh.createRow(6).createCell(1); a6.setCellFormula("SUBTOTAL(2,B2:B6)*2 + 2"); Cell a7 = sh.createRow(7).createCell(1); a7.setCellFormula("SUBTOTAL(2,B2:B7)"); + Cell a8 = sh.createRow(8).createCell(1); + a8.setCellFormula("SUBTOTAL(2,B2,B3,B4,B5,B6,B7,B8)"); fe.evaluateAll(); assertEquals(2.0, a3.getNumericCellValue()); assertEquals(6.0, a6.getNumericCellValue()); assertEquals(2.0, a7.getNumericCellValue()); + assertEquals(2.0, a8.getNumericCellValue()); } public void testCounta(){ @@ -176,18 +182,21 @@ public final class TestSubtotal extends TestCase { a3.setCellFormula("SUBTOTAL(3,B2:B3)"); Cell a4 = sh.createRow(4).createCell(1); a4.setCellValue("POI"); // A4 is string and not counted - Cell a5 = sh.createRow(5).createCell(1); // A5 is blank and not counted + /*Cell a5 =*/ sh.createRow(5).createCell(1); // A5 is blank and not counted Cell a6 = sh.createRow(6).createCell(1); a6.setCellFormula("SUBTOTAL(3,B2:B6)*2 + 2"); Cell a7 = sh.createRow(7).createCell(1); a7.setCellFormula("SUBTOTAL(3,B2:B7)"); + Cell a8 = sh.createRow(8).createCell(1); + a8.setCellFormula("SUBTOTAL(3,B2,B3,B4,B5,B6,B7,B8)"); fe.evaluateAll(); assertEquals(2.0, a3.getNumericCellValue()); assertEquals(8.0, a6.getNumericCellValue()); assertEquals(3.0, a7.getNumericCellValue()); + assertEquals(3.0, a8.getNumericCellValue()); } public void testMax(){ @@ -211,12 +220,15 @@ public final class TestSubtotal extends TestCase { a6.setCellFormula("SUBTOTAL(4,B2:B6)*2 + 2"); Cell a7 = sh.createRow(7).createCell(1); a7.setCellFormula("SUBTOTAL(4,B2:B7)"); + Cell a8 = sh.createRow(8).createCell(1); + a8.setCellFormula("SUBTOTAL(4,B2,B3,B4,B5,B6,B7,B8)"); fe.evaluateAll(); assertEquals(3.0, a3.getNumericCellValue()); assertEquals(16.0, a6.getNumericCellValue()); assertEquals(7.0, a7.getNumericCellValue()); + assertEquals(7.0, a8.getNumericCellValue()); } public void testMin(){ @@ -240,12 +252,15 @@ public final class TestSubtotal extends TestCase { a6.setCellFormula("SUBTOTAL(5,B2:B6)*2 + 2"); Cell a7 = sh.createRow(7).createCell(1); a7.setCellFormula("SUBTOTAL(5,B2:B7)"); + Cell a8 = sh.createRow(8).createCell(1); + a8.setCellFormula("SUBTOTAL(5,B2,B3,B4,B5,B6,B7,B8)"); fe.evaluateAll(); assertEquals(1.0, a3.getNumericCellValue()); assertEquals(4.0, a6.getNumericCellValue()); assertEquals(1.0, a7.getNumericCellValue()); + assertEquals(1.0, a8.getNumericCellValue()); } public void testStdev(){ @@ -269,12 +284,15 @@ public final class TestSubtotal extends TestCase { a6.setCellFormula("SUBTOTAL(7,B2:B6)*2 + 2"); Cell a7 = sh.createRow(7).createCell(1); a7.setCellFormula("SUBTOTAL(7,B2:B7)"); + Cell a8 = sh.createRow(8).createCell(1); + a8.setCellFormula("SUBTOTAL(7,B2,B3,B4,B5,B6,B7,B8)"); fe.evaluateAll(); assertEquals(1.41421, a3.getNumericCellValue(), 0.0001); assertEquals(7.65685, a6.getNumericCellValue(), 0.0001); assertEquals(2.82842, a7.getNumericCellValue(), 0.0001); + assertEquals(2.82842, a8.getNumericCellValue(), 0.0001); } public void test50209(){ @@ -328,4 +346,69 @@ public final class TestSubtotal extends TestCase { confirmExpectedResult(evaluator, "SUBTOTAL(COUNT;B2:B8,C2:C8)", cellC2, 3.0); confirmExpectedResult(evaluator, "SUBTOTAL(COUNTA;B2:B8,C2:C8)", cellC3, 5.0); } + + public void testUnimplemented(){ + Workbook wb = new HSSFWorkbook(); + + FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator(); + + Sheet sh = wb.createSheet(); + Cell a3 = sh.createRow(3).createCell(1); + a3.setCellFormula("SUBTOTAL(8,B2:B3)"); + + try { + fe.evaluateAll(); + fail("Should catch an NotImplementedFunctionException here, adjust these tests if it was actually implemented"); + } catch (NotImplementedException e) { + // expected here + } + + a3.setCellFormula("SUBTOTAL(10,B2:B3)"); + + try { + fe.evaluateAll(); + fail("Should catch an NotImplementedFunctionException here, adjust these tests if it was actually implemented"); + } catch (NotImplementedException e) { + // expected here + } + + a3.setCellFormula("SUBTOTAL(11,B2:B3)"); + + try { + fe.evaluateAll(); + fail("Should catch an NotImplementedFunctionException here, adjust these tests if it was actually implemented"); + } catch (NotImplementedException e) { + // expected here + } + + a3.setCellFormula("SUBTOTAL(107,B2:B3)"); + + try { + fe.evaluateAll(); + fail("Should catch an NotImplementedFunctionException here, adjust these tests if it was actually implemented"); + } catch (NotImplementedException e) { + // expected here + } + + a3.setCellFormula("SUBTOTAL(0,B2:B3)"); + fe.evaluateAll(); + assertEquals(FormulaError.VALUE.getCode(), a3.getErrorCellValue()); + + try { + a3.setCellFormula("SUBTOTAL(9)"); + fail("Should catch an exception here"); + } catch (FormulaParseException e) { + // expected here + } + + try { + a3.setCellFormula("SUBTOTAL()"); + fail("Should catch an exception here"); + } catch (FormulaParseException e) { + // expected here + } + + Subtotal subtotal = new Subtotal(); + assertEquals(ErrorEval.VALUE_INVALID, subtotal.evaluate(new ValueEval[] {}, 0, 0)); + } } diff --git a/test-data/spreadsheet/59736.xlsx b/test-data/spreadsheet/59736.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..1f29d54c502aa92dc8b17300df3f4dd455a23320 GIT binary patch literal 8752 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 literal 0 HcmV?d00001 From 98401573ed261b21055462a183d85712d96939e4 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Sun, 31 Jul 2016 17:19:33 +0000 Subject: [PATCH 012/157] Test a few more cases of function INDIRECT() git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754675 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/ss/formula/functions/TestIndirect.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestIndirect.java b/src/testcases/org/apache/poi/ss/formula/functions/TestIndirect.java index 8e93152c8..ea5ac9c7a 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestIndirect.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestIndirect.java @@ -27,6 +27,7 @@ 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.ErrorEval; +import org.apache.poi.ss.formula.eval.ValueEval; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.CellValue; @@ -105,6 +106,7 @@ public final class TestIndirect { // non-error cases confirm(feA, c, "INDIRECT(\"C2\")", 23); + confirm(feA, c, "INDIRECT(\"C2\", TRUE)", 23); confirm(feA, c, "INDIRECT(\"$C2\")", 23); confirm(feA, c, "INDIRECT(\"C$2\")", 23); confirm(feA, c, "SUM(INDIRECT(\"Sheet2!B1:C3\"))", 351); // area ref @@ -149,7 +151,7 @@ public final class TestIndirect { // confirm(feA, c, "INDIRECT(\"Sheet1!A65537\")", ErrorEval.REF_INVALID); // bad row // } confirm(feA, c, "INDIRECT(\"Sheet1!A 1\")", ErrorEval.REF_INVALID); // space in cell ref - + wbA.close(); } @@ -203,4 +205,9 @@ public final class TestIndirect { + "' but got '" + cv.formatAsString() + "'."); } } + + @Test + public void testInvalidInput() { + assertEquals(ErrorEval.VALUE_INVALID, Indirect.instance.evaluate(new ValueEval[] {}, null)); + } } From ced44cffa8527fb7fa0a73c38bccb4f875ac0459 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Sun, 31 Jul 2016 17:19:37 +0000 Subject: [PATCH 013/157] Exclude package sl.draw.binding from coverage-counting as this is generated code git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754676 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.xml b/build.xml index beab59292..b72890224 100644 --- a/build.xml +++ b/build.xml @@ -1166,6 +1166,8 @@ under the License. + + From d01736974e5a44f2e13278a5e5365242f1e3e2fc Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Sun, 31 Jul 2016 21:23:25 +0000 Subject: [PATCH 014/157] Allow to specify -addmods for Java 9 support, update to JaCoCo 0.7.7 for initial Java 9 support and add target to create a combined JUnit report Conflicts: build.xml git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754687 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/build.xml b/build.xml index b72890224..2fcb654ac 100644 --- a/build.xml +++ b/build.xml @@ -196,8 +196,8 @@ under the License. value="${repository.m2}/maven2/org/apache/xmlbeans/xmlbeans/2.6.0/xmlbeans-2.6.0.jar"/> - - + + @@ -307,6 +307,8 @@ under the License. + + @@ -534,12 +536,14 @@ under the License. + + @@ -1249,6 +1253,8 @@ under the License. + + @@ -1265,6 +1271,16 @@ under the License. + + + + + + + + + + @@ -1295,6 +1311,8 @@ under the License. + + @@ -1342,6 +1360,8 @@ under the License. and on Windows with jdk-1.5.22 --> + + @@ -1380,6 +1400,8 @@ under the License. + + @@ -1403,6 +1425,8 @@ under the License. + + @@ -1446,6 +1470,8 @@ under the License. + + @@ -1492,6 +1518,8 @@ under the License. + + @@ -1542,6 +1570,8 @@ under the License. + + @@ -1579,6 +1609,8 @@ under the License. + + From 2175d4dd7a10805824efebe20b563ef8546db68a Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Sun, 31 Jul 2016 21:23:34 +0000 Subject: [PATCH 015/157] Fix download-location of commons-logging4 jar and add it to FindBugs and bin-files target correctly Add ant-jar to findbugs target as it is needed for excelant-code-check now Fail on error when running Findbugs (still not on found warnings!) git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754688 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/build.xml b/build.xml index 2fcb654ac..293167090 100644 --- a/build.xml +++ b/build.xml @@ -170,7 +170,7 @@ under the License. - + @@ -1922,13 +1922,14 @@ under the License. + - + @@ -2157,6 +2158,7 @@ under the License. output="xml:withMessages" outputFile="build/findbugs.xml" effort="max" + failOnError="true" excludeFilter="src/resources/devtools/findbugs-filters.xml"> @@ -2171,11 +2173,12 @@ under the License. - + + From b23e85c852b7b67141a6e9bc0f3022cd15af8332 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Sun, 31 Jul 2016 21:24:13 +0000 Subject: [PATCH 016/157] Add coverage of function WEEKDAY git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754689 13f79535-47bb-0310-9956-ffa450edef68 --- .../ss/formula/functions/WeekdayFuncTest.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/testcases/org/apache/poi/ss/formula/functions/WeekdayFuncTest.java diff --git a/src/testcases/org/apache/poi/ss/formula/functions/WeekdayFuncTest.java b/src/testcases/org/apache/poi/ss/formula/functions/WeekdayFuncTest.java new file mode 100644 index 000000000..3e0df8ce4 --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/functions/WeekdayFuncTest.java @@ -0,0 +1,54 @@ +package org.apache.poi.ss.formula.functions; + +import org.apache.poi.ss.formula.eval.*; +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class WeekdayFuncTest { + /** + * der 1. Januar 2008 die fortlaufende Zahl 39.448, da dieser Tag nach 39.448 Tagen + * auf den 01.01.1900 folgt. + */ + + @Test + public void testEvaluate() throws Exception { + assertEquals(2.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(1.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(2.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(1.0), new NumberEval(1.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(1.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(1.0), new NumberEval(2.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(0.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(1.0), new NumberEval(3.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(1.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(1.0), new NumberEval(11.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(7.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(1.0), new NumberEval(12.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(6.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(1.0), new NumberEval(13.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(5.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(1.0), new NumberEval(14.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(4.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(1.0), new NumberEval(15.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(3.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(1.0), new NumberEval(16.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(2.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(1.0), new NumberEval(17.0)}, 0, 0)).getNumberValue(), 0.001); + + assertEquals(3.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(39448.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(3.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(39448.0), new NumberEval(1.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(2.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(39448.0), new NumberEval(2.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(1.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(39448.0), new NumberEval(3.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(2.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(39448.0), new NumberEval(11.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(1.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(39448.0), new NumberEval(12.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(7.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(39448.0), new NumberEval(13.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(6.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(39448.0), new NumberEval(14.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(5.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(39448.0), new NumberEval(15.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(4.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(39448.0), new NumberEval(16.0)}, 0, 0)).getNumberValue(), 0.001); + assertEquals(3.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(39448.0), new NumberEval(17.0)}, 0, 0)).getNumberValue(), 0.001); + } + + @Test + public void testEvaluateInvalid() throws Exception { + assertEquals(ErrorEval.VALUE_INVALID, WeekdayFunc.instance.evaluate(new ValueEval[]{}, 0, 0)); + assertEquals(ErrorEval.VALUE_INVALID, WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(1.0), new NumberEval(1.0), new NumberEval(1.0)}, 0, 0)); + + assertEquals(ErrorEval.NUM_ERROR, WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(-1.0)}, 0, 0)); + assertEquals(ErrorEval.VALUE_INVALID, WeekdayFunc.instance.evaluate(new ValueEval[]{new StringEval("")}, 0, 0)); + assertEquals(ErrorEval.VALUE_INVALID, WeekdayFunc.instance.evaluate(new ValueEval[]{new StringEval("1"), new StringEval("")}, 0, 0)); + assertEquals(ErrorEval.NUM_ERROR, WeekdayFunc.instance.evaluate(new ValueEval[]{new StringEval("2"), BlankEval.instance}, 0, 0)); + assertEquals(ErrorEval.NUM_ERROR, WeekdayFunc.instance.evaluate(new ValueEval[]{new StringEval("3"), MissingArgEval.instance}, 0, 0)); + assertEquals(ErrorEval.NUM_ERROR, WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(1.0), new NumberEval(18.0)}, 0, 0)); + } +} \ No newline at end of file From 504a26b844e0f51a1a9d42b502d83f1d8278270b Mon Sep 17 00:00:00 2001 From: Mark Murphy Date: Sun, 31 Jul 2016 23:59:02 +0000 Subject: [PATCH 017/157] Add new class Cell Style Template and supporting enum for drawing borders git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754691 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/ss/examples/DrawingBorders.java | 112 +++ .../org/apache/poi/ss/util/BorderExtent.java | 85 ++ .../org/apache/poi/ss/util/CellAddress.java | 9 + .../apache/poi/ss/util/CellStyleTemplate.java | 951 ++++++++++++++++++ .../poi/ss/util/TestCellStyleTemplate.java | 892 ++++++++++++++++ 5 files changed, 2049 insertions(+) create mode 100644 src/examples/src/org/apache/poi/ss/examples/DrawingBorders.java create mode 100644 src/java/org/apache/poi/ss/util/BorderExtent.java create mode 100644 src/java/org/apache/poi/ss/util/CellStyleTemplate.java create mode 100644 src/testcases/org/apache/poi/ss/util/TestCellStyleTemplate.java diff --git a/src/examples/src/org/apache/poi/ss/examples/DrawingBorders.java b/src/examples/src/org/apache/poi/ss/examples/DrawingBorders.java new file mode 100644 index 000000000..d8b0927f7 --- /dev/null +++ b/src/examples/src/org/apache/poi/ss/examples/DrawingBorders.java @@ -0,0 +1,112 @@ +/* + * ==================================================================== + * 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.ss.examples; + +import java.io.FileOutputStream; +import java.io.IOException; + +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.IndexedColors; +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.BorderExtent; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellStyleTemplate; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +/** + * Excel Border Drawing - examples + * + *

+ * Partly based on the code snippets from + * org.apache.poi.ss.examples.ConditionalFormats + *

+ */ +public class DrawingBorders { + + public static void main(String[] args) throws IOException { + Workbook wb; + + if (args.length > 0 && args[0].equals("-xls")) { + wb = new HSSFWorkbook(); + } else { + wb = new XSSFWorkbook(); + } + + // add a sheet, and put some values into it + Sheet sh1 = wb.createSheet("Sheet1"); + Row r = sh1.createRow(0); + Cell c = r.createCell(1); + c.setCellValue("All Borders Medium Width"); + r = sh1.createRow(4); + c = r.createCell(1); + c.setCellValue("Medium Outside / Thin Inside Borders"); + r = sh1.createRow(8); + c = r.createCell(1); + c.setCellValue("Colored Borders"); + + // draw borders (three 3x3 grids) + CellStyleTemplate cst = new CellStyleTemplate(); + // #1) these borders will all be medium in default color + cst.drawBorders(CellRangeAddress.valueOf("B2:D5"), + BorderStyle.MEDIUM, BorderExtent.ALL); + // #2) these cells will have medium outside borders and thin inside borders + cst.drawBorders(CellRangeAddress.valueOf("E2:G5"), + BorderStyle.MEDIUM, BorderExtent.OUTSIDE); + cst.drawBorders(CellRangeAddress.valueOf("E2:G5"), + BorderStyle.THIN, BorderExtent.INSIDE); + // #3) these cells will all be medium weight with different colors for the + // outside, inside horizontal, and inside vertical borders. The center + // cell will have no borders. + cst.drawBorders(CellRangeAddress.valueOf("I2:K5"), + BorderStyle.MEDIUM, IndexedColors.RED.getIndex(), + BorderExtent.OUTSIDE); + cst.drawBorders(CellRangeAddress.valueOf("I2:K5"), + BorderStyle.MEDIUM, IndexedColors.BLUE.getIndex(), + BorderExtent.INSIDE_VERTICAL); + cst.drawBorders(CellRangeAddress.valueOf("I2:K5"), + BorderStyle.MEDIUM, IndexedColors.GREEN.getIndex(), + BorderExtent.INSIDE_HORIZONTAL); + cst.drawBorders(CellRangeAddress.valueOf("J3"), + BorderStyle.NONE, + BorderExtent.ALL); + + // apply borders to sheet + cst.applyBorders(sh1); + + // add another sheet and apply the borders to it + Sheet sh2 = wb.createSheet("Sheet2"); + cst.applyBorders(sh2); + + // Write the output to a file + String file = "db-poi.xls"; + if (wb instanceof XSSFWorkbook) + file += "x"; + FileOutputStream out = new FileOutputStream(file); + wb.write(out); + out.close(); + wb.close(); + System.out.println("Generated: " + file); + } + +} diff --git a/src/java/org/apache/poi/ss/util/BorderExtent.java b/src/java/org/apache/poi/ss/util/BorderExtent.java new file mode 100644 index 000000000..d9517b34e --- /dev/null +++ b/src/java/org/apache/poi/ss/util/BorderExtent.java @@ -0,0 +1,85 @@ +package org.apache.poi.ss.util; + +public enum BorderExtent { + /** + * No properties defined. This can be used to remove existing + * properties. + */ + NONE, + + /** + * All borders, that is top, bottom, left and right, including interior + * borders for the range. Does not include diagonals which are different + * and not implemented here. + */ + ALL, + + /** + * All inside borders. This is top, bottom, left, and right borders, but + * restricted to the interior borders for the range. For a range of one + * cell, this will produce no borders. + */ + INSIDE, + + /** + * All outside borders. That is top, bottom, left and right borders that + * bound the range only. + */ + OUTSIDE, + + /** + * This is just the top border for the range. No interior borders will + * be produced. + */ + TOP, + + /** + * This is just the bottom border for the range. No interior borders + * will be produced. + */ + BOTTOM, + + /** + * This is just the left border for the range, no interior borders will + * be produced. + */ + LEFT, + + /** + * This is just the right border for the range, no interior borders will + * be produced. + */ + RIGHT, + + /** + * This is all horizontal borders for the range, including interior and + * outside borders. + */ + HORIZONTAL, + + /** + * This is just the interior horizontal borders for the range. + */ + INSIDE_HORIZONTAL, + + /** + * This is just the outside horizontal borders for the range. + */ + OUTSIDE_HORIZONTAL, + + /** + * This is all vertical borders for the range, including interior and + * outside borders. + */ + VERTICAL, + + /** + * This is just the interior vertical borders for the range. + */ + INSIDE_VERTICAL, + + /** + * This is just the outside vertical borders for the range. + */ + OUTSIDE_VERTICAL +} diff --git a/src/java/org/apache/poi/ss/util/CellAddress.java b/src/java/org/apache/poi/ss/util/CellAddress.java index b6307556f..3014891ab 100644 --- a/src/java/org/apache/poi/ss/util/CellAddress.java +++ b/src/java/org/apache/poi/ss/util/CellAddress.java @@ -96,6 +96,15 @@ public class CellAddress implements Comparable { this(cell.getRowIndex(), cell.getColumnIndex()); } + /** + * Create a new CellAddress object. + * + * @param address a cell address + */ + public CellAddress(CellAddress address) { + this(address._row, address._col); + } + /** * Get the cell address row * diff --git a/src/java/org/apache/poi/ss/util/CellStyleTemplate.java b/src/java/org/apache/poi/ss/util/CellStyleTemplate.java new file mode 100644 index 000000000..e6a7c9c7b --- /dev/null +++ b/src/java/org/apache/poi/ss/util/CellStyleTemplate.java @@ -0,0 +1,951 @@ +/* ==================================================================== + 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.ss.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.SpreadsheetVersion; +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; + +/** + *

+ * A {@link CellStyleTemplate} is a template that can be applied to any sheet in + * a project. It contains all the border type and color attributes needed to + * draw all the borders for a single sheet. That template can be applied to any + * sheet in any workbook. + * + * This class requires the full spreadsheet to be in memory so + * {@link SWorkbook} Spreadsheets are not supported. The same + * {@link CellStyleTemplate} can, however, be applied to both + * {@link org.apache.poi.hssf.usermodel.HSSFWorkbook}, and Workbook objects + * if necessary. Portions of the border that fall outside the max range of the + * {@link HSSFWorkbook} sheet are ignored. + *

+ * + *

+ * This would replace {@link RegionUtil}. + *

+ */ +public final class CellStyleTemplate { + + /** + * This is a list of cell properties for one shot application to a range of + * cells at a later time. + */ + private Map> _cellStyleTemplate; + + /** + * Create a new Cell Style Template + */ + public CellStyleTemplate() { + _cellStyleTemplate = new HashMap>(); + } + + /** + * Create a new Cell Style Template + * + * @param other CellStyleTemplate to copy + */ + public CellStyleTemplate(CellStyleTemplate other) { + this(); + for (Map.Entry> entry : other._cellStyleTemplate.entrySet()) { + CellAddress ca = new CellAddress(entry.getKey()); + Map newProperties = new HashMap(); + for (Map.Entry property : entry.getValue().entrySet()) { + if (property.getValue() instanceof Short) { + newProperties.put(property.getKey(), new Short(getShort(property.getValue()))); + } else { + newProperties.put(property.getKey(), property.getValue()); + } + } + _cellStyleTemplate.put(ca, newProperties); + } + } + + /** + * Draws a group of cell borders for a cell range. The borders are not + * applied to the cells at this time, just the template is drawn. To apply + * the drawn borders to a sheet, use {@link #applyBorders}. + * + * @param range + * - {@link CellRangeAddress} range of cells on which borders are + * drawn. + * @param borderStyle + * - Type of border to draw. {@link BorderStyle}. + * @param extent + * - {@link CellStyleTemplate.BorderExtent} of the borders to be + * applied. + */ + public void drawBorders(CellRangeAddress range, BorderStyle borderStyle, + BorderExtent extent) { + switch (extent) { + case NONE: + removeBorders(range); + break; + case ALL: + drawHorizontalBorders(range, borderStyle, BorderExtent.ALL); + drawVerticalBorders(range, borderStyle, BorderExtent.ALL); + break; + case INSIDE: + drawHorizontalBorders(range, borderStyle, BorderExtent.INSIDE); + drawVerticalBorders(range, borderStyle, BorderExtent.INSIDE); + break; + case OUTSIDE: + drawOutsideBorders(range, borderStyle, BorderExtent.ALL); + break; + case TOP: + drawTopBorder(range, borderStyle); + break; + case BOTTOM: + drawBottomBorder(range, borderStyle); + break; + case LEFT: + drawLeftBorder(range, borderStyle); + break; + case RIGHT: + drawRightBorder(range, borderStyle); + break; + case HORIZONTAL: + drawHorizontalBorders(range, borderStyle, BorderExtent.ALL); + break; + case INSIDE_HORIZONTAL: + drawHorizontalBorders(range, borderStyle, BorderExtent.INSIDE); + break; + case OUTSIDE_HORIZONTAL: + drawOutsideBorders(range, borderStyle, BorderExtent.HORIZONTAL); + break; + case VERTICAL: + drawVerticalBorders(range, borderStyle, BorderExtent.ALL); + break; + case INSIDE_VERTICAL: + drawVerticalBorders(range, borderStyle, BorderExtent.INSIDE); + break; + case OUTSIDE_VERTICAL: + drawOutsideBorders(range, borderStyle, BorderExtent.VERTICAL); + break; + } + } + + /** + * Draws a group of cell borders for a cell range. The borders are not + * applied to the cells at this time, just the template is drawn. To apply + * the drawn borders to a sheet, use {@link #applyBorders}. + * + * @param range + * - {@link CellRangeAddress} range of cells on which borders are + * drawn. + * @param borderStyle + * - Type of border to draw. {@link BorderStyle}. + * @param color + * - Color index from {@link IndexedColors} used to draw the + * borders. Ignored if extent is {@link BorderExtent.NONE}. + * @param extent + * - {@link BorderExtent} of the borders to be applied. + */ + public void drawBorders(CellRangeAddress range, BorderStyle borderStyle, + short color, BorderExtent extent) { + drawBorders(range, borderStyle, extent); + if (borderStyle != BorderStyle.NONE) { + drawBorderColors(range, color, extent); + } + } + + /** + *

+ * Draws the top border for a range of cells + *

+ * + * @param range + * - {@link CellRangeAddress} range of cells on which borders are + * drawn. + * @param borderStyle + * - Type of border to draw. {@link BorderStyle}. + */ + private void drawTopBorder(CellRangeAddress range, BorderStyle borderStyle) { + int row = range.getFirstRow(); + int firstCol = range.getFirstColumn(); + int lastCol = range.getLastColumn(); + for (int i = firstCol; i <= lastCol; i++) { + addBorderStyle(row, i, CellUtil.BORDER_TOP, borderStyle); + if (borderStyle == BorderStyle.NONE && row > 0) { + addBorderStyle(row - 1, i, CellUtil.BORDER_BOTTOM, borderStyle); + } + } + } + + /** + *

+ * Draws the bottom border for a range of cells + *

+ * + * @param range + * - {@link CellRangeAddress} range of cells on which borders are + * drawn. + * @param borderStyle + * - Type of border to draw. {@link BorderStyle}. + */ + private void drawBottomBorder(CellRangeAddress range, BorderStyle borderStyle) { + int row = range.getLastRow(); + int firstCol = range.getFirstColumn(); + int lastCol = range.getLastColumn(); + for (int i = firstCol; i <= lastCol; i++) { + addBorderStyle(row, i, CellUtil.BORDER_BOTTOM, borderStyle); + if (borderStyle == BorderStyle.NONE + && row < SpreadsheetVersion.EXCEL2007.getMaxRows() - 1) { + addBorderStyle(row + 1, i, CellUtil.BORDER_TOP, borderStyle); + } + } + } + + /** + *

+ * Draws the left border for a range of cells + *

+ * + * @param range + * - {@link CellRangeAddress} range of cells on which borders are + * drawn. + * @param borderStyle + * - Type of border to draw. {@link BorderStyle}. + */ + private void drawLeftBorder(CellRangeAddress range, BorderStyle borderStyle) { + int firstRow = range.getFirstRow(); + int lastRow = range.getLastRow(); + int col = range.getFirstColumn(); + for (int i = firstRow; i <= lastRow; i++) { + addBorderStyle(i, col, CellUtil.BORDER_LEFT, borderStyle); + if (borderStyle == BorderStyle.NONE && col > 0) { + addBorderStyle(i, col - 1, CellUtil.BORDER_RIGHT, borderStyle); + } + } + } + + /** + *

+ * Draws the right border for a range of cells + *

+ * + * @param range + * - {@link CellRangeAddress} range of cells on which borders are + * drawn. + * @param borderStyle + * - Type of border to draw. {@link BorderStyle}. + */ + private void drawRightBorder(CellRangeAddress range, BorderStyle borderStyle) { + int firstRow = range.getFirstRow(); + int lastRow = range.getLastRow(); + int col = range.getLastColumn(); + for (int i = firstRow; i <= lastRow; i++) { + addBorderStyle(i, col, CellUtil.BORDER_RIGHT, borderStyle); + if (borderStyle == BorderStyle.NONE + && col < SpreadsheetVersion.EXCEL2007.getMaxColumns() - 1) { + addBorderStyle(i, col + 1, CellUtil.BORDER_LEFT, borderStyle); + } + } + } + + /** + *

+ * Draws the outside borders for a range of cells. + *

+ * + * @param range + * - {@link CellRangeAddress} range of cells on which borders are + * drawn. + * @param borderStyle + * - Type of border to draw. {@link BorderStyle}. + * @param extent + * - {@link CellStyleTemplate.BorderExtent} of the borders to be + * applied. Valid Values are: + *
    + *
  • CellBorder.Extent.ALL
  • + *
  • CellBorder.Extent.HORIZONTAL
  • + *
  • CellBorder.Extent.VERTICAL
  • + *
+ */ + private void drawOutsideBorders(CellRangeAddress range, BorderStyle borderStyle, + BorderExtent extent) { + switch (extent) { + case ALL: + case HORIZONTAL: + case VERTICAL: + if (extent == BorderExtent.ALL || extent == BorderExtent.HORIZONTAL) { + drawTopBorder(range, borderStyle); + drawBottomBorder(range, borderStyle); + } + if (extent == BorderExtent.ALL || extent == BorderExtent.VERTICAL) { + drawLeftBorder(range, borderStyle); + drawRightBorder(range, borderStyle); + } + break; + default: + throw new IllegalArgumentException( + "Unsupported CellStyleTemplate.Extent, valid Extents are ALL, HORIZONTAL, and VERTICAL"); + } + } + + /** + *

+ * Draws the horizontal borders for a range of cells. + *

+ * + * @param range + * - {@link CellRangeAddress} range of cells on which borders are + * drawn. + * @param borderStyle + * - Type of border to draw. {@link BorderStyle}. + * @param extent + * - {@link CellStyleTemplate.BorderExtent} of the borders to be + * applied. Valid Values are: + *
    + *
  • CellBorder.Extent.ALL
  • + *
  • CellBorder.Extent.INSIDE
  • + *
+ */ + private void drawHorizontalBorders(CellRangeAddress range, BorderStyle borderStyle, + BorderExtent extent) { + switch (extent) { + case ALL: + case INSIDE: + int firstRow = range.getFirstRow(); + int lastRow = range.getLastRow(); + int firstCol = range.getFirstColumn(); + int lastCol = range.getLastColumn(); + for (int i = firstRow; i <= lastRow; i++) { + CellRangeAddress row = new CellRangeAddress(i, i, firstCol, + lastCol); + if (extent == BorderExtent.ALL || i > firstRow) { + drawTopBorder(row, borderStyle); + } + if (extent == BorderExtent.ALL || i < lastRow) { + drawBottomBorder(row, borderStyle); + } + } + break; + default: + throw new IllegalArgumentException( + "Unsupported CellStyleTemplate.Extent, valid Extents are ALL and INSIDE"); + } + } + + /** + *

+ * Draws the vertical borders for a range of cells. + *

+ * + * @param range + * - {@link CellRangeAddress} range of cells on which borders are + * drawn. + * @param borderStyle + * - Type of border to draw. {@link BorderStyle}. + * @param extent + * - {@link CellStyleTemplate.BorderExtent} of the borders to be + * applied. Valid Values are: + *
    + *
  • CellBorder.Extent.ALL
  • + *
  • CellBorder.Extent.INSIDE
  • + *
+ */ + private void drawVerticalBorders(CellRangeAddress range, BorderStyle borderStyle, + BorderExtent extent) { + switch (extent) { + case ALL: + case INSIDE: + int firstRow = range.getFirstRow(); + int lastRow = range.getLastRow(); + int firstCol = range.getFirstColumn(); + int lastCol = range.getLastColumn(); + for (int i = firstCol; i <= lastCol; i++) { + CellRangeAddress row = new CellRangeAddress(firstRow, lastRow, + i, i); + if (extent == BorderExtent.ALL || i > firstCol) { + drawLeftBorder(row, borderStyle); + } + if (extent == BorderExtent.ALL || i < lastCol) { + drawRightBorder(row, borderStyle); + } + } + break; + default: + throw new IllegalArgumentException( + "Unsupported CellStyleTemplate.Extent, valid Extents are ALL and INSIDE"); + } + } + + /** + * Removes all border properties from this {@link CellStyleTemplate} for the + * specified range. + * + * @parm range - {@link CellRangeAddress} range of cells to remove borders. + */ + private void removeBorders(CellRangeAddress range) { + Set properties = new HashSet(); + properties.add(CellUtil.BORDER_TOP); + properties.add(CellUtil.BORDER_BOTTOM); + properties.add(CellUtil.BORDER_LEFT); + properties.add(CellUtil.BORDER_RIGHT); + for (int row = range.getFirstRow(); row <= range.getLastRow(); row++) { + for (int col = range.getFirstColumn(); col <= range + .getLastColumn(); col++) { + removeProperties(row, col, properties); + } + } + removeBorderColors(range); + } + + /** + * Applies the drawn borders to a Sheet. The borders that are applied are + * the ones that have been drawn by the {@link #drawBorders} and + * {@link #drawBorderColors} methods. + * + * @param sheet + * - {@link Sheet} on which to apply borders + */ + public void applyBorders(Sheet sheet) { + Workbook wb = sheet.getWorkbook(); + for (Map.Entry> entry : _cellStyleTemplate + .entrySet()) { + CellAddress cellAddress = entry.getKey(); + if (cellAddress.getRow() < wb.getSpreadsheetVersion().getMaxRows() + && cellAddress.getColumn() < wb.getSpreadsheetVersion() + .getMaxColumns()) { + Map properties = entry.getValue(); + Row row = CellUtil.getRow(cellAddress.getRow(), sheet); + Cell cell = CellUtil.getCell(row, cellAddress.getColumn()); + CellUtil.setCellStyleProperties(cell, properties); + } + } + } + + /** + * Sets the color for a group of cell borders for a cell range. The borders + * are not applied to the cells at this time, just the template is drawn. If + * the borders do not exist, a BORDER_THIN border is used. To apply the + * drawn borders to a sheet, use {@link #applyBorders}. + * + * @param range + * - {@link CellRangeAddress} range of cells on which colors are + * set. + * @param color + * - Color index from {@link IndexedColors} used to draw the + * borders. + * @param extent + * - {@link CellStyleTemplate.BorderExtent} of the borders for which + * colors are set. + */ + public void drawBorderColors(CellRangeAddress range, short color, + BorderExtent extent) { + switch (extent) { + case NONE: + removeBorderColors(range); + break; + case ALL: + drawHorizontalBorderColors(range, color, BorderExtent.ALL); + drawVerticalBorderColors(range, color, BorderExtent.ALL); + break; + case INSIDE: + drawHorizontalBorderColors(range, color, BorderExtent.INSIDE); + drawVerticalBorderColors(range, color, BorderExtent.INSIDE); + break; + case OUTSIDE: + drawOutsideBorderColors(range, color, BorderExtent.ALL); + break; + case TOP: + drawTopBorderColor(range, color); + break; + case BOTTOM: + drawBottomBorderColor(range, color); + break; + case LEFT: + drawLeftBorderColor(range, color); + break; + case RIGHT: + drawRightBorderColor(range, color); + break; + case HORIZONTAL: + drawHorizontalBorderColors(range, color, BorderExtent.ALL); + break; + case INSIDE_HORIZONTAL: + drawHorizontalBorderColors(range, color, BorderExtent.INSIDE); + break; + case OUTSIDE_HORIZONTAL: + drawOutsideBorderColors(range, color, BorderExtent.HORIZONTAL); + break; + case VERTICAL: + drawVerticalBorderColors(range, color, BorderExtent.ALL); + break; + case INSIDE_VERTICAL: + drawVerticalBorderColors(range, color, BorderExtent.INSIDE); + break; + case OUTSIDE_VERTICAL: + drawOutsideBorderColors(range, color, BorderExtent.VERTICAL); + break; + } + } + + /** + *

+ * Sets the color of the top border for a range of cells. + *

+ * + * @param range + * - {@link CellRangeAddress} range of cells on which colors are + * set. + * @param color + * - Color index from {@link IndexedColors} used to draw the + * borders. + */ + private void drawTopBorderColor(CellRangeAddress range, short color) { + int row = range.getFirstRow(); + int firstCol = range.getFirstColumn(); + int lastCol = range.getLastColumn(); + for (int i = firstCol; i <= lastCol; i++) { + if (!borderIsSet(new CellAddress(row, i), CellUtil.BORDER_TOP)) { + drawTopBorder(new CellRangeAddress(row, row, i, i), + BorderStyle.THIN); + } + addProperty(row, i, CellUtil.TOP_BORDER_COLOR, color); + } + } + + /** + *

+ * Sets the color of the bottom border for a range of cells. + *

+ * + * @param range + * - {@link CellRangeAddress} range of cells on which colors are + * set. + * @param color + * - Color index from {@link IndexedColors} used to draw the + * borders. + */ + private void drawBottomBorderColor(CellRangeAddress range, short color) { + int row = range.getLastRow(); + int firstCol = range.getFirstColumn(); + int lastCol = range.getLastColumn(); + for (int i = firstCol; i <= lastCol; i++) { + if (!borderIsSet(new CellAddress(row, i), CellUtil.BORDER_BOTTOM)) { + drawBottomBorder(new CellRangeAddress(row, row, i, i), + BorderStyle.THIN); + } + addProperty(row, i, CellUtil.BOTTOM_BORDER_COLOR, color); + } + } + + /** + *

+ * Sets the color of the left border for a range of cells. + *

+ * + * @param range + * - {@link CellRangeAddress} range of cells on which colors are + * set. + * @param color + * - Color index from {@link IndexedColors} used to draw the + * borders. + */ + private void drawLeftBorderColor(CellRangeAddress range, short color) { + int firstRow = range.getFirstRow(); + int lastRow = range.getLastRow(); + int col = range.getFirstColumn(); + for (int i = firstRow; i <= lastRow; i++) { + if (!borderIsSet(new CellAddress(i, col), CellUtil.BORDER_LEFT)) { + drawLeftBorder(new CellRangeAddress(i, i, col, col), + BorderStyle.THIN); + } + addProperty(i, col, CellUtil.LEFT_BORDER_COLOR, color); + } + } + + /** + *

+ * Sets the color of the right border for a range of cells. If the border is + * not drawn, it defaults to BORDER_THIN + *

+ * + * @param range + * - {@link CellRangeAddress} range of cells on which colors are + * set. + * @param color + * - Color index from {@link IndexedColors} used to draw the + * borders. + */ + private void drawRightBorderColor(CellRangeAddress range, short color) { + int firstRow = range.getFirstRow(); + int lastRow = range.getLastRow(); + int col = range.getLastColumn(); + for (int i = firstRow; i <= lastRow; i++) { + if (!borderIsSet(new CellAddress(i, col), CellUtil.BORDER_RIGHT)) { + drawRightBorder(new CellRangeAddress(i, i, col, col), + BorderStyle.THIN); + } + addProperty(i, col, CellUtil.RIGHT_BORDER_COLOR, color); + } + } + + /** + *

+ * Sets the color of the outside borders for a range of cells. + *

+ * + * @param range + * - {@link CellRangeAddress} range of cells on which colors are + * set. + * @param color + * - Color index from {@link IndexedColors} used to draw the + * borders. + * @param extent + * - {@link CellStyleTemplate.BorderExtent} of the borders for which + * colors are set. Valid Values are: + *
    + *
  • CellBorder.Extent.ALL
  • + *
  • CellBorder.Extent.HORIZONTAL
  • + *
  • CellBorder.Extent.VERTICAL
  • + *
+ */ + private void drawOutsideBorderColors(CellRangeAddress range, short color, + BorderExtent extent) { + switch (extent) { + case ALL: + case HORIZONTAL: + case VERTICAL: + if (extent == BorderExtent.ALL || extent == BorderExtent.HORIZONTAL) { + drawTopBorderColor(range, color); + drawBottomBorderColor(range, color); + } + if (extent == BorderExtent.ALL || extent == BorderExtent.VERTICAL) { + drawLeftBorderColor(range, color); + drawRightBorderColor(range, color); + } + break; + default: + throw new IllegalArgumentException( + "Unsupported CellStyleTemplate.Extent, valid Extents are ALL, HORIZONTAL, and VERTICAL"); + } + } + + /** + *

+ * Sets the color of the horizontal borders for a range of cells. + *

+ * + * @param range + * - {@link CellRangeAddress} range of cells on which colors are + * set. + * @param color + * - Color index from {@link IndexedColors} used to draw the + * borders. + * @param extent + * - {@link CellStyleTemplate.BorderExtent} of the borders for which + * colors are set. Valid Values are: + *
    + *
  • CellBorder.Extent.ALL
  • + *
  • CellBorder.Extent.INSIDE
  • + *
+ */ + private void drawHorizontalBorderColors(CellRangeAddress range, short color, + BorderExtent extent) { + switch (extent) { + case ALL: + case INSIDE: + int firstRow = range.getFirstRow(); + int lastRow = range.getLastRow(); + int firstCol = range.getFirstColumn(); + int lastCol = range.getLastColumn(); + for (int i = firstRow; i <= lastRow; i++) { + CellRangeAddress row = new CellRangeAddress(i, i, firstCol, + lastCol); + if (extent == BorderExtent.ALL || i > firstRow) { + drawTopBorderColor(row, color); + } + if (extent == BorderExtent.ALL || i < lastRow) { + drawBottomBorderColor(row, color); + } + } + break; + default: + throw new IllegalArgumentException( + "Unsupported CellStyleTemplate.Extent, valid Extents are ALL and INSIDE"); + } + } + + /** + *

+ * Sets the color of the vertical borders for a range of cells. + *

+ * + * @param range + * - {@link CellRangeAddress} range of cells on which colors are + * set. + * @param color + * - Color index from {@link IndexedColors} used to draw the + * borders. + * @param extent + * - {@link CellStyleTemplate.BorderExtent} of the borders for which + * colors are set. Valid Values are: + *
    + *
  • CellBorder.Extent.ALL
  • + *
  • CellBorder.Extent.INSIDE
  • + *
+ */ + private void drawVerticalBorderColors(CellRangeAddress range, short color, + BorderExtent extent) { + switch (extent) { + case ALL: + case INSIDE: + int firstRow = range.getFirstRow(); + int lastRow = range.getLastRow(); + int firstCol = range.getFirstColumn(); + int lastCol = range.getLastColumn(); + for (int i = firstCol; i <= lastCol; i++) { + CellRangeAddress row = new CellRangeAddress(firstRow, lastRow, + i, i); + if (extent == BorderExtent.ALL || i > firstCol) { + drawLeftBorderColor(row, color); + } + if (extent == BorderExtent.ALL || i < lastCol) { + drawRightBorderColor(row, color); + } + } + break; + default: + throw new IllegalArgumentException( + "Unsupported CellStyleTemplate.Extent, valid Extents are ALL and INSIDE"); + } + } + + /** + * Removes all border properties from this {@link CellStyleTemplate} for the + * specified range. + * + * @parm range - {@link CellRangeAddress} range of cells to remove borders. + */ + private void removeBorderColors(CellRangeAddress range) { + Set properties = new HashSet(); + properties.add(CellUtil.TOP_BORDER_COLOR); + properties.add(CellUtil.BOTTOM_BORDER_COLOR); + properties.add(CellUtil.LEFT_BORDER_COLOR); + properties.add(CellUtil.RIGHT_BORDER_COLOR); + for (int row = range.getFirstRow(); row <= range.getLastRow(); row++) { + for (int col = range.getFirstColumn(); col <= range + .getLastColumn(); col++) { + removeProperties(row, col, properties); + } + } + } + + /** + * Adds a property to this {@link CellStyleTemplate} for a given cell + * + * @param row + * @param col + * @param property + * @param value + */ + private void addProperty(int row, int col, String property, Object value) { + CellAddress cell = new CellAddress(row, col); + Map cellProperties = _cellStyleTemplate.get(cell); + if (cellProperties == null) { + cellProperties = new HashMap(); + } + cellProperties.put(property, value); + _cellStyleTemplate.put(cell, cellProperties); + } + + /** + * Adds a property to this {@link CellStyleTemplate} for a given cell + * + * @param row + * @param col + * @param property + * @param value + */ + private void addProperty(int row, int col, String property, short value) { + addProperty(row, col, property, Short.valueOf(value)); + } + + /** + * Adds a property to this {@link CellStyleTemplate} for a given cell + * + * @param row + * @param col + * @param borderProperty + * @param borderStyle + */ + private void addBorderStyle(int row, int col, String borderProperty, BorderStyle borderStyle) { + addProperty(row, col, borderProperty, borderStyle); + } + + /** + * Removes a set of properties from this {@link CellStyleTemplate} for a + * given cell + * + * @param row + * @param col + * @param properties + */ + private void removeProperties(int row, int col, Set properties) { + CellAddress cell = new CellAddress(row, col); + Map cellProperties = _cellStyleTemplate.get(cell); + if (cellProperties != null) { + cellProperties.keySet().removeAll(properties); + if (cellProperties.isEmpty()) { + _cellStyleTemplate.remove(cell); + } else { + _cellStyleTemplate.put(cell, cellProperties); + } + } + } + + /** + * Retrieves the number of borders assigned to a cell + * + * @param cell + */ + public int getNumBorders(CellAddress cell) { + Map cellProperties = _cellStyleTemplate.get(cell); + if (cellProperties == null) { + return 0; + } + + int count = 0; + for (String property : cellProperties.keySet()) { + if (property.equals(CellUtil.BORDER_TOP)) + count += 1; + if (property.equals(CellUtil.BORDER_BOTTOM)) + count += 1; + if (property.equals(CellUtil.BORDER_LEFT)) + count += 1; + if (property.equals(CellUtil.BORDER_RIGHT)) + count += 1; + } + return count; + } + + /** + * Retrieves the number of borders assigned to a cell + * + * @param row + * @param col + */ + public int getNumBorders(int row, int col) { + return getNumBorders(new CellAddress(row, col)); + } + + /** + * Retrieves the number of border colors assigned to a cell + * + * @param cell + */ + public int getNumBorderColors(CellAddress cell) { + Map cellProperties = _cellStyleTemplate.get(cell); + if (cellProperties == null) { + return 0; + } + + int count = 0; + for (String property : cellProperties.keySet()) { + if (property.equals(CellUtil.TOP_BORDER_COLOR)) + count += 1; + if (property.equals(CellUtil.BOTTOM_BORDER_COLOR)) + count += 1; + if (property.equals(CellUtil.LEFT_BORDER_COLOR)) + count += 1; + if (property.equals(CellUtil.RIGHT_BORDER_COLOR)) + count += 1; + } + return count; + } + + /** + * Retrieves the number of border colors assigned to a cell + * + * @param row + * @param col + */ + public int getNumBorderColors(int row, int col) { + return getNumBorderColors(new CellAddress(row, col)); + } + + /** + * Retrieves the border style for a given cell + * + * @param cell + * @param property + */ + public short getTemplateProperty(CellAddress cell, String property) { + short value = 0; + Map cellProperties = _cellStyleTemplate.get(cell); + if (cellProperties != null) { + Object obj = cellProperties.get(property); + if (obj != null) { + value = getShort(obj); + } + } + return value; + } + + /** + * Retrieves the border style for a given cell + * + * @param row + * @param col + * @param property + */ + public short getTemplateProperty(int row, int col, String property) { + return getTemplateProperty(new CellAddress(row, col), property); + } + + /** + * Converts a Short object to a short value or 0 if the object is not a + * Short + * + * @param value + * @return short + */ + private static short getShort(Object value) { + if (value instanceof Short) { + return ((Short) value).shortValue(); + } + return 0; + } + + /** + * Returns true if the specified cell border is has been set, and is not {@link BorderStyle.NONE} + * + * @param cell + * - {@link CellAddress} of cell to test + * @param cellBorder + * - String constant from {@link CellUtil} indicating which border to test + * @return boolean + */ + private boolean borderIsSet(CellAddress cell, String cellBorder) { + Object borderLineStyle = getTemplateProperty(cell, cellBorder); + return (borderLineStyle != null) && (borderLineStyle != BorderStyle.NONE); + } +} diff --git a/src/testcases/org/apache/poi/ss/util/TestCellStyleTemplate.java b/src/testcases/org/apache/poi/ss/util/TestCellStyleTemplate.java new file mode 100644 index 000000000..13f0bbc39 --- /dev/null +++ b/src/testcases/org/apache/poi/ss/util/TestCellStyleTemplate.java @@ -0,0 +1,892 @@ +package org.apache.poi.ss.util; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.junit.Test; + +/** + * Tests Spreadsheet CellStyleTemplate + * + * @see org.apache.poi.ss.util.CellStyleTemplate + */ +public final class TestCellStyleTemplate { + @Test + public void getNumBorders() throws IOException { + CellRangeAddress a1 = CellRangeAddress.valueOf("A1"); + CellStyleTemplate cst = new CellStyleTemplate(); + cst.drawBorders(a1, BorderStyle.THIN, BorderExtent.TOP); + assertEquals(1, cst.getNumBorders(0, 0)); + cst.drawBorders(a1, BorderStyle.MEDIUM, BorderExtent.BOTTOM); + assertEquals(2, cst.getNumBorders(0, 0)); + cst.drawBorders(a1, BorderStyle.MEDIUM, BorderExtent.NONE); + assertEquals(0, cst.getNumBorders(0, 0)); + } + + @Test + public void getNumBorderColors() throws IOException { + CellRangeAddress a1 = CellRangeAddress.valueOf("A1"); + CellStyleTemplate cst = new CellStyleTemplate(); + cst.drawBorderColors(a1, IndexedColors.RED.getIndex(), BorderExtent.TOP); + assertEquals(1, cst.getNumBorderColors(0, 0)); + cst.drawBorderColors(a1, IndexedColors.RED.getIndex(), BorderExtent.BOTTOM); + assertEquals(2, cst.getNumBorderColors(0, 0)); + cst.drawBorderColors(a1, IndexedColors.RED.getIndex(), BorderExtent.NONE); + assertEquals(0, cst.getNumBorderColors(0, 0)); + } + + @Test + public void getTemplateProperties() throws IOException { + CellRangeAddress a1 = CellRangeAddress.valueOf("A1"); + CellStyleTemplate cst = new CellStyleTemplate(); + cst.drawBorders(a1, BorderStyle.THIN, BorderExtent.TOP); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(0, 0, CellUtil.BORDER_TOP)); + cst.drawBorders(a1, BorderStyle.MEDIUM, BorderExtent.BOTTOM); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(0, 0, CellUtil.BORDER_BOTTOM)); + cst.drawBorderColors(a1, IndexedColors.RED.getIndex(), BorderExtent.TOP); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(0, 0, CellUtil.TOP_BORDER_COLOR)); + cst.drawBorderColors(a1, IndexedColors.BLUE.getIndex(), BorderExtent.BOTTOM); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(0, 0, CellUtil.BOTTOM_BORDER_COLOR)); + } + + @Test + public void drawBorders() throws IOException { + CellRangeAddress a1c3 = CellRangeAddress.valueOf("A1:C3"); + CellStyleTemplate cst = new CellStyleTemplate(); + cst.drawBorders(a1c3, BorderStyle.THIN, + BorderExtent.ALL); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + assertEquals(4, cst.getNumBorders(i, j)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, CellUtil.BORDER_TOP)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, CellUtil.BORDER_BOTTOM)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, CellUtil.BORDER_LEFT)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, CellUtil.BORDER_RIGHT)); + } + } + cst.drawBorders(a1c3, BorderStyle.MEDIUM, + BorderExtent.OUTSIDE); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + assertEquals(4, cst.getNumBorders(i, j)); + if (i == 0) { + if (j == 0) { + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_TOP)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_BOTTOM)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_LEFT)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_RIGHT)); + } else if (j == 2) { + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_TOP)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_BOTTOM)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_LEFT)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_RIGHT)); + } else { + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_TOP)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_BOTTOM)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_LEFT)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_RIGHT)); + } + } else if (i == 2) { + if (j == 0) { + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_TOP)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_BOTTOM)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_LEFT)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_RIGHT)); + } else if (j == 2) { + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_TOP)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_BOTTOM)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_LEFT)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_RIGHT)); + } else { + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_TOP)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_BOTTOM)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_LEFT)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_RIGHT)); + } + } else { + if (j == 0) { + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_TOP)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_BOTTOM)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_LEFT)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_RIGHT)); + } else if (j == 2) { + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_TOP)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_BOTTOM)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_LEFT)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_RIGHT)); + } else { + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_TOP)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_BOTTOM)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_LEFT)); + assertEquals(BorderStyle.THIN, + cst.getTemplateProperty(i, j, + CellUtil.BORDER_RIGHT)); + } + } + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + assertEquals(0, cst.getNumBorders(i, j)); + } + } + cst.drawBorders(a1c3, BorderStyle.MEDIUM, + BorderExtent.TOP); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + if (i == 0) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, CellUtil.BORDER_TOP)); + } else { + assertEquals(0, cst.getNumBorders(i, j)); + } + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorders(a1c3, BorderStyle.MEDIUM, + BorderExtent.BOTTOM); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + if (i == 2) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(BorderStyle.MEDIUM, cst + .getTemplateProperty(i, j, CellUtil.BORDER_BOTTOM)); + } else { + assertEquals(0, cst.getNumBorders(i, j)); + } + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorders(a1c3, BorderStyle.MEDIUM, + BorderExtent.LEFT); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + if (j == 0) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, CellUtil.BORDER_LEFT)); + } else { + assertEquals(0, cst.getNumBorders(i, j)); + } + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorders(a1c3, BorderStyle.MEDIUM, + BorderExtent.RIGHT); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + if (j == 2) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(BorderStyle.MEDIUM, cst + .getTemplateProperty(i, j, CellUtil.BORDER_RIGHT)); + } else { + assertEquals(0, cst.getNumBorders(i, j)); + } + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorders(a1c3, BorderStyle.MEDIUM, + BorderExtent.HORIZONTAL); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + assertEquals(2, cst.getNumBorders(i, j)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, CellUtil.BORDER_TOP)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, CellUtil.BORDER_BOTTOM)); + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorders(a1c3, BorderStyle.MEDIUM, + BorderExtent.INSIDE_HORIZONTAL); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + if (i == 0) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(BorderStyle.MEDIUM, cst + .getTemplateProperty(i, j, CellUtil.BORDER_BOTTOM)); + } else if (i == 2) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, CellUtil.BORDER_TOP)); + } else { + assertEquals(2, cst.getNumBorders(i, j)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, CellUtil.BORDER_TOP)); + assertEquals(BorderStyle.MEDIUM, cst + .getTemplateProperty(i, j, CellUtil.BORDER_BOTTOM)); + } + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorders(a1c3, BorderStyle.MEDIUM, + BorderExtent.OUTSIDE_HORIZONTAL); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + if (i == 0) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, CellUtil.BORDER_TOP)); + } else if (i == 2) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(BorderStyle.MEDIUM, cst + .getTemplateProperty(i, j, CellUtil.BORDER_BOTTOM)); + } else { + assertEquals(0, cst.getNumBorders(i, j)); + } + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorders(a1c3, BorderStyle.MEDIUM, + BorderExtent.VERTICAL); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + assertEquals(2, cst.getNumBorders(i, j)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, CellUtil.BORDER_LEFT)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, CellUtil.BORDER_RIGHT)); + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorders(a1c3, BorderStyle.MEDIUM, + BorderExtent.INSIDE_VERTICAL); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + if (j == 0) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(BorderStyle.MEDIUM, cst + .getTemplateProperty(i, j, CellUtil.BORDER_RIGHT)); + } else if (j == 2) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, CellUtil.BORDER_LEFT)); + } else { + assertEquals(2, cst.getNumBorders(i, j)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, CellUtil.BORDER_LEFT)); + assertEquals(BorderStyle.MEDIUM, cst + .getTemplateProperty(i, j, CellUtil.BORDER_RIGHT)); + } + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorders(a1c3, BorderStyle.MEDIUM, + BorderExtent.OUTSIDE_VERTICAL); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + if (j == 0) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, CellUtil.BORDER_LEFT)); + } else if (j == 2) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(BorderStyle.MEDIUM, cst + .getTemplateProperty(i, j, CellUtil.BORDER_RIGHT)); + } else { + assertEquals(0, cst.getNumBorders(i, j)); + } + } + } + } + + @Test + public void drawBorderColors() throws IOException { + CellRangeAddress a1c3 = CellRangeAddress.valueOf("A1:C3"); + CellStyleTemplate cst = new CellStyleTemplate(); + cst.drawBorderColors(a1c3, IndexedColors.RED.getIndex(), + BorderExtent.ALL); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + assertEquals(4, cst.getNumBorders(i, j)); + assertEquals(4, cst.getNumBorderColors(i, j)); + assertEquals(IndexedColors.RED.getIndex(), cst + .getTemplateProperty(i, j, CellUtil.TOP_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.BOTTOM_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), cst + .getTemplateProperty(i, j, CellUtil.LEFT_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.RIGHT_BORDER_COLOR)); + } + } + cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), + BorderExtent.OUTSIDE); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + assertEquals(4, cst.getNumBorders(i, j)); + assertEquals(4, cst.getNumBorderColors(i, j)); + if (i == 0) { + if (j == 0) { + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.TOP_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.BOTTOM_BORDER_COLOR)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.LEFT_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.RIGHT_BORDER_COLOR)); + } else if (j == 2) { + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.TOP_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.BOTTOM_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.LEFT_BORDER_COLOR)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.RIGHT_BORDER_COLOR)); + } else { + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.TOP_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.BOTTOM_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.LEFT_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.RIGHT_BORDER_COLOR)); + } + } else if (i == 2) { + if (j == 0) { + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.TOP_BORDER_COLOR)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.BOTTOM_BORDER_COLOR)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.LEFT_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.RIGHT_BORDER_COLOR)); + } else if (j == 2) { + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.TOP_BORDER_COLOR)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.BOTTOM_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.LEFT_BORDER_COLOR)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.RIGHT_BORDER_COLOR)); + } else { + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.TOP_BORDER_COLOR)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.BOTTOM_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.LEFT_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.RIGHT_BORDER_COLOR)); + } + } else { + if (j == 0) { + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.TOP_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.BOTTOM_BORDER_COLOR)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.LEFT_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.RIGHT_BORDER_COLOR)); + } else if (j == 2) { + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.TOP_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.BOTTOM_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.LEFT_BORDER_COLOR)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.RIGHT_BORDER_COLOR)); + } else { + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.TOP_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.BOTTOM_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.LEFT_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.RIGHT_BORDER_COLOR)); + } + } + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), + BorderExtent.NONE); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + assertEquals(0, cst.getNumBorders(i, j)); + assertEquals(0, cst.getNumBorderColors(i, j)); + } + } + cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), + BorderExtent.TOP); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + if (i == 0) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(1, cst.getNumBorderColors(i, j)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.TOP_BORDER_COLOR)); + } else { + assertEquals(0, cst.getNumBorders(i, j)); + assertEquals(0, cst.getNumBorderColors(i, j)); + } + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), + BorderExtent.BOTTOM); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + if (i == 2) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(1, cst.getNumBorderColors(i, j)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.BOTTOM_BORDER_COLOR)); + } else { + assertEquals(0, cst.getNumBorders(i, j)); + assertEquals(0, cst.getNumBorderColors(i, j)); + } + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), + BorderExtent.LEFT); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + if (j == 0) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(1, cst.getNumBorderColors(i, j)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.LEFT_BORDER_COLOR)); + } else { + assertEquals(0, cst.getNumBorders(i, j)); + assertEquals(0, cst.getNumBorderColors(i, j)); + } + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), + BorderExtent.RIGHT); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + if (j == 2) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(1, cst.getNumBorderColors(i, j)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.RIGHT_BORDER_COLOR)); + } else { + assertEquals(0, cst.getNumBorders(i, j)); + assertEquals(0, cst.getNumBorderColors(i, j)); + } + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), + BorderExtent.HORIZONTAL); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + assertEquals(2, cst.getNumBorders(i, j)); + assertEquals(2, cst.getNumBorderColors(i, j)); + assertEquals(IndexedColors.BLUE.getIndex(), cst + .getTemplateProperty(i, j, CellUtil.TOP_BORDER_COLOR)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.BOTTOM_BORDER_COLOR)); + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), + BorderExtent.INSIDE_HORIZONTAL); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + if (i == 0) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(1, cst.getNumBorderColors(i, j)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.BOTTOM_BORDER_COLOR)); + } else if (i == 2) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(1, cst.getNumBorderColors(i, j)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.TOP_BORDER_COLOR)); + } else { + assertEquals(2, cst.getNumBorders(i, j)); + assertEquals(2, cst.getNumBorderColors(i, j)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.TOP_BORDER_COLOR)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.BOTTOM_BORDER_COLOR)); + } + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), + BorderExtent.OUTSIDE_HORIZONTAL); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + if (i == 0) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(1, cst.getNumBorderColors(i, j)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.TOP_BORDER_COLOR)); + } else if (i == 2) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(1, cst.getNumBorderColors(i, j)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.BOTTOM_BORDER_COLOR)); + } else { + assertEquals(0, cst.getNumBorders(i, j)); + assertEquals(0, cst.getNumBorderColors(i, j)); + } + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), + BorderExtent.VERTICAL); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + assertEquals(2, cst.getNumBorders(i, j)); + assertEquals(2, cst.getNumBorderColors(i, j)); + assertEquals(IndexedColors.BLUE.getIndex(), cst + .getTemplateProperty(i, j, CellUtil.LEFT_BORDER_COLOR)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.RIGHT_BORDER_COLOR)); + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), + BorderExtent.INSIDE_VERTICAL); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + if (j == 0) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(1, cst.getNumBorderColors(i, j)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.RIGHT_BORDER_COLOR)); + } else if (j == 2) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(1, cst.getNumBorderColors(i, j)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.LEFT_BORDER_COLOR)); + } else { + assertEquals(2, cst.getNumBorders(i, j)); + assertEquals(2, cst.getNumBorderColors(i, j)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.LEFT_BORDER_COLOR)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.RIGHT_BORDER_COLOR)); + } + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), + BorderExtent.NONE); + cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), + BorderExtent.OUTSIDE_VERTICAL); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + if (j == 0) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(1, cst.getNumBorderColors(i, j)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.LEFT_BORDER_COLOR)); + } else if (j == 2) { + assertEquals(1, cst.getNumBorders(i, j)); + assertEquals(1, cst.getNumBorderColors(i, j)); + assertEquals(IndexedColors.BLUE.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.RIGHT_BORDER_COLOR)); + } else { + assertEquals(0, cst.getNumBorders(i, j)); + assertEquals(0, cst.getNumBorderColors(i, j)); + } + } + } + } + + @Test + public void drawBordersWithColors() throws IOException { + CellRangeAddress a1c3 = CellRangeAddress.valueOf("A1:C3"); + CellStyleTemplate cst = new CellStyleTemplate(); + + cst.drawBorders(a1c3, BorderStyle.MEDIUM, IndexedColors.RED.getIndex(), BorderExtent.ALL); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + assertEquals(4, cst.getNumBorders(i, j)); + assertEquals(4, cst.getNumBorderColors(i, j)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, CellUtil.BORDER_TOP)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, CellUtil.BORDER_BOTTOM)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, CellUtil.BORDER_LEFT)); + assertEquals(BorderStyle.MEDIUM, + cst.getTemplateProperty(i, j, CellUtil.BORDER_RIGHT)); + assertEquals(IndexedColors.RED.getIndex(), cst + .getTemplateProperty(i, j, CellUtil.TOP_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.BOTTOM_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), cst + .getTemplateProperty(i, j, CellUtil.LEFT_BORDER_COLOR)); + assertEquals(IndexedColors.RED.getIndex(), + cst.getTemplateProperty(i, j, + CellUtil.RIGHT_BORDER_COLOR)); + } + } + cst.drawBorders(a1c3, BorderStyle.NONE, BorderExtent.NONE); + cst.drawBorders(a1c3, BorderStyle.NONE, IndexedColors.RED.getIndex(), BorderExtent.ALL); + for (int i = 0; i <= 2; i++) { + for (int j = 0; j <= 2; j++) { + assertEquals(4, cst.getNumBorders(i, j)); + assertEquals(0, cst.getNumBorderColors(i, j)); + assertEquals(BorderStyle.NONE, + cst.getTemplateProperty(i, j, CellUtil.BORDER_TOP)); + assertEquals(BorderStyle.NONE, + cst.getTemplateProperty(i, j, CellUtil.BORDER_BOTTOM)); + assertEquals(BorderStyle.NONE, + cst.getTemplateProperty(i, j, CellUtil.BORDER_LEFT)); + assertEquals(BorderStyle.NONE, + cst.getTemplateProperty(i, j, CellUtil.BORDER_RIGHT)); + } + } + } + + @Test + public void applyBorders() throws IOException { + CellRangeAddress a1c3 = CellRangeAddress.valueOf("A1:C3"); + CellRangeAddress b2 = CellRangeAddress.valueOf("B2"); + CellStyleTemplate cst = new CellStyleTemplate(); + Workbook wb = new HSSFWorkbook(); + Sheet sheet = wb.createSheet(); + + cst.drawBorders(a1c3, BorderStyle.THIN, IndexedColors.RED.getIndex(), BorderExtent.ALL); + cst.applyBorders(sheet); + + for (Row row: sheet) { + for (Cell cell: row) { + CellStyle cs = cell.getCellStyle(); + assertEquals(BorderStyle.THIN, cs.getBorderTop()); + assertEquals(IndexedColors.RED.getIndex(), cs.getTopBorderColor()); + assertEquals(BorderStyle.THIN, cs.getBorderBottom()); + assertEquals(IndexedColors.RED.getIndex(), cs.getBottomBorderColor()); + assertEquals(BorderStyle.THIN, cs.getBorderLeft()); + assertEquals(IndexedColors.RED.getIndex(), cs.getLeftBorderColor()); + assertEquals(BorderStyle.THIN, cs.getBorderRight()); + assertEquals(IndexedColors.RED.getIndex(), cs.getRightBorderColor()); + } + } + + cst.drawBorders(b2, BorderStyle.NONE, BorderExtent.ALL); + cst.applyBorders(sheet); + + for (Row row: sheet) { + for (Cell cell: row) { + CellStyle cs = cell.getCellStyle(); + if (cell.getColumnIndex() != 1 || row.getRowNum() == 0) { + assertEquals(BorderStyle.THIN, cs.getBorderTop()); + assertEquals(IndexedColors.RED.getIndex(), cs.getTopBorderColor()); + } else { + assertEquals(BorderStyle.NONE, cs.getBorderTop()); + } + if (cell.getColumnIndex() != 1 || row.getRowNum() == 2) { + assertEquals(BorderStyle.THIN, cs.getBorderBottom()); + assertEquals(IndexedColors.RED.getIndex(), cs.getBottomBorderColor()); + } else { + assertEquals(BorderStyle.NONE, cs.getBorderBottom()); + } + if (cell.getColumnIndex() == 0 || row.getRowNum() != 1) { + assertEquals(BorderStyle.THIN, cs.getBorderLeft()); + assertEquals(IndexedColors.RED.getIndex(), cs.getLeftBorderColor()); + } else { + assertEquals(BorderStyle.NONE, cs.getBorderLeft()); + } + if (cell.getColumnIndex() == 2 || row.getRowNum() != 1) { + assertEquals(BorderStyle.THIN, cs.getBorderRight()); + assertEquals(IndexedColors.RED.getIndex(), cs.getRightBorderColor()); + } else { + assertEquals(BorderStyle.NONE, cs.getBorderRight()); + } + } + } + + wb.close(); + } +} From 0fe7cd52990478e860df8142fc800319da1ecc31 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Mon, 1 Aug 2016 00:17:33 +0000 Subject: [PATCH 018/157] Javadoc fixes git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754694 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/ss/util/CellStyleTemplate.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/java/org/apache/poi/ss/util/CellStyleTemplate.java b/src/java/org/apache/poi/ss/util/CellStyleTemplate.java index e6a7c9c7b..6c66b9bae 100644 --- a/src/java/org/apache/poi/ss/util/CellStyleTemplate.java +++ b/src/java/org/apache/poi/ss/util/CellStyleTemplate.java @@ -39,7 +39,7 @@ import org.apache.poi.ss.usermodel.Workbook; * sheet in any workbook. * * This class requires the full spreadsheet to be in memory so - * {@link SWorkbook} Spreadsheets are not supported. The same + * {@link SXSSFWorkbook} Spreadsheets are not supported. The same * {@link CellStyleTemplate} can, however, be applied to both * {@link org.apache.poi.hssf.usermodel.HSSFWorkbook}, and Workbook objects * if necessary. Portions of the border that fall outside the max range of the @@ -97,8 +97,7 @@ public final class CellStyleTemplate { * @param borderStyle * - Type of border to draw. {@link BorderStyle}. * @param extent - * - {@link CellStyleTemplate.BorderExtent} of the borders to be - * applied. + * - {@link BorderExtent} of the borders to be applied. */ public void drawBorders(CellRangeAddress range, BorderStyle borderStyle, BorderExtent extent) { @@ -162,7 +161,7 @@ public final class CellStyleTemplate { * - Type of border to draw. {@link BorderStyle}. * @param color * - Color index from {@link IndexedColors} used to draw the - * borders. Ignored if extent is {@link BorderExtent.NONE}. + * borders. Ignored if extent is {@link BorderExtent#NONE}. * @param extent * - {@link BorderExtent} of the borders to be applied. */ @@ -454,8 +453,7 @@ public final class CellStyleTemplate { * - Color index from {@link IndexedColors} used to draw the * borders. * @param extent - * - {@link CellStyleTemplate.BorderExtent} of the borders for which - * colors are set. + * - {@link BorderExtent} of the borders for which colors are set. */ public void drawBorderColors(CellRangeAddress range, short color, BorderExtent extent) { From 8c0adfe55f773994a262b39ef24ee4beac3c71bd Mon Sep 17 00:00:00 2001 From: Mark Murphy Date: Mon, 1 Aug 2016 02:53:55 +0000 Subject: [PATCH 019/157] correction to junit bugs in r1754691 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754698 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/ss/util/CellStyleTemplate.java | 34 ++++- .../poi/ss/util/TestCellStyleTemplate.java | 140 +++++++++--------- 2 files changed, 101 insertions(+), 73 deletions(-) diff --git a/src/java/org/apache/poi/ss/util/CellStyleTemplate.java b/src/java/org/apache/poi/ss/util/CellStyleTemplate.java index 6c66b9bae..64e7d790d 100644 --- a/src/java/org/apache/poi/ss/util/CellStyleTemplate.java +++ b/src/java/org/apache/poi/ss/util/CellStyleTemplate.java @@ -890,8 +890,8 @@ public final class CellStyleTemplate { return getNumBorderColors(new CellAddress(row, col)); } - /** - * Retrieves the border style for a given cell + /** + * Retrieves a template property as a short for a given cell * * @param cell * @param property @@ -909,7 +909,7 @@ public final class CellStyleTemplate { } /** - * Retrieves the border style for a given cell + * Retrieves a template property as a short for a given cell * * @param row * @param col @@ -919,6 +919,34 @@ public final class CellStyleTemplate { return getTemplateProperty(new CellAddress(row, col), property); } + /** + * Retrieves the border style for a given cell + * + * @param cell + * @param property + */ + public BorderStyle getBorderStyle(CellAddress cell, String property) { + Map cellProperties = _cellStyleTemplate.get(cell); + if (cellProperties != null) { + Object obj = cellProperties.get(property); + if (obj instanceof BorderStyle) { + return (BorderStyle) obj; + } + } + return null; + } + + /** + * Retrieves the border style for a given cell + * + * @param row + * @param col + * @param property + */ + public BorderStyle getBorderStyle(int row, int col, String property) { + return getBorderStyle(new CellAddress(row, col), property); + } + /** * Converts a Short object to a short value or 0 if the object is not a * Short diff --git a/src/testcases/org/apache/poi/ss/util/TestCellStyleTemplate.java b/src/testcases/org/apache/poi/ss/util/TestCellStyleTemplate.java index 13f0bbc39..d9b8f9060 100644 --- a/src/testcases/org/apache/poi/ss/util/TestCellStyleTemplate.java +++ b/src/testcases/org/apache/poi/ss/util/TestCellStyleTemplate.java @@ -50,10 +50,10 @@ public final class TestCellStyleTemplate { CellStyleTemplate cst = new CellStyleTemplate(); cst.drawBorders(a1, BorderStyle.THIN, BorderExtent.TOP); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(0, 0, CellUtil.BORDER_TOP)); + cst.getBorderStyle(0, 0, CellUtil.BORDER_TOP)); cst.drawBorders(a1, BorderStyle.MEDIUM, BorderExtent.BOTTOM); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(0, 0, CellUtil.BORDER_BOTTOM)); + cst.getBorderStyle(0, 0, CellUtil.BORDER_BOTTOM)); cst.drawBorderColors(a1, IndexedColors.RED.getIndex(), BorderExtent.TOP); assertEquals(IndexedColors.RED.getIndex(), cst.getTemplateProperty(0, 0, CellUtil.TOP_BORDER_COLOR)); @@ -72,13 +72,13 @@ public final class TestCellStyleTemplate { for (int j = 0; j <= 2; j++) { assertEquals(4, cst.getNumBorders(i, j)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, CellUtil.BORDER_TOP)); + cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, CellUtil.BORDER_BOTTOM)); + cst.getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, CellUtil.BORDER_LEFT)); + cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, CellUtil.BORDER_RIGHT)); + cst.getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); } } cst.drawBorders(a1c3, BorderStyle.MEDIUM, @@ -89,124 +89,124 @@ public final class TestCellStyleTemplate { if (i == 0) { if (j == 0) { assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); } else if (j == 2) { assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); } else { assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); } } else if (i == 2) { if (j == 0) { assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); } else if (j == 2) { assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); } else { assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); } } else { if (j == 0) { assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); } else if (j == 2) { assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); } else { assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); assertEquals(BorderStyle.THIN, - cst.getTemplateProperty(i, j, + cst.getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); } } @@ -226,7 +226,7 @@ public final class TestCellStyleTemplate { if (i == 0) { assertEquals(1, cst.getNumBorders(i, j)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, CellUtil.BORDER_TOP)); + cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); } else { assertEquals(0, cst.getNumBorders(i, j)); } @@ -241,7 +241,7 @@ public final class TestCellStyleTemplate { if (i == 2) { assertEquals(1, cst.getNumBorders(i, j)); assertEquals(BorderStyle.MEDIUM, cst - .getTemplateProperty(i, j, CellUtil.BORDER_BOTTOM)); + .getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); } else { assertEquals(0, cst.getNumBorders(i, j)); } @@ -256,7 +256,7 @@ public final class TestCellStyleTemplate { if (j == 0) { assertEquals(1, cst.getNumBorders(i, j)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, CellUtil.BORDER_LEFT)); + cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); } else { assertEquals(0, cst.getNumBorders(i, j)); } @@ -271,7 +271,7 @@ public final class TestCellStyleTemplate { if (j == 2) { assertEquals(1, cst.getNumBorders(i, j)); assertEquals(BorderStyle.MEDIUM, cst - .getTemplateProperty(i, j, CellUtil.BORDER_RIGHT)); + .getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); } else { assertEquals(0, cst.getNumBorders(i, j)); } @@ -285,9 +285,9 @@ public final class TestCellStyleTemplate { for (int j = 0; j <= 2; j++) { assertEquals(2, cst.getNumBorders(i, j)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, CellUtil.BORDER_TOP)); + cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, CellUtil.BORDER_BOTTOM)); + cst.getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); } } cst.drawBorders(a1c3, BorderStyle.NONE, @@ -299,17 +299,17 @@ public final class TestCellStyleTemplate { if (i == 0) { assertEquals(1, cst.getNumBorders(i, j)); assertEquals(BorderStyle.MEDIUM, cst - .getTemplateProperty(i, j, CellUtil.BORDER_BOTTOM)); + .getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); } else if (i == 2) { assertEquals(1, cst.getNumBorders(i, j)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, CellUtil.BORDER_TOP)); + cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); } else { assertEquals(2, cst.getNumBorders(i, j)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, CellUtil.BORDER_TOP)); + cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); assertEquals(BorderStyle.MEDIUM, cst - .getTemplateProperty(i, j, CellUtil.BORDER_BOTTOM)); + .getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); } } } @@ -322,11 +322,11 @@ public final class TestCellStyleTemplate { if (i == 0) { assertEquals(1, cst.getNumBorders(i, j)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, CellUtil.BORDER_TOP)); + cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); } else if (i == 2) { assertEquals(1, cst.getNumBorders(i, j)); assertEquals(BorderStyle.MEDIUM, cst - .getTemplateProperty(i, j, CellUtil.BORDER_BOTTOM)); + .getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); } else { assertEquals(0, cst.getNumBorders(i, j)); } @@ -340,9 +340,9 @@ public final class TestCellStyleTemplate { for (int j = 0; j <= 2; j++) { assertEquals(2, cst.getNumBorders(i, j)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, CellUtil.BORDER_LEFT)); + cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, CellUtil.BORDER_RIGHT)); + cst.getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); } } cst.drawBorders(a1c3, BorderStyle.NONE, @@ -354,17 +354,17 @@ public final class TestCellStyleTemplate { if (j == 0) { assertEquals(1, cst.getNumBorders(i, j)); assertEquals(BorderStyle.MEDIUM, cst - .getTemplateProperty(i, j, CellUtil.BORDER_RIGHT)); + .getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); } else if (j == 2) { assertEquals(1, cst.getNumBorders(i, j)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, CellUtil.BORDER_LEFT)); + cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); } else { assertEquals(2, cst.getNumBorders(i, j)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, CellUtil.BORDER_LEFT)); + cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); assertEquals(BorderStyle.MEDIUM, cst - .getTemplateProperty(i, j, CellUtil.BORDER_RIGHT)); + .getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); } } } @@ -377,11 +377,11 @@ public final class TestCellStyleTemplate { if (j == 0) { assertEquals(1, cst.getNumBorders(i, j)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, CellUtil.BORDER_LEFT)); + cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); } else if (j == 2) { assertEquals(1, cst.getNumBorders(i, j)); assertEquals(BorderStyle.MEDIUM, cst - .getTemplateProperty(i, j, CellUtil.BORDER_RIGHT)); + .getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); } else { assertEquals(0, cst.getNumBorders(i, j)); } @@ -792,13 +792,13 @@ public final class TestCellStyleTemplate { assertEquals(4, cst.getNumBorders(i, j)); assertEquals(4, cst.getNumBorderColors(i, j)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, CellUtil.BORDER_TOP)); + cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, CellUtil.BORDER_BOTTOM)); + cst.getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, CellUtil.BORDER_LEFT)); + cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); assertEquals(BorderStyle.MEDIUM, - cst.getTemplateProperty(i, j, CellUtil.BORDER_RIGHT)); + cst.getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); assertEquals(IndexedColors.RED.getIndex(), cst .getTemplateProperty(i, j, CellUtil.TOP_BORDER_COLOR)); assertEquals(IndexedColors.RED.getIndex(), @@ -818,13 +818,13 @@ public final class TestCellStyleTemplate { assertEquals(4, cst.getNumBorders(i, j)); assertEquals(0, cst.getNumBorderColors(i, j)); assertEquals(BorderStyle.NONE, - cst.getTemplateProperty(i, j, CellUtil.BORDER_TOP)); + cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); assertEquals(BorderStyle.NONE, - cst.getTemplateProperty(i, j, CellUtil.BORDER_BOTTOM)); + cst.getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); assertEquals(BorderStyle.NONE, - cst.getTemplateProperty(i, j, CellUtil.BORDER_LEFT)); + cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); assertEquals(BorderStyle.NONE, - cst.getTemplateProperty(i, j, CellUtil.BORDER_RIGHT)); + cst.getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); } } } From 20907fc5b466b8a301b4081552e3e2d70c6bc990 Mon Sep 17 00:00:00 2001 From: Mark Murphy Date: Mon, 1 Aug 2016 04:21:14 +0000 Subject: [PATCH 020/157] revert changes made in r1754691 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754700 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/ss/examples/DrawingBorders.java | 112 -- .../org/apache/poi/ss/util/BorderExtent.java | 85 -- .../org/apache/poi/ss/util/CellAddress.java | 9 - .../apache/poi/ss/util/CellStyleTemplate.java | 977 ------------------ .../poi/ss/util/TestCellStyleTemplate.java | 892 ---------------- 5 files changed, 2075 deletions(-) delete mode 100644 src/examples/src/org/apache/poi/ss/examples/DrawingBorders.java delete mode 100644 src/java/org/apache/poi/ss/util/BorderExtent.java delete mode 100644 src/java/org/apache/poi/ss/util/CellStyleTemplate.java delete mode 100644 src/testcases/org/apache/poi/ss/util/TestCellStyleTemplate.java diff --git a/src/examples/src/org/apache/poi/ss/examples/DrawingBorders.java b/src/examples/src/org/apache/poi/ss/examples/DrawingBorders.java deleted file mode 100644 index d8b0927f7..000000000 --- a/src/examples/src/org/apache/poi/ss/examples/DrawingBorders.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * ==================================================================== - * 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.ss.examples; - -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.IndexedColors; -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.BorderExtent; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellStyleTemplate; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -/** - * Excel Border Drawing - examples - * - *

- * Partly based on the code snippets from - * org.apache.poi.ss.examples.ConditionalFormats - *

- */ -public class DrawingBorders { - - public static void main(String[] args) throws IOException { - Workbook wb; - - if (args.length > 0 && args[0].equals("-xls")) { - wb = new HSSFWorkbook(); - } else { - wb = new XSSFWorkbook(); - } - - // add a sheet, and put some values into it - Sheet sh1 = wb.createSheet("Sheet1"); - Row r = sh1.createRow(0); - Cell c = r.createCell(1); - c.setCellValue("All Borders Medium Width"); - r = sh1.createRow(4); - c = r.createCell(1); - c.setCellValue("Medium Outside / Thin Inside Borders"); - r = sh1.createRow(8); - c = r.createCell(1); - c.setCellValue("Colored Borders"); - - // draw borders (three 3x3 grids) - CellStyleTemplate cst = new CellStyleTemplate(); - // #1) these borders will all be medium in default color - cst.drawBorders(CellRangeAddress.valueOf("B2:D5"), - BorderStyle.MEDIUM, BorderExtent.ALL); - // #2) these cells will have medium outside borders and thin inside borders - cst.drawBorders(CellRangeAddress.valueOf("E2:G5"), - BorderStyle.MEDIUM, BorderExtent.OUTSIDE); - cst.drawBorders(CellRangeAddress.valueOf("E2:G5"), - BorderStyle.THIN, BorderExtent.INSIDE); - // #3) these cells will all be medium weight with different colors for the - // outside, inside horizontal, and inside vertical borders. The center - // cell will have no borders. - cst.drawBorders(CellRangeAddress.valueOf("I2:K5"), - BorderStyle.MEDIUM, IndexedColors.RED.getIndex(), - BorderExtent.OUTSIDE); - cst.drawBorders(CellRangeAddress.valueOf("I2:K5"), - BorderStyle.MEDIUM, IndexedColors.BLUE.getIndex(), - BorderExtent.INSIDE_VERTICAL); - cst.drawBorders(CellRangeAddress.valueOf("I2:K5"), - BorderStyle.MEDIUM, IndexedColors.GREEN.getIndex(), - BorderExtent.INSIDE_HORIZONTAL); - cst.drawBorders(CellRangeAddress.valueOf("J3"), - BorderStyle.NONE, - BorderExtent.ALL); - - // apply borders to sheet - cst.applyBorders(sh1); - - // add another sheet and apply the borders to it - Sheet sh2 = wb.createSheet("Sheet2"); - cst.applyBorders(sh2); - - // Write the output to a file - String file = "db-poi.xls"; - if (wb instanceof XSSFWorkbook) - file += "x"; - FileOutputStream out = new FileOutputStream(file); - wb.write(out); - out.close(); - wb.close(); - System.out.println("Generated: " + file); - } - -} diff --git a/src/java/org/apache/poi/ss/util/BorderExtent.java b/src/java/org/apache/poi/ss/util/BorderExtent.java deleted file mode 100644 index d9517b34e..000000000 --- a/src/java/org/apache/poi/ss/util/BorderExtent.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.apache.poi.ss.util; - -public enum BorderExtent { - /** - * No properties defined. This can be used to remove existing - * properties. - */ - NONE, - - /** - * All borders, that is top, bottom, left and right, including interior - * borders for the range. Does not include diagonals which are different - * and not implemented here. - */ - ALL, - - /** - * All inside borders. This is top, bottom, left, and right borders, but - * restricted to the interior borders for the range. For a range of one - * cell, this will produce no borders. - */ - INSIDE, - - /** - * All outside borders. That is top, bottom, left and right borders that - * bound the range only. - */ - OUTSIDE, - - /** - * This is just the top border for the range. No interior borders will - * be produced. - */ - TOP, - - /** - * This is just the bottom border for the range. No interior borders - * will be produced. - */ - BOTTOM, - - /** - * This is just the left border for the range, no interior borders will - * be produced. - */ - LEFT, - - /** - * This is just the right border for the range, no interior borders will - * be produced. - */ - RIGHT, - - /** - * This is all horizontal borders for the range, including interior and - * outside borders. - */ - HORIZONTAL, - - /** - * This is just the interior horizontal borders for the range. - */ - INSIDE_HORIZONTAL, - - /** - * This is just the outside horizontal borders for the range. - */ - OUTSIDE_HORIZONTAL, - - /** - * This is all vertical borders for the range, including interior and - * outside borders. - */ - VERTICAL, - - /** - * This is just the interior vertical borders for the range. - */ - INSIDE_VERTICAL, - - /** - * This is just the outside vertical borders for the range. - */ - OUTSIDE_VERTICAL -} diff --git a/src/java/org/apache/poi/ss/util/CellAddress.java b/src/java/org/apache/poi/ss/util/CellAddress.java index 3014891ab..b6307556f 100644 --- a/src/java/org/apache/poi/ss/util/CellAddress.java +++ b/src/java/org/apache/poi/ss/util/CellAddress.java @@ -96,15 +96,6 @@ public class CellAddress implements Comparable { this(cell.getRowIndex(), cell.getColumnIndex()); } - /** - * Create a new CellAddress object. - * - * @param address a cell address - */ - public CellAddress(CellAddress address) { - this(address._row, address._col); - } - /** * Get the cell address row * diff --git a/src/java/org/apache/poi/ss/util/CellStyleTemplate.java b/src/java/org/apache/poi/ss/util/CellStyleTemplate.java deleted file mode 100644 index 64e7d790d..000000000 --- a/src/java/org/apache/poi/ss/util/CellStyleTemplate.java +++ /dev/null @@ -1,977 +0,0 @@ -/* ==================================================================== - 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.ss.util; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; - -/** - *

- * A {@link CellStyleTemplate} is a template that can be applied to any sheet in - * a project. It contains all the border type and color attributes needed to - * draw all the borders for a single sheet. That template can be applied to any - * sheet in any workbook. - * - * This class requires the full spreadsheet to be in memory so - * {@link SXSSFWorkbook} Spreadsheets are not supported. The same - * {@link CellStyleTemplate} can, however, be applied to both - * {@link org.apache.poi.hssf.usermodel.HSSFWorkbook}, and Workbook objects - * if necessary. Portions of the border that fall outside the max range of the - * {@link HSSFWorkbook} sheet are ignored. - *

- * - *

- * This would replace {@link RegionUtil}. - *

- */ -public final class CellStyleTemplate { - - /** - * This is a list of cell properties for one shot application to a range of - * cells at a later time. - */ - private Map> _cellStyleTemplate; - - /** - * Create a new Cell Style Template - */ - public CellStyleTemplate() { - _cellStyleTemplate = new HashMap>(); - } - - /** - * Create a new Cell Style Template - * - * @param other CellStyleTemplate to copy - */ - public CellStyleTemplate(CellStyleTemplate other) { - this(); - for (Map.Entry> entry : other._cellStyleTemplate.entrySet()) { - CellAddress ca = new CellAddress(entry.getKey()); - Map newProperties = new HashMap(); - for (Map.Entry property : entry.getValue().entrySet()) { - if (property.getValue() instanceof Short) { - newProperties.put(property.getKey(), new Short(getShort(property.getValue()))); - } else { - newProperties.put(property.getKey(), property.getValue()); - } - } - _cellStyleTemplate.put(ca, newProperties); - } - } - - /** - * Draws a group of cell borders for a cell range. The borders are not - * applied to the cells at this time, just the template is drawn. To apply - * the drawn borders to a sheet, use {@link #applyBorders}. - * - * @param range - * - {@link CellRangeAddress} range of cells on which borders are - * drawn. - * @param borderStyle - * - Type of border to draw. {@link BorderStyle}. - * @param extent - * - {@link BorderExtent} of the borders to be applied. - */ - public void drawBorders(CellRangeAddress range, BorderStyle borderStyle, - BorderExtent extent) { - switch (extent) { - case NONE: - removeBorders(range); - break; - case ALL: - drawHorizontalBorders(range, borderStyle, BorderExtent.ALL); - drawVerticalBorders(range, borderStyle, BorderExtent.ALL); - break; - case INSIDE: - drawHorizontalBorders(range, borderStyle, BorderExtent.INSIDE); - drawVerticalBorders(range, borderStyle, BorderExtent.INSIDE); - break; - case OUTSIDE: - drawOutsideBorders(range, borderStyle, BorderExtent.ALL); - break; - case TOP: - drawTopBorder(range, borderStyle); - break; - case BOTTOM: - drawBottomBorder(range, borderStyle); - break; - case LEFT: - drawLeftBorder(range, borderStyle); - break; - case RIGHT: - drawRightBorder(range, borderStyle); - break; - case HORIZONTAL: - drawHorizontalBorders(range, borderStyle, BorderExtent.ALL); - break; - case INSIDE_HORIZONTAL: - drawHorizontalBorders(range, borderStyle, BorderExtent.INSIDE); - break; - case OUTSIDE_HORIZONTAL: - drawOutsideBorders(range, borderStyle, BorderExtent.HORIZONTAL); - break; - case VERTICAL: - drawVerticalBorders(range, borderStyle, BorderExtent.ALL); - break; - case INSIDE_VERTICAL: - drawVerticalBorders(range, borderStyle, BorderExtent.INSIDE); - break; - case OUTSIDE_VERTICAL: - drawOutsideBorders(range, borderStyle, BorderExtent.VERTICAL); - break; - } - } - - /** - * Draws a group of cell borders for a cell range. The borders are not - * applied to the cells at this time, just the template is drawn. To apply - * the drawn borders to a sheet, use {@link #applyBorders}. - * - * @param range - * - {@link CellRangeAddress} range of cells on which borders are - * drawn. - * @param borderStyle - * - Type of border to draw. {@link BorderStyle}. - * @param color - * - Color index from {@link IndexedColors} used to draw the - * borders. Ignored if extent is {@link BorderExtent#NONE}. - * @param extent - * - {@link BorderExtent} of the borders to be applied. - */ - public void drawBorders(CellRangeAddress range, BorderStyle borderStyle, - short color, BorderExtent extent) { - drawBorders(range, borderStyle, extent); - if (borderStyle != BorderStyle.NONE) { - drawBorderColors(range, color, extent); - } - } - - /** - *

- * Draws the top border for a range of cells - *

- * - * @param range - * - {@link CellRangeAddress} range of cells on which borders are - * drawn. - * @param borderStyle - * - Type of border to draw. {@link BorderStyle}. - */ - private void drawTopBorder(CellRangeAddress range, BorderStyle borderStyle) { - int row = range.getFirstRow(); - int firstCol = range.getFirstColumn(); - int lastCol = range.getLastColumn(); - for (int i = firstCol; i <= lastCol; i++) { - addBorderStyle(row, i, CellUtil.BORDER_TOP, borderStyle); - if (borderStyle == BorderStyle.NONE && row > 0) { - addBorderStyle(row - 1, i, CellUtil.BORDER_BOTTOM, borderStyle); - } - } - } - - /** - *

- * Draws the bottom border for a range of cells - *

- * - * @param range - * - {@link CellRangeAddress} range of cells on which borders are - * drawn. - * @param borderStyle - * - Type of border to draw. {@link BorderStyle}. - */ - private void drawBottomBorder(CellRangeAddress range, BorderStyle borderStyle) { - int row = range.getLastRow(); - int firstCol = range.getFirstColumn(); - int lastCol = range.getLastColumn(); - for (int i = firstCol; i <= lastCol; i++) { - addBorderStyle(row, i, CellUtil.BORDER_BOTTOM, borderStyle); - if (borderStyle == BorderStyle.NONE - && row < SpreadsheetVersion.EXCEL2007.getMaxRows() - 1) { - addBorderStyle(row + 1, i, CellUtil.BORDER_TOP, borderStyle); - } - } - } - - /** - *

- * Draws the left border for a range of cells - *

- * - * @param range - * - {@link CellRangeAddress} range of cells on which borders are - * drawn. - * @param borderStyle - * - Type of border to draw. {@link BorderStyle}. - */ - private void drawLeftBorder(CellRangeAddress range, BorderStyle borderStyle) { - int firstRow = range.getFirstRow(); - int lastRow = range.getLastRow(); - int col = range.getFirstColumn(); - for (int i = firstRow; i <= lastRow; i++) { - addBorderStyle(i, col, CellUtil.BORDER_LEFT, borderStyle); - if (borderStyle == BorderStyle.NONE && col > 0) { - addBorderStyle(i, col - 1, CellUtil.BORDER_RIGHT, borderStyle); - } - } - } - - /** - *

- * Draws the right border for a range of cells - *

- * - * @param range - * - {@link CellRangeAddress} range of cells on which borders are - * drawn. - * @param borderStyle - * - Type of border to draw. {@link BorderStyle}. - */ - private void drawRightBorder(CellRangeAddress range, BorderStyle borderStyle) { - int firstRow = range.getFirstRow(); - int lastRow = range.getLastRow(); - int col = range.getLastColumn(); - for (int i = firstRow; i <= lastRow; i++) { - addBorderStyle(i, col, CellUtil.BORDER_RIGHT, borderStyle); - if (borderStyle == BorderStyle.NONE - && col < SpreadsheetVersion.EXCEL2007.getMaxColumns() - 1) { - addBorderStyle(i, col + 1, CellUtil.BORDER_LEFT, borderStyle); - } - } - } - - /** - *

- * Draws the outside borders for a range of cells. - *

- * - * @param range - * - {@link CellRangeAddress} range of cells on which borders are - * drawn. - * @param borderStyle - * - Type of border to draw. {@link BorderStyle}. - * @param extent - * - {@link CellStyleTemplate.BorderExtent} of the borders to be - * applied. Valid Values are: - *
    - *
  • CellBorder.Extent.ALL
  • - *
  • CellBorder.Extent.HORIZONTAL
  • - *
  • CellBorder.Extent.VERTICAL
  • - *
- */ - private void drawOutsideBorders(CellRangeAddress range, BorderStyle borderStyle, - BorderExtent extent) { - switch (extent) { - case ALL: - case HORIZONTAL: - case VERTICAL: - if (extent == BorderExtent.ALL || extent == BorderExtent.HORIZONTAL) { - drawTopBorder(range, borderStyle); - drawBottomBorder(range, borderStyle); - } - if (extent == BorderExtent.ALL || extent == BorderExtent.VERTICAL) { - drawLeftBorder(range, borderStyle); - drawRightBorder(range, borderStyle); - } - break; - default: - throw new IllegalArgumentException( - "Unsupported CellStyleTemplate.Extent, valid Extents are ALL, HORIZONTAL, and VERTICAL"); - } - } - - /** - *

- * Draws the horizontal borders for a range of cells. - *

- * - * @param range - * - {@link CellRangeAddress} range of cells on which borders are - * drawn. - * @param borderStyle - * - Type of border to draw. {@link BorderStyle}. - * @param extent - * - {@link CellStyleTemplate.BorderExtent} of the borders to be - * applied. Valid Values are: - *
    - *
  • CellBorder.Extent.ALL
  • - *
  • CellBorder.Extent.INSIDE
  • - *
- */ - private void drawHorizontalBorders(CellRangeAddress range, BorderStyle borderStyle, - BorderExtent extent) { - switch (extent) { - case ALL: - case INSIDE: - int firstRow = range.getFirstRow(); - int lastRow = range.getLastRow(); - int firstCol = range.getFirstColumn(); - int lastCol = range.getLastColumn(); - for (int i = firstRow; i <= lastRow; i++) { - CellRangeAddress row = new CellRangeAddress(i, i, firstCol, - lastCol); - if (extent == BorderExtent.ALL || i > firstRow) { - drawTopBorder(row, borderStyle); - } - if (extent == BorderExtent.ALL || i < lastRow) { - drawBottomBorder(row, borderStyle); - } - } - break; - default: - throw new IllegalArgumentException( - "Unsupported CellStyleTemplate.Extent, valid Extents are ALL and INSIDE"); - } - } - - /** - *

- * Draws the vertical borders for a range of cells. - *

- * - * @param range - * - {@link CellRangeAddress} range of cells on which borders are - * drawn. - * @param borderStyle - * - Type of border to draw. {@link BorderStyle}. - * @param extent - * - {@link CellStyleTemplate.BorderExtent} of the borders to be - * applied. Valid Values are: - *
    - *
  • CellBorder.Extent.ALL
  • - *
  • CellBorder.Extent.INSIDE
  • - *
- */ - private void drawVerticalBorders(CellRangeAddress range, BorderStyle borderStyle, - BorderExtent extent) { - switch (extent) { - case ALL: - case INSIDE: - int firstRow = range.getFirstRow(); - int lastRow = range.getLastRow(); - int firstCol = range.getFirstColumn(); - int lastCol = range.getLastColumn(); - for (int i = firstCol; i <= lastCol; i++) { - CellRangeAddress row = new CellRangeAddress(firstRow, lastRow, - i, i); - if (extent == BorderExtent.ALL || i > firstCol) { - drawLeftBorder(row, borderStyle); - } - if (extent == BorderExtent.ALL || i < lastCol) { - drawRightBorder(row, borderStyle); - } - } - break; - default: - throw new IllegalArgumentException( - "Unsupported CellStyleTemplate.Extent, valid Extents are ALL and INSIDE"); - } - } - - /** - * Removes all border properties from this {@link CellStyleTemplate} for the - * specified range. - * - * @parm range - {@link CellRangeAddress} range of cells to remove borders. - */ - private void removeBorders(CellRangeAddress range) { - Set properties = new HashSet(); - properties.add(CellUtil.BORDER_TOP); - properties.add(CellUtil.BORDER_BOTTOM); - properties.add(CellUtil.BORDER_LEFT); - properties.add(CellUtil.BORDER_RIGHT); - for (int row = range.getFirstRow(); row <= range.getLastRow(); row++) { - for (int col = range.getFirstColumn(); col <= range - .getLastColumn(); col++) { - removeProperties(row, col, properties); - } - } - removeBorderColors(range); - } - - /** - * Applies the drawn borders to a Sheet. The borders that are applied are - * the ones that have been drawn by the {@link #drawBorders} and - * {@link #drawBorderColors} methods. - * - * @param sheet - * - {@link Sheet} on which to apply borders - */ - public void applyBorders(Sheet sheet) { - Workbook wb = sheet.getWorkbook(); - for (Map.Entry> entry : _cellStyleTemplate - .entrySet()) { - CellAddress cellAddress = entry.getKey(); - if (cellAddress.getRow() < wb.getSpreadsheetVersion().getMaxRows() - && cellAddress.getColumn() < wb.getSpreadsheetVersion() - .getMaxColumns()) { - Map properties = entry.getValue(); - Row row = CellUtil.getRow(cellAddress.getRow(), sheet); - Cell cell = CellUtil.getCell(row, cellAddress.getColumn()); - CellUtil.setCellStyleProperties(cell, properties); - } - } - } - - /** - * Sets the color for a group of cell borders for a cell range. The borders - * are not applied to the cells at this time, just the template is drawn. If - * the borders do not exist, a BORDER_THIN border is used. To apply the - * drawn borders to a sheet, use {@link #applyBorders}. - * - * @param range - * - {@link CellRangeAddress} range of cells on which colors are - * set. - * @param color - * - Color index from {@link IndexedColors} used to draw the - * borders. - * @param extent - * - {@link BorderExtent} of the borders for which colors are set. - */ - public void drawBorderColors(CellRangeAddress range, short color, - BorderExtent extent) { - switch (extent) { - case NONE: - removeBorderColors(range); - break; - case ALL: - drawHorizontalBorderColors(range, color, BorderExtent.ALL); - drawVerticalBorderColors(range, color, BorderExtent.ALL); - break; - case INSIDE: - drawHorizontalBorderColors(range, color, BorderExtent.INSIDE); - drawVerticalBorderColors(range, color, BorderExtent.INSIDE); - break; - case OUTSIDE: - drawOutsideBorderColors(range, color, BorderExtent.ALL); - break; - case TOP: - drawTopBorderColor(range, color); - break; - case BOTTOM: - drawBottomBorderColor(range, color); - break; - case LEFT: - drawLeftBorderColor(range, color); - break; - case RIGHT: - drawRightBorderColor(range, color); - break; - case HORIZONTAL: - drawHorizontalBorderColors(range, color, BorderExtent.ALL); - break; - case INSIDE_HORIZONTAL: - drawHorizontalBorderColors(range, color, BorderExtent.INSIDE); - break; - case OUTSIDE_HORIZONTAL: - drawOutsideBorderColors(range, color, BorderExtent.HORIZONTAL); - break; - case VERTICAL: - drawVerticalBorderColors(range, color, BorderExtent.ALL); - break; - case INSIDE_VERTICAL: - drawVerticalBorderColors(range, color, BorderExtent.INSIDE); - break; - case OUTSIDE_VERTICAL: - drawOutsideBorderColors(range, color, BorderExtent.VERTICAL); - break; - } - } - - /** - *

- * Sets the color of the top border for a range of cells. - *

- * - * @param range - * - {@link CellRangeAddress} range of cells on which colors are - * set. - * @param color - * - Color index from {@link IndexedColors} used to draw the - * borders. - */ - private void drawTopBorderColor(CellRangeAddress range, short color) { - int row = range.getFirstRow(); - int firstCol = range.getFirstColumn(); - int lastCol = range.getLastColumn(); - for (int i = firstCol; i <= lastCol; i++) { - if (!borderIsSet(new CellAddress(row, i), CellUtil.BORDER_TOP)) { - drawTopBorder(new CellRangeAddress(row, row, i, i), - BorderStyle.THIN); - } - addProperty(row, i, CellUtil.TOP_BORDER_COLOR, color); - } - } - - /** - *

- * Sets the color of the bottom border for a range of cells. - *

- * - * @param range - * - {@link CellRangeAddress} range of cells on which colors are - * set. - * @param color - * - Color index from {@link IndexedColors} used to draw the - * borders. - */ - private void drawBottomBorderColor(CellRangeAddress range, short color) { - int row = range.getLastRow(); - int firstCol = range.getFirstColumn(); - int lastCol = range.getLastColumn(); - for (int i = firstCol; i <= lastCol; i++) { - if (!borderIsSet(new CellAddress(row, i), CellUtil.BORDER_BOTTOM)) { - drawBottomBorder(new CellRangeAddress(row, row, i, i), - BorderStyle.THIN); - } - addProperty(row, i, CellUtil.BOTTOM_BORDER_COLOR, color); - } - } - - /** - *

- * Sets the color of the left border for a range of cells. - *

- * - * @param range - * - {@link CellRangeAddress} range of cells on which colors are - * set. - * @param color - * - Color index from {@link IndexedColors} used to draw the - * borders. - */ - private void drawLeftBorderColor(CellRangeAddress range, short color) { - int firstRow = range.getFirstRow(); - int lastRow = range.getLastRow(); - int col = range.getFirstColumn(); - for (int i = firstRow; i <= lastRow; i++) { - if (!borderIsSet(new CellAddress(i, col), CellUtil.BORDER_LEFT)) { - drawLeftBorder(new CellRangeAddress(i, i, col, col), - BorderStyle.THIN); - } - addProperty(i, col, CellUtil.LEFT_BORDER_COLOR, color); - } - } - - /** - *

- * Sets the color of the right border for a range of cells. If the border is - * not drawn, it defaults to BORDER_THIN - *

- * - * @param range - * - {@link CellRangeAddress} range of cells on which colors are - * set. - * @param color - * - Color index from {@link IndexedColors} used to draw the - * borders. - */ - private void drawRightBorderColor(CellRangeAddress range, short color) { - int firstRow = range.getFirstRow(); - int lastRow = range.getLastRow(); - int col = range.getLastColumn(); - for (int i = firstRow; i <= lastRow; i++) { - if (!borderIsSet(new CellAddress(i, col), CellUtil.BORDER_RIGHT)) { - drawRightBorder(new CellRangeAddress(i, i, col, col), - BorderStyle.THIN); - } - addProperty(i, col, CellUtil.RIGHT_BORDER_COLOR, color); - } - } - - /** - *

- * Sets the color of the outside borders for a range of cells. - *

- * - * @param range - * - {@link CellRangeAddress} range of cells on which colors are - * set. - * @param color - * - Color index from {@link IndexedColors} used to draw the - * borders. - * @param extent - * - {@link CellStyleTemplate.BorderExtent} of the borders for which - * colors are set. Valid Values are: - *
    - *
  • CellBorder.Extent.ALL
  • - *
  • CellBorder.Extent.HORIZONTAL
  • - *
  • CellBorder.Extent.VERTICAL
  • - *
- */ - private void drawOutsideBorderColors(CellRangeAddress range, short color, - BorderExtent extent) { - switch (extent) { - case ALL: - case HORIZONTAL: - case VERTICAL: - if (extent == BorderExtent.ALL || extent == BorderExtent.HORIZONTAL) { - drawTopBorderColor(range, color); - drawBottomBorderColor(range, color); - } - if (extent == BorderExtent.ALL || extent == BorderExtent.VERTICAL) { - drawLeftBorderColor(range, color); - drawRightBorderColor(range, color); - } - break; - default: - throw new IllegalArgumentException( - "Unsupported CellStyleTemplate.Extent, valid Extents are ALL, HORIZONTAL, and VERTICAL"); - } - } - - /** - *

- * Sets the color of the horizontal borders for a range of cells. - *

- * - * @param range - * - {@link CellRangeAddress} range of cells on which colors are - * set. - * @param color - * - Color index from {@link IndexedColors} used to draw the - * borders. - * @param extent - * - {@link CellStyleTemplate.BorderExtent} of the borders for which - * colors are set. Valid Values are: - *
    - *
  • CellBorder.Extent.ALL
  • - *
  • CellBorder.Extent.INSIDE
  • - *
- */ - private void drawHorizontalBorderColors(CellRangeAddress range, short color, - BorderExtent extent) { - switch (extent) { - case ALL: - case INSIDE: - int firstRow = range.getFirstRow(); - int lastRow = range.getLastRow(); - int firstCol = range.getFirstColumn(); - int lastCol = range.getLastColumn(); - for (int i = firstRow; i <= lastRow; i++) { - CellRangeAddress row = new CellRangeAddress(i, i, firstCol, - lastCol); - if (extent == BorderExtent.ALL || i > firstRow) { - drawTopBorderColor(row, color); - } - if (extent == BorderExtent.ALL || i < lastRow) { - drawBottomBorderColor(row, color); - } - } - break; - default: - throw new IllegalArgumentException( - "Unsupported CellStyleTemplate.Extent, valid Extents are ALL and INSIDE"); - } - } - - /** - *

- * Sets the color of the vertical borders for a range of cells. - *

- * - * @param range - * - {@link CellRangeAddress} range of cells on which colors are - * set. - * @param color - * - Color index from {@link IndexedColors} used to draw the - * borders. - * @param extent - * - {@link CellStyleTemplate.BorderExtent} of the borders for which - * colors are set. Valid Values are: - *
    - *
  • CellBorder.Extent.ALL
  • - *
  • CellBorder.Extent.INSIDE
  • - *
- */ - private void drawVerticalBorderColors(CellRangeAddress range, short color, - BorderExtent extent) { - switch (extent) { - case ALL: - case INSIDE: - int firstRow = range.getFirstRow(); - int lastRow = range.getLastRow(); - int firstCol = range.getFirstColumn(); - int lastCol = range.getLastColumn(); - for (int i = firstCol; i <= lastCol; i++) { - CellRangeAddress row = new CellRangeAddress(firstRow, lastRow, - i, i); - if (extent == BorderExtent.ALL || i > firstCol) { - drawLeftBorderColor(row, color); - } - if (extent == BorderExtent.ALL || i < lastCol) { - drawRightBorderColor(row, color); - } - } - break; - default: - throw new IllegalArgumentException( - "Unsupported CellStyleTemplate.Extent, valid Extents are ALL and INSIDE"); - } - } - - /** - * Removes all border properties from this {@link CellStyleTemplate} for the - * specified range. - * - * @parm range - {@link CellRangeAddress} range of cells to remove borders. - */ - private void removeBorderColors(CellRangeAddress range) { - Set properties = new HashSet(); - properties.add(CellUtil.TOP_BORDER_COLOR); - properties.add(CellUtil.BOTTOM_BORDER_COLOR); - properties.add(CellUtil.LEFT_BORDER_COLOR); - properties.add(CellUtil.RIGHT_BORDER_COLOR); - for (int row = range.getFirstRow(); row <= range.getLastRow(); row++) { - for (int col = range.getFirstColumn(); col <= range - .getLastColumn(); col++) { - removeProperties(row, col, properties); - } - } - } - - /** - * Adds a property to this {@link CellStyleTemplate} for a given cell - * - * @param row - * @param col - * @param property - * @param value - */ - private void addProperty(int row, int col, String property, Object value) { - CellAddress cell = new CellAddress(row, col); - Map cellProperties = _cellStyleTemplate.get(cell); - if (cellProperties == null) { - cellProperties = new HashMap(); - } - cellProperties.put(property, value); - _cellStyleTemplate.put(cell, cellProperties); - } - - /** - * Adds a property to this {@link CellStyleTemplate} for a given cell - * - * @param row - * @param col - * @param property - * @param value - */ - private void addProperty(int row, int col, String property, short value) { - addProperty(row, col, property, Short.valueOf(value)); - } - - /** - * Adds a property to this {@link CellStyleTemplate} for a given cell - * - * @param row - * @param col - * @param borderProperty - * @param borderStyle - */ - private void addBorderStyle(int row, int col, String borderProperty, BorderStyle borderStyle) { - addProperty(row, col, borderProperty, borderStyle); - } - - /** - * Removes a set of properties from this {@link CellStyleTemplate} for a - * given cell - * - * @param row - * @param col - * @param properties - */ - private void removeProperties(int row, int col, Set properties) { - CellAddress cell = new CellAddress(row, col); - Map cellProperties = _cellStyleTemplate.get(cell); - if (cellProperties != null) { - cellProperties.keySet().removeAll(properties); - if (cellProperties.isEmpty()) { - _cellStyleTemplate.remove(cell); - } else { - _cellStyleTemplate.put(cell, cellProperties); - } - } - } - - /** - * Retrieves the number of borders assigned to a cell - * - * @param cell - */ - public int getNumBorders(CellAddress cell) { - Map cellProperties = _cellStyleTemplate.get(cell); - if (cellProperties == null) { - return 0; - } - - int count = 0; - for (String property : cellProperties.keySet()) { - if (property.equals(CellUtil.BORDER_TOP)) - count += 1; - if (property.equals(CellUtil.BORDER_BOTTOM)) - count += 1; - if (property.equals(CellUtil.BORDER_LEFT)) - count += 1; - if (property.equals(CellUtil.BORDER_RIGHT)) - count += 1; - } - return count; - } - - /** - * Retrieves the number of borders assigned to a cell - * - * @param row - * @param col - */ - public int getNumBorders(int row, int col) { - return getNumBorders(new CellAddress(row, col)); - } - - /** - * Retrieves the number of border colors assigned to a cell - * - * @param cell - */ - public int getNumBorderColors(CellAddress cell) { - Map cellProperties = _cellStyleTemplate.get(cell); - if (cellProperties == null) { - return 0; - } - - int count = 0; - for (String property : cellProperties.keySet()) { - if (property.equals(CellUtil.TOP_BORDER_COLOR)) - count += 1; - if (property.equals(CellUtil.BOTTOM_BORDER_COLOR)) - count += 1; - if (property.equals(CellUtil.LEFT_BORDER_COLOR)) - count += 1; - if (property.equals(CellUtil.RIGHT_BORDER_COLOR)) - count += 1; - } - return count; - } - - /** - * Retrieves the number of border colors assigned to a cell - * - * @param row - * @param col - */ - public int getNumBorderColors(int row, int col) { - return getNumBorderColors(new CellAddress(row, col)); - } - - /** - * Retrieves a template property as a short for a given cell - * - * @param cell - * @param property - */ - public short getTemplateProperty(CellAddress cell, String property) { - short value = 0; - Map cellProperties = _cellStyleTemplate.get(cell); - if (cellProperties != null) { - Object obj = cellProperties.get(property); - if (obj != null) { - value = getShort(obj); - } - } - return value; - } - - /** - * Retrieves a template property as a short for a given cell - * - * @param row - * @param col - * @param property - */ - public short getTemplateProperty(int row, int col, String property) { - return getTemplateProperty(new CellAddress(row, col), property); - } - - /** - * Retrieves the border style for a given cell - * - * @param cell - * @param property - */ - public BorderStyle getBorderStyle(CellAddress cell, String property) { - Map cellProperties = _cellStyleTemplate.get(cell); - if (cellProperties != null) { - Object obj = cellProperties.get(property); - if (obj instanceof BorderStyle) { - return (BorderStyle) obj; - } - } - return null; - } - - /** - * Retrieves the border style for a given cell - * - * @param row - * @param col - * @param property - */ - public BorderStyle getBorderStyle(int row, int col, String property) { - return getBorderStyle(new CellAddress(row, col), property); - } - - /** - * Converts a Short object to a short value or 0 if the object is not a - * Short - * - * @param value - * @return short - */ - private static short getShort(Object value) { - if (value instanceof Short) { - return ((Short) value).shortValue(); - } - return 0; - } - - /** - * Returns true if the specified cell border is has been set, and is not {@link BorderStyle.NONE} - * - * @param cell - * - {@link CellAddress} of cell to test - * @param cellBorder - * - String constant from {@link CellUtil} indicating which border to test - * @return boolean - */ - private boolean borderIsSet(CellAddress cell, String cellBorder) { - Object borderLineStyle = getTemplateProperty(cell, cellBorder); - return (borderLineStyle != null) && (borderLineStyle != BorderStyle.NONE); - } -} diff --git a/src/testcases/org/apache/poi/ss/util/TestCellStyleTemplate.java b/src/testcases/org/apache/poi/ss/util/TestCellStyleTemplate.java deleted file mode 100644 index d9b8f9060..000000000 --- a/src/testcases/org/apache/poi/ss/util/TestCellStyleTemplate.java +++ /dev/null @@ -1,892 +0,0 @@ -package org.apache.poi.ss.util; - -import static org.junit.Assert.assertEquals; - -import java.io.IOException; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.junit.Test; - -/** - * Tests Spreadsheet CellStyleTemplate - * - * @see org.apache.poi.ss.util.CellStyleTemplate - */ -public final class TestCellStyleTemplate { - @Test - public void getNumBorders() throws IOException { - CellRangeAddress a1 = CellRangeAddress.valueOf("A1"); - CellStyleTemplate cst = new CellStyleTemplate(); - cst.drawBorders(a1, BorderStyle.THIN, BorderExtent.TOP); - assertEquals(1, cst.getNumBorders(0, 0)); - cst.drawBorders(a1, BorderStyle.MEDIUM, BorderExtent.BOTTOM); - assertEquals(2, cst.getNumBorders(0, 0)); - cst.drawBorders(a1, BorderStyle.MEDIUM, BorderExtent.NONE); - assertEquals(0, cst.getNumBorders(0, 0)); - } - - @Test - public void getNumBorderColors() throws IOException { - CellRangeAddress a1 = CellRangeAddress.valueOf("A1"); - CellStyleTemplate cst = new CellStyleTemplate(); - cst.drawBorderColors(a1, IndexedColors.RED.getIndex(), BorderExtent.TOP); - assertEquals(1, cst.getNumBorderColors(0, 0)); - cst.drawBorderColors(a1, IndexedColors.RED.getIndex(), BorderExtent.BOTTOM); - assertEquals(2, cst.getNumBorderColors(0, 0)); - cst.drawBorderColors(a1, IndexedColors.RED.getIndex(), BorderExtent.NONE); - assertEquals(0, cst.getNumBorderColors(0, 0)); - } - - @Test - public void getTemplateProperties() throws IOException { - CellRangeAddress a1 = CellRangeAddress.valueOf("A1"); - CellStyleTemplate cst = new CellStyleTemplate(); - cst.drawBorders(a1, BorderStyle.THIN, BorderExtent.TOP); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(0, 0, CellUtil.BORDER_TOP)); - cst.drawBorders(a1, BorderStyle.MEDIUM, BorderExtent.BOTTOM); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(0, 0, CellUtil.BORDER_BOTTOM)); - cst.drawBorderColors(a1, IndexedColors.RED.getIndex(), BorderExtent.TOP); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(0, 0, CellUtil.TOP_BORDER_COLOR)); - cst.drawBorderColors(a1, IndexedColors.BLUE.getIndex(), BorderExtent.BOTTOM); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(0, 0, CellUtil.BOTTOM_BORDER_COLOR)); - } - - @Test - public void drawBorders() throws IOException { - CellRangeAddress a1c3 = CellRangeAddress.valueOf("A1:C3"); - CellStyleTemplate cst = new CellStyleTemplate(); - cst.drawBorders(a1c3, BorderStyle.THIN, - BorderExtent.ALL); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - assertEquals(4, cst.getNumBorders(i, j)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); - } - } - cst.drawBorders(a1c3, BorderStyle.MEDIUM, - BorderExtent.OUTSIDE); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - assertEquals(4, cst.getNumBorders(i, j)); - if (i == 0) { - if (j == 0) { - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, - CellUtil.BORDER_TOP)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_BOTTOM)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, - CellUtil.BORDER_LEFT)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_RIGHT)); - } else if (j == 2) { - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, - CellUtil.BORDER_TOP)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_BOTTOM)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_LEFT)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, - CellUtil.BORDER_RIGHT)); - } else { - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, - CellUtil.BORDER_TOP)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_BOTTOM)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_LEFT)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_RIGHT)); - } - } else if (i == 2) { - if (j == 0) { - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_TOP)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, - CellUtil.BORDER_BOTTOM)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, - CellUtil.BORDER_LEFT)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_RIGHT)); - } else if (j == 2) { - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_TOP)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, - CellUtil.BORDER_BOTTOM)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_LEFT)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, - CellUtil.BORDER_RIGHT)); - } else { - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_TOP)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, - CellUtil.BORDER_BOTTOM)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_LEFT)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_RIGHT)); - } - } else { - if (j == 0) { - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_TOP)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_BOTTOM)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, - CellUtil.BORDER_LEFT)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_RIGHT)); - } else if (j == 2) { - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_TOP)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_BOTTOM)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_LEFT)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, - CellUtil.BORDER_RIGHT)); - } else { - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_TOP)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_BOTTOM)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_LEFT)); - assertEquals(BorderStyle.THIN, - cst.getBorderStyle(i, j, - CellUtil.BORDER_RIGHT)); - } - } - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - assertEquals(0, cst.getNumBorders(i, j)); - } - } - cst.drawBorders(a1c3, BorderStyle.MEDIUM, - BorderExtent.TOP); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - if (i == 0) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); - } else { - assertEquals(0, cst.getNumBorders(i, j)); - } - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorders(a1c3, BorderStyle.MEDIUM, - BorderExtent.BOTTOM); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - if (i == 2) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(BorderStyle.MEDIUM, cst - .getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); - } else { - assertEquals(0, cst.getNumBorders(i, j)); - } - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorders(a1c3, BorderStyle.MEDIUM, - BorderExtent.LEFT); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - if (j == 0) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); - } else { - assertEquals(0, cst.getNumBorders(i, j)); - } - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorders(a1c3, BorderStyle.MEDIUM, - BorderExtent.RIGHT); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - if (j == 2) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(BorderStyle.MEDIUM, cst - .getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); - } else { - assertEquals(0, cst.getNumBorders(i, j)); - } - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorders(a1c3, BorderStyle.MEDIUM, - BorderExtent.HORIZONTAL); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - assertEquals(2, cst.getNumBorders(i, j)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorders(a1c3, BorderStyle.MEDIUM, - BorderExtent.INSIDE_HORIZONTAL); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - if (i == 0) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(BorderStyle.MEDIUM, cst - .getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); - } else if (i == 2) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); - } else { - assertEquals(2, cst.getNumBorders(i, j)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); - assertEquals(BorderStyle.MEDIUM, cst - .getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); - } - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorders(a1c3, BorderStyle.MEDIUM, - BorderExtent.OUTSIDE_HORIZONTAL); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - if (i == 0) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); - } else if (i == 2) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(BorderStyle.MEDIUM, cst - .getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); - } else { - assertEquals(0, cst.getNumBorders(i, j)); - } - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorders(a1c3, BorderStyle.MEDIUM, - BorderExtent.VERTICAL); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - assertEquals(2, cst.getNumBorders(i, j)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorders(a1c3, BorderStyle.MEDIUM, - BorderExtent.INSIDE_VERTICAL); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - if (j == 0) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(BorderStyle.MEDIUM, cst - .getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); - } else if (j == 2) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); - } else { - assertEquals(2, cst.getNumBorders(i, j)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); - assertEquals(BorderStyle.MEDIUM, cst - .getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); - } - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorders(a1c3, BorderStyle.MEDIUM, - BorderExtent.OUTSIDE_VERTICAL); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - if (j == 0) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); - } else if (j == 2) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(BorderStyle.MEDIUM, cst - .getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); - } else { - assertEquals(0, cst.getNumBorders(i, j)); - } - } - } - } - - @Test - public void drawBorderColors() throws IOException { - CellRangeAddress a1c3 = CellRangeAddress.valueOf("A1:C3"); - CellStyleTemplate cst = new CellStyleTemplate(); - cst.drawBorderColors(a1c3, IndexedColors.RED.getIndex(), - BorderExtent.ALL); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - assertEquals(4, cst.getNumBorders(i, j)); - assertEquals(4, cst.getNumBorderColors(i, j)); - assertEquals(IndexedColors.RED.getIndex(), cst - .getTemplateProperty(i, j, CellUtil.TOP_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.BOTTOM_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), cst - .getTemplateProperty(i, j, CellUtil.LEFT_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.RIGHT_BORDER_COLOR)); - } - } - cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), - BorderExtent.OUTSIDE); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - assertEquals(4, cst.getNumBorders(i, j)); - assertEquals(4, cst.getNumBorderColors(i, j)); - if (i == 0) { - if (j == 0) { - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.TOP_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.BOTTOM_BORDER_COLOR)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.LEFT_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.RIGHT_BORDER_COLOR)); - } else if (j == 2) { - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.TOP_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.BOTTOM_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.LEFT_BORDER_COLOR)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.RIGHT_BORDER_COLOR)); - } else { - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.TOP_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.BOTTOM_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.LEFT_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.RIGHT_BORDER_COLOR)); - } - } else if (i == 2) { - if (j == 0) { - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.TOP_BORDER_COLOR)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.BOTTOM_BORDER_COLOR)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.LEFT_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.RIGHT_BORDER_COLOR)); - } else if (j == 2) { - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.TOP_BORDER_COLOR)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.BOTTOM_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.LEFT_BORDER_COLOR)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.RIGHT_BORDER_COLOR)); - } else { - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.TOP_BORDER_COLOR)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.BOTTOM_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.LEFT_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.RIGHT_BORDER_COLOR)); - } - } else { - if (j == 0) { - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.TOP_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.BOTTOM_BORDER_COLOR)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.LEFT_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.RIGHT_BORDER_COLOR)); - } else if (j == 2) { - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.TOP_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.BOTTOM_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.LEFT_BORDER_COLOR)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.RIGHT_BORDER_COLOR)); - } else { - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.TOP_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.BOTTOM_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.LEFT_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.RIGHT_BORDER_COLOR)); - } - } - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), - BorderExtent.NONE); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - assertEquals(0, cst.getNumBorders(i, j)); - assertEquals(0, cst.getNumBorderColors(i, j)); - } - } - cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), - BorderExtent.TOP); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - if (i == 0) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(1, cst.getNumBorderColors(i, j)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.TOP_BORDER_COLOR)); - } else { - assertEquals(0, cst.getNumBorders(i, j)); - assertEquals(0, cst.getNumBorderColors(i, j)); - } - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), - BorderExtent.BOTTOM); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - if (i == 2) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(1, cst.getNumBorderColors(i, j)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.BOTTOM_BORDER_COLOR)); - } else { - assertEquals(0, cst.getNumBorders(i, j)); - assertEquals(0, cst.getNumBorderColors(i, j)); - } - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), - BorderExtent.LEFT); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - if (j == 0) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(1, cst.getNumBorderColors(i, j)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.LEFT_BORDER_COLOR)); - } else { - assertEquals(0, cst.getNumBorders(i, j)); - assertEquals(0, cst.getNumBorderColors(i, j)); - } - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), - BorderExtent.RIGHT); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - if (j == 2) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(1, cst.getNumBorderColors(i, j)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.RIGHT_BORDER_COLOR)); - } else { - assertEquals(0, cst.getNumBorders(i, j)); - assertEquals(0, cst.getNumBorderColors(i, j)); - } - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), - BorderExtent.HORIZONTAL); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - assertEquals(2, cst.getNumBorders(i, j)); - assertEquals(2, cst.getNumBorderColors(i, j)); - assertEquals(IndexedColors.BLUE.getIndex(), cst - .getTemplateProperty(i, j, CellUtil.TOP_BORDER_COLOR)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.BOTTOM_BORDER_COLOR)); - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), - BorderExtent.INSIDE_HORIZONTAL); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - if (i == 0) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(1, cst.getNumBorderColors(i, j)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.BOTTOM_BORDER_COLOR)); - } else if (i == 2) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(1, cst.getNumBorderColors(i, j)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.TOP_BORDER_COLOR)); - } else { - assertEquals(2, cst.getNumBorders(i, j)); - assertEquals(2, cst.getNumBorderColors(i, j)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.TOP_BORDER_COLOR)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.BOTTOM_BORDER_COLOR)); - } - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), - BorderExtent.OUTSIDE_HORIZONTAL); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - if (i == 0) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(1, cst.getNumBorderColors(i, j)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.TOP_BORDER_COLOR)); - } else if (i == 2) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(1, cst.getNumBorderColors(i, j)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.BOTTOM_BORDER_COLOR)); - } else { - assertEquals(0, cst.getNumBorders(i, j)); - assertEquals(0, cst.getNumBorderColors(i, j)); - } - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), - BorderExtent.VERTICAL); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - assertEquals(2, cst.getNumBorders(i, j)); - assertEquals(2, cst.getNumBorderColors(i, j)); - assertEquals(IndexedColors.BLUE.getIndex(), cst - .getTemplateProperty(i, j, CellUtil.LEFT_BORDER_COLOR)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.RIGHT_BORDER_COLOR)); - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), - BorderExtent.INSIDE_VERTICAL); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - if (j == 0) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(1, cst.getNumBorderColors(i, j)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.RIGHT_BORDER_COLOR)); - } else if (j == 2) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(1, cst.getNumBorderColors(i, j)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.LEFT_BORDER_COLOR)); - } else { - assertEquals(2, cst.getNumBorders(i, j)); - assertEquals(2, cst.getNumBorderColors(i, j)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.LEFT_BORDER_COLOR)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.RIGHT_BORDER_COLOR)); - } - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.AUTOMATIC.getIndex(), - BorderExtent.NONE); - cst.drawBorderColors(a1c3, IndexedColors.BLUE.getIndex(), - BorderExtent.OUTSIDE_VERTICAL); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - if (j == 0) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(1, cst.getNumBorderColors(i, j)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.LEFT_BORDER_COLOR)); - } else if (j == 2) { - assertEquals(1, cst.getNumBorders(i, j)); - assertEquals(1, cst.getNumBorderColors(i, j)); - assertEquals(IndexedColors.BLUE.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.RIGHT_BORDER_COLOR)); - } else { - assertEquals(0, cst.getNumBorders(i, j)); - assertEquals(0, cst.getNumBorderColors(i, j)); - } - } - } - } - - @Test - public void drawBordersWithColors() throws IOException { - CellRangeAddress a1c3 = CellRangeAddress.valueOf("A1:C3"); - CellStyleTemplate cst = new CellStyleTemplate(); - - cst.drawBorders(a1c3, BorderStyle.MEDIUM, IndexedColors.RED.getIndex(), BorderExtent.ALL); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - assertEquals(4, cst.getNumBorders(i, j)); - assertEquals(4, cst.getNumBorderColors(i, j)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); - assertEquals(BorderStyle.MEDIUM, - cst.getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); - assertEquals(IndexedColors.RED.getIndex(), cst - .getTemplateProperty(i, j, CellUtil.TOP_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.BOTTOM_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), cst - .getTemplateProperty(i, j, CellUtil.LEFT_BORDER_COLOR)); - assertEquals(IndexedColors.RED.getIndex(), - cst.getTemplateProperty(i, j, - CellUtil.RIGHT_BORDER_COLOR)); - } - } - cst.drawBorders(a1c3, BorderStyle.NONE, BorderExtent.NONE); - cst.drawBorders(a1c3, BorderStyle.NONE, IndexedColors.RED.getIndex(), BorderExtent.ALL); - for (int i = 0; i <= 2; i++) { - for (int j = 0; j <= 2; j++) { - assertEquals(4, cst.getNumBorders(i, j)); - assertEquals(0, cst.getNumBorderColors(i, j)); - assertEquals(BorderStyle.NONE, - cst.getBorderStyle(i, j, CellUtil.BORDER_TOP)); - assertEquals(BorderStyle.NONE, - cst.getBorderStyle(i, j, CellUtil.BORDER_BOTTOM)); - assertEquals(BorderStyle.NONE, - cst.getBorderStyle(i, j, CellUtil.BORDER_LEFT)); - assertEquals(BorderStyle.NONE, - cst.getBorderStyle(i, j, CellUtil.BORDER_RIGHT)); - } - } - } - - @Test - public void applyBorders() throws IOException { - CellRangeAddress a1c3 = CellRangeAddress.valueOf("A1:C3"); - CellRangeAddress b2 = CellRangeAddress.valueOf("B2"); - CellStyleTemplate cst = new CellStyleTemplate(); - Workbook wb = new HSSFWorkbook(); - Sheet sheet = wb.createSheet(); - - cst.drawBorders(a1c3, BorderStyle.THIN, IndexedColors.RED.getIndex(), BorderExtent.ALL); - cst.applyBorders(sheet); - - for (Row row: sheet) { - for (Cell cell: row) { - CellStyle cs = cell.getCellStyle(); - assertEquals(BorderStyle.THIN, cs.getBorderTop()); - assertEquals(IndexedColors.RED.getIndex(), cs.getTopBorderColor()); - assertEquals(BorderStyle.THIN, cs.getBorderBottom()); - assertEquals(IndexedColors.RED.getIndex(), cs.getBottomBorderColor()); - assertEquals(BorderStyle.THIN, cs.getBorderLeft()); - assertEquals(IndexedColors.RED.getIndex(), cs.getLeftBorderColor()); - assertEquals(BorderStyle.THIN, cs.getBorderRight()); - assertEquals(IndexedColors.RED.getIndex(), cs.getRightBorderColor()); - } - } - - cst.drawBorders(b2, BorderStyle.NONE, BorderExtent.ALL); - cst.applyBorders(sheet); - - for (Row row: sheet) { - for (Cell cell: row) { - CellStyle cs = cell.getCellStyle(); - if (cell.getColumnIndex() != 1 || row.getRowNum() == 0) { - assertEquals(BorderStyle.THIN, cs.getBorderTop()); - assertEquals(IndexedColors.RED.getIndex(), cs.getTopBorderColor()); - } else { - assertEquals(BorderStyle.NONE, cs.getBorderTop()); - } - if (cell.getColumnIndex() != 1 || row.getRowNum() == 2) { - assertEquals(BorderStyle.THIN, cs.getBorderBottom()); - assertEquals(IndexedColors.RED.getIndex(), cs.getBottomBorderColor()); - } else { - assertEquals(BorderStyle.NONE, cs.getBorderBottom()); - } - if (cell.getColumnIndex() == 0 || row.getRowNum() != 1) { - assertEquals(BorderStyle.THIN, cs.getBorderLeft()); - assertEquals(IndexedColors.RED.getIndex(), cs.getLeftBorderColor()); - } else { - assertEquals(BorderStyle.NONE, cs.getBorderLeft()); - } - if (cell.getColumnIndex() == 2 || row.getRowNum() != 1) { - assertEquals(BorderStyle.THIN, cs.getBorderRight()); - assertEquals(IndexedColors.RED.getIndex(), cs.getRightBorderColor()); - } else { - assertEquals(BorderStyle.NONE, cs.getBorderRight()); - } - } - } - - wb.close(); - } -} From 5ddd0386405621691aa4f26b6f2fd962869b312e Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Mon, 1 Aug 2016 05:32:41 +0000 Subject: [PATCH 021/157] javadoc fix: incorrect deprecated replacement git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754702 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/ss/usermodel/CellStyle.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java/org/apache/poi/ss/usermodel/CellStyle.java b/src/java/org/apache/poi/ss/usermodel/CellStyle.java index c82ffb98e..b6c971979 100644 --- a/src/java/org/apache/poi/ss/usermodel/CellStyle.java +++ b/src/java/org/apache/poi/ss/usermodel/CellStyle.java @@ -81,7 +81,7 @@ public interface CellStyle { /** * vertically justified vertical alignment - * @deprecated POI 3.15 beta 3. Use {@link VerticalAlignment#TOP} instead. + * @deprecated POI 3.15 beta 3. Use {@link VerticalAlignment#JUSTIFY} instead. */ static final short VERTICAL_JUSTIFY = 0x3; //VerticalAlignment.JUSTIFY.getCode(); From b8f1906f2ae6939e0f309735665090fc26dee45d Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Mon, 1 Aug 2016 06:23:36 +0000 Subject: [PATCH 022/157] Rename and add missing license header git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754705 13f79535-47bb-0310-9956-ffa450edef68 --- ...kdayFuncTest.java => TestWeekdayFunc.java} | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) rename src/testcases/org/apache/poi/ss/formula/functions/{WeekdayFuncTest.java => TestWeekdayFunc.java} (83%) diff --git a/src/testcases/org/apache/poi/ss/formula/functions/WeekdayFuncTest.java b/src/testcases/org/apache/poi/ss/formula/functions/TestWeekdayFunc.java similarity index 83% rename from src/testcases/org/apache/poi/ss/formula/functions/WeekdayFuncTest.java rename to src/testcases/org/apache/poi/ss/formula/functions/TestWeekdayFunc.java index 3e0df8ce4..c6c797c18 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/WeekdayFuncTest.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestWeekdayFunc.java @@ -1,3 +1,20 @@ +/* ==================================================================== + 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.ss.formula.functions; import org.apache.poi.ss.formula.eval.*; @@ -6,12 +23,7 @@ import org.junit.Test; import static org.junit.Assert.*; -public class WeekdayFuncTest { - /** - * der 1. Januar 2008 die fortlaufende Zahl 39.448, da dieser Tag nach 39.448 Tagen - * auf den 01.01.1900 folgt. - */ - +public class TestWeekdayFunc { @Test public void testEvaluate() throws Exception { assertEquals(2.0, ((NumberEval)WeekdayFunc.instance.evaluate(new ValueEval[]{new NumberEval(1.0)}, 0, 0)).getNumberValue(), 0.001); From 984683ab4b44920c8be6af5779c246966cb4bcb4 Mon Sep 17 00:00:00 2001 From: David North Date: Mon, 1 Aug 2016 12:51:24 +0000 Subject: [PATCH 023/157] Fix zero-padding and handling of empty passwords (meaning protection on, but no password to remove it) for XSSF workbook protection. https://bz.apache.org/bugzilla/show_bug.cgi?id=59920 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754744 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/poifs/crypt/CryptoFunctions.java | 26 ++++++++++--------- .../usermodel/helpers/XSSFPaswordHelper.java | 4 +-- .../poi/xssf/usermodel/TestXSSFSheet.java | 25 ++++++++++++++++++ 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java b/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java index f681f3ad1..69f8d6768 100644 --- a/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java +++ b/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java @@ -374,20 +374,22 @@ public class CryptoFunctions { // SET Verifier TO 0x0000 short verifier = 0; - // FOR EACH PasswordByte IN PasswordArray IN REVERSE ORDER - for (int i = arrByteChars.length-1; i >= 0; i--) { - // SET Verifier TO Intermediate3 BITWISE XOR PasswordByte + if (!"".equals(password)) { + // FOR EACH PasswordByte IN PasswordArray IN REVERSE ORDER + for (int i = arrByteChars.length-1; i >= 0; i--) { + // SET Verifier TO Intermediate3 BITWISE XOR PasswordByte + verifier = rotateLeftBase15Bit(verifier); + verifier ^= arrByteChars[i]; + } + + // as we haven't prepended the password length into the input array + // we need to do it now separately ... verifier = rotateLeftBase15Bit(verifier); - verifier ^= arrByteChars[i]; + verifier ^= arrByteChars.length; + + // RETURN Verifier BITWISE XOR 0xCE4B + verifier ^= 0xCE4B; // (0x8000 | ('N' << 8) | 'K') } - - // as we haven't prepended the password length into the input array - // we need to do it now separately ... - verifier = rotateLeftBase15Bit(verifier); - verifier ^= arrByteChars.length; - - // RETURN Verifier BITWISE XOR 0xCE4B - verifier ^= 0xCE4B; // (0x8000 | ('N' << 8) | 'K') return verifier & 0xFFFF; } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java index c91049948..fd6e2dbd0 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java @@ -55,8 +55,8 @@ public class XSSFPaswordHelper { cur.toFirstContentToken(); if (hashAlgo == null) { int hash = CryptoFunctions.createXorVerifier1(password); - cur.insertAttributeWithValue(getAttrName(prefix, "password"), - Integer.toHexString(hash).toUpperCase(Locale.ROOT)); + cur.insertAttributeWithValue(getAttrName(prefix, "password"), + String.format(Locale.ROOT, "%04X", hash).toUpperCase(Locale.ROOT)); } else { SecureRandom random = new SecureRandom(); byte salt[] = random.generateSeed(16); diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java index a9b0d1f0b..689e999bc 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java @@ -80,6 +80,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXf; import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCalcMode; import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPane; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnsignedShortHex; public final class TestXSSFSheet extends BaseTestXSheet { @@ -1099,6 +1100,30 @@ public final class TestXSSFSheet extends BaseTestXSheet { wb.close(); } + @Test + public void protectSheet_emptyPassword() throws IOException { + XSSFWorkbook wb = new XSSFWorkbook(); + XSSFSheet sheet = wb.createSheet(); + CTSheetProtection pr = sheet.getCTWorksheet().getSheetProtection(); + assertNull("CTSheetProtection should be null by default", pr); + String password = ""; + sheet.protectSheet(password); + pr = sheet.getCTWorksheet().getSheetProtection(); + assertNotNull("CTSheetProtection should be not null", pr); + assertTrue("sheet protection should be on", pr.isSetSheet()); + assertTrue("object protection should be on", pr.isSetObjects()); + assertTrue("scenario protection should be on", pr.isSetScenarios()); + int hashVal = CryptoFunctions.createXorVerifier1(password); + STUnsignedShortHex xpassword = pr.xgetPassword(); + int actualVal = Integer.parseInt(xpassword.getStringValue(),16); + assertEquals("well known value for top secret hash should match", hashVal, actualVal); + + sheet.protectSheet(null); + assertNull("protectSheet(null) should unset CTSheetProtection", sheet.getCTWorksheet().getSheetProtection()); + + wb.close(); + } + @Test public void protectSheet_lowlevel_2013() throws IOException { String password = "test"; From 3c77adf9e8e919602d7a05a957e8c41556fbf2b9 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Mon, 1 Aug 2016 17:36:06 +0000 Subject: [PATCH 024/157] whitespace git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754782 13f79535-47bb-0310-9956-ffa450edef68 --- .../aggregates/RowRecordsAggregate.java | 786 +++++++++--------- 1 file changed, 393 insertions(+), 393 deletions(-) diff --git a/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java index 0319af64e..5551639b4 100644 --- a/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java +++ b/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java @@ -34,184 +34,184 @@ import org.apache.poi.ss.formula.FormulaShifter; * @author Jason Height (jheight at chariot dot net dot au) */ public final class RowRecordsAggregate extends RecordAggregate { - private int _firstrow = -1; - private int _lastrow = -1; - private final Map _rowRecords; - private final ValueRecordsAggregate _valuesAgg; - private final List _unknownRecords; - private final SharedValueManager _sharedValueManager; + private int _firstrow = -1; + private int _lastrow = -1; + private final Map _rowRecords; + private final ValueRecordsAggregate _valuesAgg; + private final List _unknownRecords; + private final SharedValueManager _sharedValueManager; - // Cache values to speed up performance of + // Cache values to speed up performance of // getStartRowNumberForBlock / getEndRowNumberForBlock, see Bugzilla 47405 private RowRecord[] _rowRecordValues = null; - /** Creates a new instance of ValueRecordsAggregate */ - public RowRecordsAggregate() { - this(SharedValueManager.createEmpty()); - } - private RowRecordsAggregate(SharedValueManager svm) { - if (svm == null) { - throw new IllegalArgumentException("SharedValueManager must be provided."); - } - _rowRecords = new TreeMap(); - _valuesAgg = new ValueRecordsAggregate(); - _unknownRecords = new ArrayList(); - _sharedValueManager = svm; - } + /** Creates a new instance of ValueRecordsAggregate */ + public RowRecordsAggregate() { + this(SharedValueManager.createEmpty()); + } + private RowRecordsAggregate(SharedValueManager svm) { + if (svm == null) { + throw new IllegalArgumentException("SharedValueManager must be provided."); + } + _rowRecords = new TreeMap(); + _valuesAgg = new ValueRecordsAggregate(); + _unknownRecords = new ArrayList(); + _sharedValueManager = svm; + } - /** - * @param rs record stream with all {@link SharedFormulaRecord} - * {@link ArrayRecord}, {@link TableRecord} {@link MergeCellsRecord} Records removed - * @param svm an initialised {@link SharedValueManager} (from the shared formula, array - * and table records of the current sheet). Never null. - */ - public RowRecordsAggregate(RecordStream rs, SharedValueManager svm) { - this(svm); - while(rs.hasNext()) { - Record rec = rs.getNext(); - switch (rec.getSid()) { - case RowRecord.sid: - insertRow((RowRecord) rec); - continue; + /** + * @param rs record stream with all {@link SharedFormulaRecord} + * {@link ArrayRecord}, {@link TableRecord} {@link MergeCellsRecord} Records removed + * @param svm an initialised {@link SharedValueManager} (from the shared formula, array + * and table records of the current sheet). Never null. + */ + public RowRecordsAggregate(RecordStream rs, SharedValueManager svm) { + this(svm); + while(rs.hasNext()) { + Record rec = rs.getNext(); + switch (rec.getSid()) { + case RowRecord.sid: + insertRow((RowRecord) rec); + continue; case DConRefRecord.sid: addUnknownRecord(rec); continue; case DBCellRecord.sid: - // end of 'Row Block'. Should only occur after cell records - // ignore DBCELL records because POI generates them upon re-serialization - continue; - } - if (rec instanceof UnknownRecord) { - // might need to keep track of where exactly these belong - addUnknownRecord(rec); - while (rs.peekNextSid() == ContinueRecord.sid) { - addUnknownRecord(rs.getNext()); - } - continue; - } - if (rec instanceof MulBlankRecord) { - _valuesAgg.addMultipleBlanks((MulBlankRecord) rec); - continue; - } - if (!(rec instanceof CellValueRecordInterface)) { - throw new RuntimeException("Unexpected record type (" + rec.getClass().getName() + ")"); - } - _valuesAgg.construct((CellValueRecordInterface)rec, rs, svm); - } - } - /** - * Handles UnknownRecords which appear within the row/cell records - */ - private void addUnknownRecord(Record rec) { - // ony a few distinct record IDs are encountered by the existing POI test cases: - // 0x1065 // many - // 0x01C2 // several - // 0x0034 // few - // No documentation could be found for these + // end of 'Row Block'. Should only occur after cell records + // ignore DBCELL records because POI generates them upon re-serialization + continue; + } + if (rec instanceof UnknownRecord) { + // might need to keep track of where exactly these belong + addUnknownRecord(rec); + while (rs.peekNextSid() == ContinueRecord.sid) { + addUnknownRecord(rs.getNext()); + } + continue; + } + if (rec instanceof MulBlankRecord) { + _valuesAgg.addMultipleBlanks((MulBlankRecord) rec); + continue; + } + if (!(rec instanceof CellValueRecordInterface)) { + throw new RuntimeException("Unexpected record type (" + rec.getClass().getName() + ")"); + } + _valuesAgg.construct((CellValueRecordInterface)rec, rs, svm); + } + } + /** + * Handles UnknownRecords which appear within the row/cell records + */ + private void addUnknownRecord(Record rec) { + // ony a few distinct record IDs are encountered by the existing POI test cases: + // 0x1065 // many + // 0x01C2 // several + // 0x0034 // few + // No documentation could be found for these - // keep the unknown records for re-serialization - _unknownRecords.add(rec); - } - public void insertRow(RowRecord row) { - // Integer integer = Integer.valueOf(row.getRowNumber()); - _rowRecords.put(Integer.valueOf(row.getRowNumber()), row); - // Clear the cached values - _rowRecordValues = null; - if ((row.getRowNumber() < _firstrow) || (_firstrow == -1)) { - _firstrow = row.getRowNumber(); - } - if ((row.getRowNumber() > _lastrow) || (_lastrow == -1)) { - _lastrow = row.getRowNumber(); - } - } + // keep the unknown records for re-serialization + _unknownRecords.add(rec); + } + public void insertRow(RowRecord row) { + // Integer integer = Integer.valueOf(row.getRowNumber()); + _rowRecords.put(Integer.valueOf(row.getRowNumber()), row); + // Clear the cached values + _rowRecordValues = null; + if ((row.getRowNumber() < _firstrow) || (_firstrow == -1)) { + _firstrow = row.getRowNumber(); + } + if ((row.getRowNumber() > _lastrow) || (_lastrow == -1)) { + _lastrow = row.getRowNumber(); + } + } - public void removeRow(RowRecord row) { - int rowIndex = row.getRowNumber(); - _valuesAgg.removeAllCellsValuesForRow(rowIndex); - Integer key = Integer.valueOf(rowIndex); - RowRecord rr = _rowRecords.remove(key); - if (rr == null) { - throw new RuntimeException("Invalid row index (" + key.intValue() + ")"); - } - if (row != rr) { - _rowRecords.put(key, rr); - throw new RuntimeException("Attempt to remove row that does not belong to this sheet"); - } - - // Clear the cached values - _rowRecordValues = null; - } + public void removeRow(RowRecord row) { + int rowIndex = row.getRowNumber(); + _valuesAgg.removeAllCellsValuesForRow(rowIndex); + Integer key = Integer.valueOf(rowIndex); + RowRecord rr = _rowRecords.remove(key); + if (rr == null) { + throw new RuntimeException("Invalid row index (" + key.intValue() + ")"); + } + if (row != rr) { + _rowRecords.put(key, rr); + throw new RuntimeException("Attempt to remove row that does not belong to this sheet"); + } + + // Clear the cached values + _rowRecordValues = null; + } - public RowRecord getRow(int rowIndex) { + public RowRecord getRow(int rowIndex) { int maxrow = SpreadsheetVersion.EXCEL97.getLastRowIndex(); if (rowIndex < 0 || rowIndex > maxrow) { - throw new IllegalArgumentException("The row number must be between 0 and " + maxrow + ", but had: " + rowIndex); - } - return _rowRecords.get(Integer.valueOf(rowIndex)); - } + throw new IllegalArgumentException("The row number must be between 0 and " + maxrow + ", but had: " + rowIndex); + } + return _rowRecords.get(Integer.valueOf(rowIndex)); + } - public int getPhysicalNumberOfRows() - { - return _rowRecords.size(); - } + public int getPhysicalNumberOfRows() + { + return _rowRecords.size(); + } - public int getFirstRowNum() - { - return _firstrow; - } + public int getFirstRowNum() + { + return _firstrow; + } - public int getLastRowNum() - { - return _lastrow; - } + public int getLastRowNum() + { + return _lastrow; + } - /** Returns the number of row blocks. - *

The row blocks are goupings of rows that contain the DBCell record - * after them - */ - public int getRowBlockCount() { - int size = _rowRecords.size()/DBCellRecord.BLOCK_SIZE; - if ((_rowRecords.size() % DBCellRecord.BLOCK_SIZE) != 0) - size++; - return size; - } + /** Returns the number of row blocks. + *

The row blocks are goupings of rows that contain the DBCell record + * after them + */ + public int getRowBlockCount() { + int size = _rowRecords.size()/DBCellRecord.BLOCK_SIZE; + if ((_rowRecords.size() % DBCellRecord.BLOCK_SIZE) != 0) + size++; + return size; + } - private int getRowBlockSize(int block) { - return RowRecord.ENCODED_SIZE * getRowCountForBlock(block); - } + private int getRowBlockSize(int block) { + return RowRecord.ENCODED_SIZE * getRowCountForBlock(block); + } - /** Returns the number of physical rows within a block*/ - public int getRowCountForBlock(int block) { - int startIndex = block * DBCellRecord.BLOCK_SIZE; - int endIndex = startIndex + DBCellRecord.BLOCK_SIZE - 1; - if (endIndex >= _rowRecords.size()) - endIndex = _rowRecords.size()-1; + /** Returns the number of physical rows within a block*/ + public int getRowCountForBlock(int block) { + int startIndex = block * DBCellRecord.BLOCK_SIZE; + int endIndex = startIndex + DBCellRecord.BLOCK_SIZE - 1; + if (endIndex >= _rowRecords.size()) + endIndex = _rowRecords.size()-1; - return endIndex-startIndex+1; - } + return endIndex-startIndex+1; + } - /** Returns the physical row number of the first row in a block*/ - private int getStartRowNumberForBlock(int block) { - int startIndex = block * DBCellRecord.BLOCK_SIZE; + /** Returns the physical row number of the first row in a block*/ + private int getStartRowNumberForBlock(int block) { + int startIndex = block * DBCellRecord.BLOCK_SIZE; - if(_rowRecordValues == null){ + if (_rowRecordValues == null) { _rowRecordValues = _rowRecords.values().toArray(new RowRecord[_rowRecords.size()]); } try { return _rowRecordValues[startIndex].getRowNumber(); } catch(ArrayIndexOutOfBoundsException e) { - throw new RuntimeException("Did not find start row for block " + block); - } - } + throw new RuntimeException("Did not find start row for block " + block); + } + } - /** Returns the physical row number of the end row in a block*/ - private int getEndRowNumberForBlock(int block) { - int endIndex = ((block + 1)*DBCellRecord.BLOCK_SIZE)-1; - if (endIndex >= _rowRecords.size()) - endIndex = _rowRecords.size()-1; + /** Returns the physical row number of the end row in a block*/ + private int getEndRowNumberForBlock(int block) { + int endIndex = ((block + 1)*DBCellRecord.BLOCK_SIZE)-1; + if (endIndex >= _rowRecords.size()) + endIndex = _rowRecords.size()-1; - if(_rowRecordValues == null){ + if (_rowRecordValues == null){ _rowRecordValues = _rowRecords.values().toArray(new RowRecord[_rowRecords.size()]); } @@ -219,287 +219,287 @@ public final class RowRecordsAggregate extends RecordAggregate { return _rowRecordValues[endIndex].getRowNumber(); } catch(ArrayIndexOutOfBoundsException e) { throw new RuntimeException("Did not find end row for block " + block); - } - } + } + } - private int visitRowRecordsForBlock(int blockIndex, RecordVisitor rv) { - final int startIndex = blockIndex*DBCellRecord.BLOCK_SIZE; - final int endIndex = startIndex + DBCellRecord.BLOCK_SIZE; + private int visitRowRecordsForBlock(int blockIndex, RecordVisitor rv) { + final int startIndex = blockIndex*DBCellRecord.BLOCK_SIZE; + final int endIndex = startIndex + DBCellRecord.BLOCK_SIZE; - Iterator rowIterator = _rowRecords.values().iterator(); + Iterator rowIterator = _rowRecords.values().iterator(); - //Given that we basically iterate through the rows in order, - //For a performance improvement, it would be better to return an instance of - //an iterator and use that instance throughout, rather than recreating one and - //having to move it to the right position. - int i=0; - for (;i getIterator() { - return _rowRecords.values().iterator(); - } + public Iterator getIterator() { + return _rowRecords.values().iterator(); + } - public int findStartOfRowOutlineGroup(int row) { - // Find the start of the group. - RowRecord rowRecord = this.getRow( row ); - int level = rowRecord.getOutlineLevel(); - int currentRow = row; - while (currentRow >= 0 && this.getRow( currentRow ) != null) { - rowRecord = this.getRow( currentRow ); - if (rowRecord.getOutlineLevel() < level) { - return currentRow + 1; - } - currentRow--; - } + public int findStartOfRowOutlineGroup(int row) { + // Find the start of the group. + RowRecord rowRecord = this.getRow( row ); + int level = rowRecord.getOutlineLevel(); + int currentRow = row; + while (currentRow >= 0 && this.getRow( currentRow ) != null) { + rowRecord = this.getRow( currentRow ); + if (rowRecord.getOutlineLevel() < level) { + return currentRow + 1; + } + currentRow--; + } - return currentRow + 1; - } + return currentRow + 1; + } - public int findEndOfRowOutlineGroup(int row) { - int level = getRow( row ).getOutlineLevel(); - int currentRow; - for (currentRow = row; currentRow < getLastRowNum(); currentRow++) { - if (getRow(currentRow) == null || getRow(currentRow).getOutlineLevel() < level) { - break; - } - } + public int findEndOfRowOutlineGroup(int row) { + int level = getRow( row ).getOutlineLevel(); + int currentRow; + for (currentRow = row; currentRow < getLastRowNum(); currentRow++) { + if (getRow(currentRow) == null || getRow(currentRow).getOutlineLevel() < level) { + break; + } + } - return currentRow-1; - } + return currentRow-1; + } - /** - * Hide all rows at or below the current outline level - * @return index of the next row after the last row that gets hidden - */ - private int writeHidden(RowRecord pRowRecord, int row) { - int rowIx = row; - RowRecord rowRecord = pRowRecord; - int level = rowRecord.getOutlineLevel(); - while (rowRecord != null && getRow(rowIx).getOutlineLevel() >= level) { - rowRecord.setZeroHeight(true); - rowIx++; - rowRecord = getRow(rowIx); - } - return rowIx; - } + /** + * Hide all rows at or below the current outline level + * @return index of the next row after the last row that gets hidden + */ + private int writeHidden(RowRecord pRowRecord, int row) { + int rowIx = row; + RowRecord rowRecord = pRowRecord; + int level = rowRecord.getOutlineLevel(); + while (rowRecord != null && getRow(rowIx).getOutlineLevel() >= level) { + rowRecord.setZeroHeight(true); + rowIx++; + rowRecord = getRow(rowIx); + } + return rowIx; + } - public void collapseRow(int rowNumber) { + public void collapseRow(int rowNumber) { - // Find the start of the group. - int startRow = findStartOfRowOutlineGroup(rowNumber); - RowRecord rowRecord = getRow(startRow); + // Find the start of the group. + int startRow = findStartOfRowOutlineGroup(rowNumber); + RowRecord rowRecord = getRow(startRow); - // Hide all the columns until the end of the group - int nextRowIx = writeHidden(rowRecord, startRow); + // Hide all the columns until the end of the group + int nextRowIx = writeHidden(rowRecord, startRow); - RowRecord row = getRow(nextRowIx); - if (row == null) { - row = createRow(nextRowIx); - insertRow(row); - } - // Write collapse field - row.setColapsed(true); - } + RowRecord row = getRow(nextRowIx); + if (row == null) { + row = createRow(nextRowIx); + insertRow(row); + } + // Write collapse field + row.setColapsed(true); + } - /** - * Create a row record. - * - * @param rowNumber row number - * @return RowRecord created for the passed in row number - * @see org.apache.poi.hssf.record.RowRecord - */ - public static RowRecord createRow(int rowNumber) { - return new RowRecord(rowNumber); - } + /** + * Create a row record. + * + * @param rowNumber row number + * @return RowRecord created for the passed in row number + * @see org.apache.poi.hssf.record.RowRecord + */ + public static RowRecord createRow(int rowNumber) { + return new RowRecord(rowNumber); + } - public boolean isRowGroupCollapsed(int row) { - int collapseRow = findEndOfRowOutlineGroup(row) + 1; + public boolean isRowGroupCollapsed(int row) { + int collapseRow = findEndOfRowOutlineGroup(row) + 1; - return getRow(collapseRow) != null && getRow(collapseRow).getColapsed(); - } + return getRow(collapseRow) != null && getRow(collapseRow).getColapsed(); + } - public void expandRow(int rowNumber) { - if (rowNumber == -1) - return; + public void expandRow(int rowNumber) { + if (rowNumber == -1) + return; - // If it is already expanded do nothing. - if (!isRowGroupCollapsed(rowNumber)) { - return; - } + // If it is already expanded do nothing. + if (!isRowGroupCollapsed(rowNumber)) { + return; + } - // Find the start of the group. - int startIdx = findStartOfRowOutlineGroup(rowNumber); - RowRecord row = getRow(startIdx); + // Find the start of the group. + int startIdx = findStartOfRowOutlineGroup(rowNumber); + RowRecord row = getRow(startIdx); - // Find the end of the group. - int endIdx = findEndOfRowOutlineGroup(rowNumber); + // Find the end of the group. + int endIdx = findEndOfRowOutlineGroup(rowNumber); - // expand: - // collapsed bit must be unset - // hidden bit gets unset _if_ surrounding groups are expanded you can determine - // this by looking at the hidden bit of the enclosing group. You will have - // to look at the start and the end of the current group to determine which - // is the enclosing group - // hidden bit only is altered for this outline level. ie. don't un-collapse contained groups - if (!isRowGroupHiddenByParent(rowNumber)) { - for (int i = startIdx; i <= endIdx; i++) { - RowRecord otherRow = getRow(i); - if (row.getOutlineLevel() == otherRow.getOutlineLevel() || !isRowGroupCollapsed(i)) { - otherRow.setZeroHeight(false); - } - } - } + // expand: + // collapsed bit must be unset + // hidden bit gets unset _if_ surrounding groups are expanded you can determine + // this by looking at the hidden bit of the enclosing group. You will have + // to look at the start and the end of the current group to determine which + // is the enclosing group + // hidden bit only is altered for this outline level. ie. don't un-collapse contained groups + if (!isRowGroupHiddenByParent(rowNumber)) { + for (int i = startIdx; i <= endIdx; i++) { + RowRecord otherRow = getRow(i); + if (row.getOutlineLevel() == otherRow.getOutlineLevel() || !isRowGroupCollapsed(i)) { + otherRow.setZeroHeight(false); + } + } + } - // Write collapse field - getRow(endIdx + 1).setColapsed(false); - } + // Write collapse field + getRow(endIdx + 1).setColapsed(false); + } - public boolean isRowGroupHiddenByParent(int row) { - // Look out outline details of end - int endLevel; - boolean endHidden; - int endOfOutlineGroupIdx = findEndOfRowOutlineGroup(row); - if (getRow(endOfOutlineGroupIdx + 1) == null) { - endLevel = 0; - endHidden = false; - } else { - endLevel = getRow(endOfOutlineGroupIdx + 1).getOutlineLevel(); - endHidden = getRow(endOfOutlineGroupIdx + 1).getZeroHeight(); - } + public boolean isRowGroupHiddenByParent(int row) { + // Look out outline details of end + int endLevel; + boolean endHidden; + int endOfOutlineGroupIdx = findEndOfRowOutlineGroup(row); + if (getRow(endOfOutlineGroupIdx + 1) == null) { + endLevel = 0; + endHidden = false; + } else { + endLevel = getRow(endOfOutlineGroupIdx + 1).getOutlineLevel(); + endHidden = getRow(endOfOutlineGroupIdx + 1).getZeroHeight(); + } - // Look out outline details of start - int startLevel; - boolean startHidden; - int startOfOutlineGroupIdx = findStartOfRowOutlineGroup( row ); - if (startOfOutlineGroupIdx - 1 < 0 || getRow(startOfOutlineGroupIdx - 1) == null) { - startLevel = 0; - startHidden = false; - } else { - startLevel = getRow(startOfOutlineGroupIdx - 1).getOutlineLevel(); - startHidden = getRow(startOfOutlineGroupIdx - 1).getZeroHeight(); - } + // Look out outline details of start + int startLevel; + boolean startHidden; + int startOfOutlineGroupIdx = findStartOfRowOutlineGroup( row ); + if (startOfOutlineGroupIdx - 1 < 0 || getRow(startOfOutlineGroupIdx - 1) == null) { + startLevel = 0; + startHidden = false; + } else { + startLevel = getRow(startOfOutlineGroupIdx - 1).getOutlineLevel(); + startHidden = getRow(startOfOutlineGroupIdx - 1).getZeroHeight(); + } - if (endLevel > startLevel) { - return endHidden; - } + if (endLevel > startLevel) { + return endHidden; + } - return startHidden; - } - - /** - * Returns an iterator for the cell values - */ - public Iterator getCellValueIterator() { - return _valuesAgg.iterator(); - } + return startHidden; + } + + /** + * Returns an iterator for the cell values + */ + public Iterator getCellValueIterator() { + return _valuesAgg.iterator(); + } - public IndexRecord createIndexRecord(int indexRecordOffset, int sizeOfInitialSheetRecords) { - IndexRecord result = new IndexRecord(); - result.setFirstRow(_firstrow); - result.setLastRowAdd1(_lastrow + 1); - // Calculate the size of the records from the end of the BOF - // and up to the RowRecordsAggregate... + public IndexRecord createIndexRecord(int indexRecordOffset, int sizeOfInitialSheetRecords) { + IndexRecord result = new IndexRecord(); + result.setFirstRow(_firstrow); + result.setLastRowAdd1(_lastrow + 1); + // Calculate the size of the records from the end of the BOF + // and up to the RowRecordsAggregate... - // Add the references to the DBCells in the IndexRecord (one for each block) - // Note: The offsets are relative to the Workbook BOF. Assume that this is - // 0 for now..... + // Add the references to the DBCells in the IndexRecord (one for each block) + // Note: The offsets are relative to the Workbook BOF. Assume that this is + // 0 for now..... - int blockCount = getRowBlockCount(); - // Calculate the size of this IndexRecord - int indexRecSize = IndexRecord.getRecordSizeForBlockCount(blockCount); + int blockCount = getRowBlockCount(); + // Calculate the size of this IndexRecord + int indexRecSize = IndexRecord.getRecordSizeForBlockCount(blockCount); - int currentOffset = indexRecordOffset + indexRecSize + sizeOfInitialSheetRecords; + int currentOffset = indexRecordOffset + indexRecSize + sizeOfInitialSheetRecords; - for (int block = 0; block < blockCount; block++) { - // each row-block has a DBCELL record. - // The offset of each DBCELL record needs to be updated in the INDEX record + for (int block = 0; block < blockCount; block++) { + // each row-block has a DBCELL record. + // The offset of each DBCELL record needs to be updated in the INDEX record - // account for row records in this row-block - currentOffset += getRowBlockSize(block); - // account for cell value records after those - currentOffset += _valuesAgg.getRowCellBlockSize( - getStartRowNumberForBlock(block), getEndRowNumberForBlock(block)); + // account for row records in this row-block + currentOffset += getRowBlockSize(block); + // account for cell value records after those + currentOffset += _valuesAgg.getRowCellBlockSize( + getStartRowNumberForBlock(block), getEndRowNumberForBlock(block)); - // currentOffset is now the location of the DBCELL record for this row-block - result.addDbcell(currentOffset); - // Add space required to write the DBCELL record (whose reference was just added). - currentOffset += (8 + (getRowCountForBlock(block) * 2)); - } - return result; - } - public void insertCell(CellValueRecordInterface cvRec) { - _valuesAgg.insertCell(cvRec); - } - public void removeCell(CellValueRecordInterface cvRec) { - if (cvRec instanceof FormulaRecordAggregate) { - ((FormulaRecordAggregate)cvRec).notifyFormulaChanging(); - } - _valuesAgg.removeCell(cvRec); - } - public FormulaRecordAggregate createFormula(int row, int col) { - FormulaRecord fr = new FormulaRecord(); - fr.setRow(row); - fr.setColumn((short) col); - return new FormulaRecordAggregate(fr, null, _sharedValueManager); - } - public void updateFormulasAfterRowShift(FormulaShifter formulaShifter, int currentExternSheetIndex) { - _valuesAgg.updateFormulasAfterRowShift(formulaShifter, currentExternSheetIndex); - } - public DimensionsRecord createDimensions() { - DimensionsRecord result = new DimensionsRecord(); - result.setFirstRow(_firstrow); - result.setLastRow(_lastrow); - result.setFirstCol((short) _valuesAgg.getFirstCellNum()); - result.setLastCol((short) _valuesAgg.getLastCellNum()); - return result; - } + // currentOffset is now the location of the DBCELL record for this row-block + result.addDbcell(currentOffset); + // Add space required to write the DBCELL record (whose reference was just added). + currentOffset += (8 + (getRowCountForBlock(block) * 2)); + } + return result; + } + public void insertCell(CellValueRecordInterface cvRec) { + _valuesAgg.insertCell(cvRec); + } + public void removeCell(CellValueRecordInterface cvRec) { + if (cvRec instanceof FormulaRecordAggregate) { + ((FormulaRecordAggregate)cvRec).notifyFormulaChanging(); + } + _valuesAgg.removeCell(cvRec); + } + public FormulaRecordAggregate createFormula(int row, int col) { + FormulaRecord fr = new FormulaRecord(); + fr.setRow(row); + fr.setColumn((short) col); + return new FormulaRecordAggregate(fr, null, _sharedValueManager); + } + public void updateFormulasAfterRowShift(FormulaShifter formulaShifter, int currentExternSheetIndex) { + _valuesAgg.updateFormulasAfterRowShift(formulaShifter, currentExternSheetIndex); + } + public DimensionsRecord createDimensions() { + DimensionsRecord result = new DimensionsRecord(); + result.setFirstRow(_firstrow); + result.setLastRow(_lastrow); + result.setFirstCol((short) _valuesAgg.getFirstCellNum()); + result.setLastCol((short) _valuesAgg.getLastCellNum()); + return result; + } } From 66d7d4ddaacbb8c8a94ba6798d2b4d54fb4dd9f2 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Mon, 1 Aug 2016 18:01:24 +0000 Subject: [PATCH 025/157] whitespace; +svn:eol-style=native git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754784 13f79535-47bb-0310-9956-ffa450edef68 --- .../usermodel/helpers/XSSFPaswordHelper.java | 260 +++++++++--------- 1 file changed, 130 insertions(+), 130 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java index fd6e2dbd0..39ba2c66f 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java @@ -1,130 +1,130 @@ -/* - * ==================================================================== - * 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.xssf.usermodel.helpers; - -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.Locale; - -import javax.xml.bind.DatatypeConverter; -import javax.xml.namespace.QName; - -import org.apache.poi.poifs.crypt.CryptoFunctions; -import org.apache.poi.poifs.crypt.HashAlgorithm; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlObject; - -public class XSSFPaswordHelper { - /** - * Sets the XORed or hashed password - * - * @param xobj the xmlbeans object which contains the password attributes - * @param password the password, if null, the password attributes will be removed - * @param hashAlgo the hash algorithm, if null the password will be XORed - * @param prefix the prefix of the password attributes, may be null - */ - public static void setPassword(XmlObject xobj, String password, HashAlgorithm hashAlgo, String prefix) { - XmlCursor cur = xobj.newCursor(); - - if (password == null) { - cur.removeAttribute(getAttrName(prefix, "password")); - cur.removeAttribute(getAttrName(prefix, "algorithmName")); - cur.removeAttribute(getAttrName(prefix, "hashValue")); - cur.removeAttribute(getAttrName(prefix, "saltValue")); - cur.removeAttribute(getAttrName(prefix, "spinCount")); - return; - } - - cur.toFirstContentToken(); - if (hashAlgo == null) { - int hash = CryptoFunctions.createXorVerifier1(password); - cur.insertAttributeWithValue(getAttrName(prefix, "password"), - String.format(Locale.ROOT, "%04X", hash).toUpperCase(Locale.ROOT)); - } else { - SecureRandom random = new SecureRandom(); - byte salt[] = random.generateSeed(16); - - // Iterations specifies the number of times the hashing function shall be iteratively run (using each - // iteration's result as the input for the next iteration). - int spinCount = 100000; - - // Implementation Notes List: - // --> In this third stage, the reversed byte order legacy hash from the second stage shall - // be converted to Unicode hex string representation - byte hash[] = CryptoFunctions.hashPassword(password, hashAlgo, salt, spinCount, false); - - cur.insertAttributeWithValue(getAttrName(prefix, "algorithmName"), hashAlgo.jceId); - cur.insertAttributeWithValue(getAttrName(prefix, "hashValue"), DatatypeConverter.printBase64Binary(hash)); - cur.insertAttributeWithValue(getAttrName(prefix, "saltValue"), DatatypeConverter.printBase64Binary(salt)); - cur.insertAttributeWithValue(getAttrName(prefix, "spinCount"), ""+spinCount); - } - cur.dispose(); - } - - /** - * Validates the password, i.e. - * calculates the hash of the given password and compares it against the stored hash - * - * @param xobj the xmlbeans object which contains the password attributes - * @param password the password, if null the method will always return false, - * even if there's no password set - * @param prefix the prefix of the password attributes, may be null - * - * @return true, if the hashes match - */ - public static boolean validatePassword(XmlObject xobj, String password, String prefix) { - // TODO: is "velvetSweatshop" the default password? - if (password == null) return false; - - XmlCursor cur = xobj.newCursor(); - String xorHashVal = cur.getAttributeText(getAttrName(prefix, "password")); - String algoName = cur.getAttributeText(getAttrName(prefix, "algorithmName")); - String hashVal = cur.getAttributeText(getAttrName(prefix, "hashValue")); - String saltVal = cur.getAttributeText(getAttrName(prefix, "saltValue")); - String spinCount = cur.getAttributeText(getAttrName(prefix, "spinCount")); - cur.dispose(); - - if (xorHashVal != null) { - int hash1 = Integer.parseInt(xorHashVal, 16); - int hash2 = CryptoFunctions.createXorVerifier1(password); - return hash1 == hash2; - } else { - if (hashVal == null || algoName == null || saltVal == null || spinCount == null) { - return false; - } - - byte hash1[] = DatatypeConverter.parseBase64Binary(hashVal); - HashAlgorithm hashAlgo = HashAlgorithm.fromString(algoName); - byte salt[] = DatatypeConverter.parseBase64Binary(saltVal); - int spinCnt = Integer.parseInt(spinCount); - byte hash2[] = CryptoFunctions.hashPassword(password, hashAlgo, salt, spinCnt, false); - return Arrays.equals(hash1, hash2); - } - } - - - private static QName getAttrName(String prefix, String name) { - if (prefix == null || "".equals(prefix)) { - return new QName(name); - } else { - return new QName(prefix+Character.toUpperCase(name.charAt(0))+name.substring(1)); - } - } -} +/* + * ==================================================================== + * 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.xssf.usermodel.helpers; + +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.Locale; + +import javax.xml.bind.DatatypeConverter; +import javax.xml.namespace.QName; + +import org.apache.poi.poifs.crypt.CryptoFunctions; +import org.apache.poi.poifs.crypt.HashAlgorithm; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlObject; + +public class XSSFPaswordHelper { + /** + * Sets the XORed or hashed password + * + * @param xobj the xmlbeans object which contains the password attributes + * @param password the password, if null, the password attributes will be removed + * @param hashAlgo the hash algorithm, if null the password will be XORed + * @param prefix the prefix of the password attributes, may be null + */ + public static void setPassword(XmlObject xobj, String password, HashAlgorithm hashAlgo, String prefix) { + XmlCursor cur = xobj.newCursor(); + + if (password == null) { + cur.removeAttribute(getAttrName(prefix, "password")); + cur.removeAttribute(getAttrName(prefix, "algorithmName")); + cur.removeAttribute(getAttrName(prefix, "hashValue")); + cur.removeAttribute(getAttrName(prefix, "saltValue")); + cur.removeAttribute(getAttrName(prefix, "spinCount")); + return; + } + + cur.toFirstContentToken(); + if (hashAlgo == null) { + int hash = CryptoFunctions.createXorVerifier1(password); + cur.insertAttributeWithValue(getAttrName(prefix, "password"), + String.format(Locale.ROOT, "%04X", hash).toUpperCase(Locale.ROOT)); + } else { + SecureRandom random = new SecureRandom(); + byte salt[] = random.generateSeed(16); + + // Iterations specifies the number of times the hashing function shall be iteratively run (using each + // iteration's result as the input for the next iteration). + int spinCount = 100000; + + // Implementation Notes List: + // --> In this third stage, the reversed byte order legacy hash from the second stage shall + // be converted to Unicode hex string representation + byte hash[] = CryptoFunctions.hashPassword(password, hashAlgo, salt, spinCount, false); + + cur.insertAttributeWithValue(getAttrName(prefix, "algorithmName"), hashAlgo.jceId); + cur.insertAttributeWithValue(getAttrName(prefix, "hashValue"), DatatypeConverter.printBase64Binary(hash)); + cur.insertAttributeWithValue(getAttrName(prefix, "saltValue"), DatatypeConverter.printBase64Binary(salt)); + cur.insertAttributeWithValue(getAttrName(prefix, "spinCount"), ""+spinCount); + } + cur.dispose(); + } + + /** + * Validates the password, i.e. + * calculates the hash of the given password and compares it against the stored hash + * + * @param xobj the xmlbeans object which contains the password attributes + * @param password the password, if null the method will always return false, + * even if there's no password set + * @param prefix the prefix of the password attributes, may be null + * + * @return true, if the hashes match + */ + public static boolean validatePassword(XmlObject xobj, String password, String prefix) { + // TODO: is "velvetSweatshop" the default password? + if (password == null) return false; + + XmlCursor cur = xobj.newCursor(); + String xorHashVal = cur.getAttributeText(getAttrName(prefix, "password")); + String algoName = cur.getAttributeText(getAttrName(prefix, "algorithmName")); + String hashVal = cur.getAttributeText(getAttrName(prefix, "hashValue")); + String saltVal = cur.getAttributeText(getAttrName(prefix, "saltValue")); + String spinCount = cur.getAttributeText(getAttrName(prefix, "spinCount")); + cur.dispose(); + + if (xorHashVal != null) { + int hash1 = Integer.parseInt(xorHashVal, 16); + int hash2 = CryptoFunctions.createXorVerifier1(password); + return hash1 == hash2; + } else { + if (hashVal == null || algoName == null || saltVal == null || spinCount == null) { + return false; + } + + byte hash1[] = DatatypeConverter.parseBase64Binary(hashVal); + HashAlgorithm hashAlgo = HashAlgorithm.fromString(algoName); + byte salt[] = DatatypeConverter.parseBase64Binary(saltVal); + int spinCnt = Integer.parseInt(spinCount); + byte hash2[] = CryptoFunctions.hashPassword(password, hashAlgo, salt, spinCnt, false); + return Arrays.equals(hash1, hash2); + } + } + + + private static QName getAttrName(String prefix, String name) { + if (prefix == null || "".equals(prefix)) { + return new QName(name); + } else { + return new QName(prefix+Character.toUpperCase(name.charAt(0))+name.substring(1)); + } + } +} From ca31684a27785be24f04ea560a020f89a59a084e Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Mon, 1 Aug 2016 18:03:36 +0000 Subject: [PATCH 026/157] bug 59922: make XSSFPasswordHelper internal because it works on XmlObject objects, which are generally an internal implementation detail of POI-OOXML git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754785 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java index 39ba2c66f..926058f89 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java @@ -28,9 +28,11 @@ import javax.xml.namespace.QName; import org.apache.poi.poifs.crypt.CryptoFunctions; import org.apache.poi.poifs.crypt.HashAlgorithm; +import org.apache.poi.util.Internal; import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlObject; +@Internal(since="3.15 beta 3") public class XSSFPaswordHelper { /** * Sets the XORed or hashed password From fcb22a8a5eb1f2ed3c1ef297ee529075ff3668a1 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Mon, 1 Aug 2016 18:20:43 +0000 Subject: [PATCH 027/157] bug 59922: rename XSSFPaswordHelper to XSSFPasswordHelper git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754786 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/xssf/usermodel/XSSFSheet.java | 4 +- .../poi/xssf/usermodel/XSSFWorkbook.java | 4 +- .../usermodel/helpers/XSSFPasswordHelper.java | 136 ++++++++++++++++++ .../usermodel/helpers/XSSFPaswordHelper.java | 88 ++---------- 4 files changed, 148 insertions(+), 84 deletions(-) create mode 100644 src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPasswordHelper.java diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java index 2271e0b4d..5f1da12ec 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java @@ -18,8 +18,8 @@ package org.apache.poi.xssf.usermodel; import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; -import static org.apache.poi.xssf.usermodel.helpers.XSSFPaswordHelper.setPassword; -import static org.apache.poi.xssf.usermodel.helpers.XSSFPaswordHelper.validatePassword; +import static org.apache.poi.xssf.usermodel.helpers.XSSFPasswordHelper.setPassword; +import static org.apache.poi.xssf.usermodel.helpers.XSSFPasswordHelper.validatePassword; import java.io.IOException; import java.io.InputStream; diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java index f3a5879db..afddcd9c4 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java @@ -18,8 +18,8 @@ package org.apache.poi.xssf.usermodel; import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; -import static org.apache.poi.xssf.usermodel.helpers.XSSFPaswordHelper.setPassword; -import static org.apache.poi.xssf.usermodel.helpers.XSSFPaswordHelper.validatePassword; +import static org.apache.poi.xssf.usermodel.helpers.XSSFPasswordHelper.setPassword; +import static org.apache.poi.xssf.usermodel.helpers.XSSFPasswordHelper.validatePassword; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPasswordHelper.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPasswordHelper.java new file mode 100644 index 000000000..46e47f688 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPasswordHelper.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.xssf.usermodel.helpers; + +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.Locale; + +import javax.xml.bind.DatatypeConverter; +import javax.xml.namespace.QName; + +import org.apache.poi.poifs.crypt.CryptoFunctions; +import org.apache.poi.poifs.crypt.HashAlgorithm; +import org.apache.poi.util.Internal; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlObject; + +@Internal(since="3.15 beta 3") +public final class XSSFPasswordHelper { + private XSSFPasswordHelper() { + // no instances of this static class + } + + /** + * Sets the XORed or hashed password + * + * @param xobj the xmlbeans object which contains the password attributes + * @param password the password, if null, the password attributes will be removed + * @param hashAlgo the hash algorithm, if null the password will be XORed + * @param prefix the prefix of the password attributes, may be null + */ + public static void setPassword(XmlObject xobj, String password, HashAlgorithm hashAlgo, String prefix) { + XmlCursor cur = xobj.newCursor(); + + if (password == null) { + cur.removeAttribute(getAttrName(prefix, "password")); + cur.removeAttribute(getAttrName(prefix, "algorithmName")); + cur.removeAttribute(getAttrName(prefix, "hashValue")); + cur.removeAttribute(getAttrName(prefix, "saltValue")); + cur.removeAttribute(getAttrName(prefix, "spinCount")); + return; + } + + cur.toFirstContentToken(); + if (hashAlgo == null) { + int hash = CryptoFunctions.createXorVerifier1(password); + cur.insertAttributeWithValue(getAttrName(prefix, "password"), + String.format(Locale.ROOT, "%04X", hash).toUpperCase(Locale.ROOT)); + } else { + SecureRandom random = new SecureRandom(); + byte salt[] = random.generateSeed(16); + + // Iterations specifies the number of times the hashing function shall be iteratively run (using each + // iteration's result as the input for the next iteration). + int spinCount = 100000; + + // Implementation Notes List: + // --> In this third stage, the reversed byte order legacy hash from the second stage shall + // be converted to Unicode hex string representation + byte hash[] = CryptoFunctions.hashPassword(password, hashAlgo, salt, spinCount, false); + + cur.insertAttributeWithValue(getAttrName(prefix, "algorithmName"), hashAlgo.jceId); + cur.insertAttributeWithValue(getAttrName(prefix, "hashValue"), DatatypeConverter.printBase64Binary(hash)); + cur.insertAttributeWithValue(getAttrName(prefix, "saltValue"), DatatypeConverter.printBase64Binary(salt)); + cur.insertAttributeWithValue(getAttrName(prefix, "spinCount"), ""+spinCount); + } + cur.dispose(); + } + + /** + * Validates the password, i.e. + * calculates the hash of the given password and compares it against the stored hash + * + * @param xobj the xmlbeans object which contains the password attributes + * @param password the password, if null the method will always return false, + * even if there's no password set + * @param prefix the prefix of the password attributes, may be null + * + * @return true, if the hashes match + */ + public static boolean validatePassword(XmlObject xobj, String password, String prefix) { + // TODO: is "velvetSweatshop" the default password? + if (password == null) return false; + + XmlCursor cur = xobj.newCursor(); + String xorHashVal = cur.getAttributeText(getAttrName(prefix, "password")); + String algoName = cur.getAttributeText(getAttrName(prefix, "algorithmName")); + String hashVal = cur.getAttributeText(getAttrName(prefix, "hashValue")); + String saltVal = cur.getAttributeText(getAttrName(prefix, "saltValue")); + String spinCount = cur.getAttributeText(getAttrName(prefix, "spinCount")); + cur.dispose(); + + if (xorHashVal != null) { + int hash1 = Integer.parseInt(xorHashVal, 16); + int hash2 = CryptoFunctions.createXorVerifier1(password); + return hash1 == hash2; + } else { + if (hashVal == null || algoName == null || saltVal == null || spinCount == null) { + return false; + } + + byte hash1[] = DatatypeConverter.parseBase64Binary(hashVal); + HashAlgorithm hashAlgo = HashAlgorithm.fromString(algoName); + byte salt[] = DatatypeConverter.parseBase64Binary(saltVal); + int spinCnt = Integer.parseInt(spinCount); + byte hash2[] = CryptoFunctions.hashPassword(password, hashAlgo, salt, spinCnt, false); + return Arrays.equals(hash1, hash2); + } + } + + + private static QName getAttrName(String prefix, String name) { + if (prefix == null || "".equals(prefix)) { + return new QName(name); + } else { + return new QName(prefix+Character.toUpperCase(name.charAt(0))+name.substring(1)); + } + } +} diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java index 926058f89..4e3c90819 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java @@ -19,20 +19,17 @@ package org.apache.poi.xssf.usermodel.helpers; -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.Locale; - -import javax.xml.bind.DatatypeConverter; -import javax.xml.namespace.QName; - -import org.apache.poi.poifs.crypt.CryptoFunctions; import org.apache.poi.poifs.crypt.HashAlgorithm; import org.apache.poi.util.Internal; -import org.apache.xmlbeans.XmlCursor; +import org.apache.poi.util.Removal; import org.apache.xmlbeans.XmlObject; +/** + * @deprecated POI 3.15 beta 3. Use {@link XSSFPasswordHelper} instead. + */ @Internal(since="3.15 beta 3") +@Deprecated +@Removal(version="3.17") public class XSSFPaswordHelper { /** * Sets the XORed or hashed password @@ -43,41 +40,7 @@ public class XSSFPaswordHelper { * @param prefix the prefix of the password attributes, may be null */ public static void setPassword(XmlObject xobj, String password, HashAlgorithm hashAlgo, String prefix) { - XmlCursor cur = xobj.newCursor(); - - if (password == null) { - cur.removeAttribute(getAttrName(prefix, "password")); - cur.removeAttribute(getAttrName(prefix, "algorithmName")); - cur.removeAttribute(getAttrName(prefix, "hashValue")); - cur.removeAttribute(getAttrName(prefix, "saltValue")); - cur.removeAttribute(getAttrName(prefix, "spinCount")); - return; - } - - cur.toFirstContentToken(); - if (hashAlgo == null) { - int hash = CryptoFunctions.createXorVerifier1(password); - cur.insertAttributeWithValue(getAttrName(prefix, "password"), - String.format(Locale.ROOT, "%04X", hash).toUpperCase(Locale.ROOT)); - } else { - SecureRandom random = new SecureRandom(); - byte salt[] = random.generateSeed(16); - - // Iterations specifies the number of times the hashing function shall be iteratively run (using each - // iteration's result as the input for the next iteration). - int spinCount = 100000; - - // Implementation Notes List: - // --> In this third stage, the reversed byte order legacy hash from the second stage shall - // be converted to Unicode hex string representation - byte hash[] = CryptoFunctions.hashPassword(password, hashAlgo, salt, spinCount, false); - - cur.insertAttributeWithValue(getAttrName(prefix, "algorithmName"), hashAlgo.jceId); - cur.insertAttributeWithValue(getAttrName(prefix, "hashValue"), DatatypeConverter.printBase64Binary(hash)); - cur.insertAttributeWithValue(getAttrName(prefix, "saltValue"), DatatypeConverter.printBase64Binary(salt)); - cur.insertAttributeWithValue(getAttrName(prefix, "spinCount"), ""+spinCount); - } - cur.dispose(); + XSSFPasswordHelper.setPassword(xobj, password, hashAlgo, prefix); } /** @@ -92,41 +55,6 @@ public class XSSFPaswordHelper { * @return true, if the hashes match */ public static boolean validatePassword(XmlObject xobj, String password, String prefix) { - // TODO: is "velvetSweatshop" the default password? - if (password == null) return false; - - XmlCursor cur = xobj.newCursor(); - String xorHashVal = cur.getAttributeText(getAttrName(prefix, "password")); - String algoName = cur.getAttributeText(getAttrName(prefix, "algorithmName")); - String hashVal = cur.getAttributeText(getAttrName(prefix, "hashValue")); - String saltVal = cur.getAttributeText(getAttrName(prefix, "saltValue")); - String spinCount = cur.getAttributeText(getAttrName(prefix, "spinCount")); - cur.dispose(); - - if (xorHashVal != null) { - int hash1 = Integer.parseInt(xorHashVal, 16); - int hash2 = CryptoFunctions.createXorVerifier1(password); - return hash1 == hash2; - } else { - if (hashVal == null || algoName == null || saltVal == null || spinCount == null) { - return false; - } - - byte hash1[] = DatatypeConverter.parseBase64Binary(hashVal); - HashAlgorithm hashAlgo = HashAlgorithm.fromString(algoName); - byte salt[] = DatatypeConverter.parseBase64Binary(saltVal); - int spinCnt = Integer.parseInt(spinCount); - byte hash2[] = CryptoFunctions.hashPassword(password, hashAlgo, salt, spinCnt, false); - return Arrays.equals(hash1, hash2); - } - } - - - private static QName getAttrName(String prefix, String name) { - if (prefix == null || "".equals(prefix)) { - return new QName(name); - } else { - return new QName(prefix+Character.toUpperCase(name.charAt(0))+name.substring(1)); - } + return XSSFPasswordHelper.validatePassword(xobj, password, prefix); } } From f9ba5bba33ae647d9e74539bb5babafde067eb13 Mon Sep 17 00:00:00 2001 From: David North Date: Tue, 2 Aug 2016 08:29:37 +0000 Subject: [PATCH 028/157] Trivial change to test SVN is working again git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754845 13f79535-47bb-0310-9956-ffa450edef68 --- patch.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patch.xml b/patch.xml index ed52a91d7..727c22641 100644 --- a/patch.xml +++ b/patch.xml @@ -17,7 +17,7 @@ --> From ebf4e2b511b20a8712bcf0a661347d3b1c24b301 Mon Sep 17 00:00:00 2001 From: David North Date: Tue, 2 Aug 2016 08:31:52 +0000 Subject: [PATCH 029/157] Tweak git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754846 13f79535-47bb-0310-9956-ffa450edef68 --- patch.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patch.xml b/patch.xml index 727c22641..ed52a91d7 100644 --- a/patch.xml +++ b/patch.xml @@ -17,7 +17,7 @@ --> From 0640df0b97ec65a660a9248ef5e227db4db6f2f7 Mon Sep 17 00:00:00 2001 From: David North Date: Tue, 2 Aug 2016 08:35:25 +0000 Subject: [PATCH 030/157] Test commit git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754847 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/build.xml b/build.xml index 293167090..da14c7f77 100644 --- a/build.xml +++ b/build.xml @@ -17,7 +17,6 @@ KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> - + - - - + + - - - - + @@ -441,7 +438,7 @@ under the License. This is POI ${version.id} - Java Version ${ant.java.version} + Java Version ${ant.java.version}/${java.version} Timestamp ${DSTAMP} The main targets of interest are: - clean Erase all build work products (ie. everything in the build directory) @@ -480,7 +477,9 @@ under the License. + + var rel = ("REL_"+project.getProperty("version.id")).toUpperCase().replace(/\W/g,"_"); From 8c7c45ecca9d4057e9d1ebbc6fa6b62e9015f153 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Thu, 11 Aug 2016 15:14:04 +0000 Subject: [PATCH 045/157] HWPF in-place write support git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1756001 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/org/apache/poi/hwpf/HWPFDocument.java | 51 ++++++++++++------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java index fe22c03ef..0d6538917 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java @@ -572,12 +572,27 @@ public final class HWPFDocument extends HWPFDocumentCore { } /** - * Warning - not currently implemented for HWPF! + * Write out the word file that is represented by this class, to the + * currently open {@link File}, via the writeable {@link POIFSFileSystem} + * it was opened as. + * + *

This will fail (with an {@link IllegalStateException} if the + * Document was opened read-only, opened from an {@link InputStream} + * instead of a File, or if this is not the root document. For those cases, + * you must use {@link #write(OutputStream)} or {@link #write(File)} to + * write to a brand new document. + * + * @since 3.15 */ @Override public void write() throws IOException { - // TODO Implement - throw new IllegalStateException("Coming soon!"); + validateInPlaceWritePossible(); + + // Update the Document+Properties streams in the file + write(directory.getFileSystem(), false); + + // Sync with the File on disk + directory.getFileSystem().writeFilesystem(); } /** @@ -912,22 +927,18 @@ public final class HWPFDocument extends HWPFDocumentCore { dataBuf = tempBuf; } - // create new document preserving order of entries - // TODO Check "copyOtherEntries" and tweak behaviour based on that - // TODO That's needed for in-place write + // Create a new document preserving order of entries / Update existing boolean docWritten = false; boolean dataWritten = false; boolean objectPoolWritten = false; boolean tableWritten = false; boolean propertiesWritten = false; - for ( Iterator iter = directory.getEntries(); iter.hasNext(); ) - { - Entry entry = iter.next(); + for (Entry entry : directory) { if ( entry.getName().equals( STREAM_WORD_DOCUMENT ) ) { if ( !docWritten ) { - pfs.createDocument( new ByteArrayInputStream( mainBuf ), + pfs.createOrUpdateDocument( new ByteArrayInputStream( mainBuf ), STREAM_WORD_DOCUMENT ); docWritten = true; } @@ -936,7 +947,11 @@ public final class HWPFDocument extends HWPFDocumentCore { { if ( !objectPoolWritten ) { - _objectPool.writeTo( pfs.getRoot() ); + if ( copyOtherEntries ) { + _objectPool.writeTo( pfs.getRoot() ); + } else { + // Object pool is already there, no need to change/copy + } objectPoolWritten = true; } } @@ -945,7 +960,7 @@ public final class HWPFDocument extends HWPFDocumentCore { { if ( !tableWritten ) { - pfs.createDocument( new ByteArrayInputStream( tableBuf ), + pfs.createOrUpdateDocument( new ByteArrayInputStream( tableBuf ), STREAM_TABLE_1 ); tableWritten = true; } @@ -965,29 +980,29 @@ public final class HWPFDocument extends HWPFDocumentCore { { if ( !dataWritten ) { - pfs.createDocument( new ByteArrayInputStream( dataBuf ), + pfs.createOrUpdateDocument( new ByteArrayInputStream( dataBuf ), STREAM_DATA ); dataWritten = true; } } - else + else if ( copyOtherEntries ) { EntryUtils.copyNodeRecursively( entry, pfs.getRoot() ); } } if ( !docWritten ) - pfs.createDocument( new ByteArrayInputStream( mainBuf ), + pfs.createOrUpdateDocument( new ByteArrayInputStream( mainBuf ), STREAM_WORD_DOCUMENT ); if ( !tableWritten ) - pfs.createDocument( new ByteArrayInputStream( tableBuf ), + pfs.createOrUpdateDocument( new ByteArrayInputStream( tableBuf ), STREAM_TABLE_1 ); if ( !propertiesWritten ) writeProperties( pfs ); if ( !dataWritten ) - pfs.createDocument( new ByteArrayInputStream( dataBuf ), + pfs.createOrUpdateDocument( new ByteArrayInputStream( dataBuf ), STREAM_DATA ); - if ( !objectPoolWritten ) + if ( !objectPoolWritten && copyOtherEntries ) _objectPool.writeTo( pfs.getRoot() ); this.directory = pfs.getRoot(); From 34a6732b01678de7360546f3f8f3ffdb46c49212 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Thu, 11 Aug 2016 15:27:33 +0000 Subject: [PATCH 046/157] Slightly simplify HWPF writing code, and add in-place write tests git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1756003 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/org/apache/poi/hwpf/HWPFDocument.java | 45 +++---------- .../poi/hwpf/usermodel/TestHWPFWrite.java | 67 ++++++++++++++++++- 2 files changed, 75 insertions(+), 37 deletions(-) diff --git a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java index 0d6538917..ce9d58f03 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java @@ -22,32 +22,10 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.Iterator; import org.apache.poi.hpsf.DocumentSummaryInformation; import org.apache.poi.hpsf.SummaryInformation; -import org.apache.poi.hwpf.model.BookmarksTables; -import org.apache.poi.hwpf.model.CHPBinTable; -import org.apache.poi.hwpf.model.ComplexFileTable; -import org.apache.poi.hwpf.model.DocumentProperties; -import org.apache.poi.hwpf.model.EscherRecordHolder; -import org.apache.poi.hwpf.model.FSPADocumentPart; -import org.apache.poi.hwpf.model.FSPATable; -import org.apache.poi.hwpf.model.FieldsTables; -import org.apache.poi.hwpf.model.FontTable; -import org.apache.poi.hwpf.model.ListTables; -import org.apache.poi.hwpf.model.NoteType; -import org.apache.poi.hwpf.model.NotesTables; -import org.apache.poi.hwpf.model.PAPBinTable; -import org.apache.poi.hwpf.model.PicturesTable; -import org.apache.poi.hwpf.model.RevisionMarkAuthorTable; -import org.apache.poi.hwpf.model.SavedByTable; -import org.apache.poi.hwpf.model.SectionTable; -import org.apache.poi.hwpf.model.SinglentonTextPiece; -import org.apache.poi.hwpf.model.StyleSheet; -import org.apache.poi.hwpf.model.SubdocumentType; -import org.apache.poi.hwpf.model.TextPiece; -import org.apache.poi.hwpf.model.TextPieceTable; +import org.apache.poi.hwpf.model.*; import org.apache.poi.hwpf.model.io.HWPFFileSystem; import org.apache.poi.hwpf.model.io.HWPFOutputStream; import org.apache.poi.hwpf.usermodel.Bookmarks; @@ -938,8 +916,7 @@ public final class HWPFDocument extends HWPFDocumentCore { { if ( !docWritten ) { - pfs.createOrUpdateDocument( new ByteArrayInputStream( mainBuf ), - STREAM_WORD_DOCUMENT ); + write(pfs, mainBuf, STREAM_WORD_DOCUMENT); docWritten = true; } } @@ -960,8 +937,7 @@ public final class HWPFDocument extends HWPFDocumentCore { { if ( !tableWritten ) { - pfs.createOrUpdateDocument( new ByteArrayInputStream( tableBuf ), - STREAM_TABLE_1 ); + write(pfs, tableBuf, STREAM_TABLE_1); tableWritten = true; } } @@ -980,8 +956,7 @@ public final class HWPFDocument extends HWPFDocumentCore { { if ( !dataWritten ) { - pfs.createOrUpdateDocument( new ByteArrayInputStream( dataBuf ), - STREAM_DATA ); + write(pfs, dataBuf, STREAM_DATA); dataWritten = true; } } @@ -992,16 +967,13 @@ public final class HWPFDocument extends HWPFDocumentCore { } if ( !docWritten ) - pfs.createOrUpdateDocument( new ByteArrayInputStream( mainBuf ), - STREAM_WORD_DOCUMENT ); + write(pfs, mainBuf, STREAM_WORD_DOCUMENT); if ( !tableWritten ) - pfs.createOrUpdateDocument( new ByteArrayInputStream( tableBuf ), - STREAM_TABLE_1 ); + write(pfs, tableBuf, STREAM_TABLE_1); if ( !propertiesWritten ) writeProperties( pfs ); if ( !dataWritten ) - pfs.createOrUpdateDocument( new ByteArrayInputStream( dataBuf ), - STREAM_DATA ); + write(pfs, dataBuf, STREAM_DATA); if ( !objectPoolWritten && copyOtherEntries ) _objectPool.writeTo( pfs.getRoot() ); @@ -1015,6 +987,9 @@ public final class HWPFDocument extends HWPFDocumentCore { this._tableStream = tableStream.toByteArray(); this._dataStream = dataBuf; } + private static void write(NPOIFSFileSystem pfs, byte[] data, String name) throws IOException { + pfs.createOrUpdateDocument(new ByteArrayInputStream(data), name); + } @Internal public byte[] getDataStream() diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestHWPFWrite.java b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestHWPFWrite.java index 95d7919e3..a45b031da 100644 --- a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestHWPFWrite.java +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestHWPFWrite.java @@ -21,11 +21,16 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; +import java.io.FileOutputStream; +import org.apache.poi.POIDataSamples; import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.HWPFTestCase; import org.apache.poi.hwpf.HWPFTestDataSamples; +import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; +import org.apache.poi.poifs.filesystem.OPOIFSFileSystem; import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.util.IOUtils; import org.apache.poi.util.TempFile; /** @@ -75,7 +80,65 @@ public final class TestHWPFWrite extends HWPFTestCase { r = doc.getRange(); assertEquals("I am a test document\r", r.getParagraph(0).text()); doc.close(); - } + } - // TODO In-place write positive and negative checks + /** + * Writing to the file we opened from - note, uses a temp file to + * avoid changing our test files! + */ + @SuppressWarnings("resource") + public void testInPlaceWrite() throws Exception { + // Setup as a copy of a known-good file + final File file = TempFile.createTempFile("TestDocument", ".doc"); + IOUtils.copy( + POIDataSamples.getDocumentInstance().openResourceAsStream("SampleDoc.doc"), + new FileOutputStream(file) + ); + + // Open from the temp file in read-write mode + HWPFDocument doc = new HWPFDocument(new NPOIFSFileSystem(file, false).getRoot()); + Range r = doc.getRange(); + assertEquals("I am a test document\r", r.getParagraph(0).text()); + + // Change + r.replaceText("X XX a test document\r", false); + + // Save in-place, close, re-open and check + doc.write(); + doc.close(); + + doc = new HWPFDocument(new NPOIFSFileSystem(file).getRoot()); + assertEquals("X XX a test document\r", r.getParagraph(0).text()); + } + + @SuppressWarnings("resource") + public void testInvalidInPlaceWrite() throws Exception { + HWPFDocument doc; + + // Can't work for InputStream opened files + doc = new HWPFDocument( + POIDataSamples.getDocumentInstance().openResourceAsStream("SampleDoc.doc")); + try { + doc.write(); + fail("Shouldn't work for InputStream"); + } catch (IllegalStateException e) {} + + // Can't work for OPOIFS + OPOIFSFileSystem ofs = new OPOIFSFileSystem( + POIDataSamples.getDocumentInstance().openResourceAsStream("SampleDoc.doc")); + doc = new HWPFDocument(ofs.getRoot()); + try { + doc.write(); + fail("Shouldn't work for OPOIFSFileSystem"); + } catch (IllegalStateException e) {} + + // Can't work for Read-Only files + NPOIFSFileSystem fs = new NPOIFSFileSystem( + POIDataSamples.getDocumentInstance().getFile("SampleDoc.doc"), true); + doc = new HWPFDocument(fs.getRoot()); + try { + doc.write(); + fail("Shouldn't work for Read Only"); + } catch (IllegalStateException e) {} + } } From e97b333ea00d5cbdc9cac81710932a7213609198 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Mon, 15 Aug 2016 04:42:31 +0000 Subject: [PATCH 047/157] bug 59773: move loop invariants out of for-loop for performance, use for-each instead of for loop when possible git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1756345 13f79535-47bb-0310-9956-ffa450edef68 --- .../hslf/extractor/PowerPointExtractor.java | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java b/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java index f248ab633..43c7d69bb 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java +++ b/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java @@ -257,8 +257,8 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor { // Comments, if requested and present if (getCommentText) { Comment[] comments = slide.getComments(); - for (int j = 0; j < comments.length; j++) { - ret.append(comments[j].getAuthor() + " - " + comments[j].getText() + "\n"); + for (Comment comment : slide.getComments()) { + ret.append(comment.getAuthor() + " - " + comment.getText() + "\n"); } } } @@ -285,8 +285,8 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor { } - for (int i = 0; i < _slides.size(); i++) { - HSLFNotes notes = _slides.get(i).getNotes(); + for (HSLFSlide slide : _slides) { + HSLFNotes notes = slide.getNotes(); if (notes == null) { continue; } @@ -297,13 +297,13 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor { seenNotes.add(id); // Repeat the Notes header, if set - ret.append(headerText); + ret.append(headerText); // Notes text - textRunsToText(ret, notes.getTextParagraphs()); + textRunsToText(ret, notes.getTextParagraphs()); // Repeat the notes footer, if set - ret.append(footerText); + ret.append(footerText); } } @@ -315,16 +315,18 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor { } private void extractTableText(StringBuffer ret, HSLFTable table) { - for (int row = 0; row < table.getNumberOfRows(); row++){ - for (int col = 0; col < table.getNumberOfColumns(); col++){ + final int nrows = table.getNumberOfRows(); + final int ncols = table.getNumberOfColumns(); + for (int row = 0; row < nrows; row++){ + for (int col = 0; col < ncols; col++){ HSLFTableCell cell = table.getCell(row, col); //defensive null checks; don't know if they're necessary if (cell != null){ String txt = cell.getText(); txt = (txt == null) ? "" : txt; ret.append(txt); - if (col < table.getNumberOfColumns()-1){ - ret.append("\t"); + if (col < ncols-1){ + ret.append('\t'); } } } @@ -339,7 +341,7 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor { for (List lp : paragraphs) { ret.append(HSLFTextParagraph.getText(lp)); if (ret.length() > 0 && ret.charAt(ret.length()-1) != '\n') { - ret.append("\n"); + ret.append('\n'); } } } From f3ba3ffe5f435a8e8282de64c54f8ac83893d723 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Mon, 15 Aug 2016 05:23:34 +0000 Subject: [PATCH 048/157] whitespace, remove unused variable, expose Set interface for seenNotes, append \n character instead of String git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1756348 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/hslf/extractor/PowerPointExtractor.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java b/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java index 43c7d69bb..59434f074 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java +++ b/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java @@ -240,9 +240,9 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor { } // Slide header, if set - ret.append(headerText); + ret.append(headerText); - // Slide text + // Slide text textRunsToText(ret, slide.getTextParagraphs()); // Table text @@ -256,14 +256,13 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor { // Comments, if requested and present if (getCommentText) { - Comment[] comments = slide.getComments(); for (Comment comment : slide.getComments()) { ret.append(comment.getAuthor() + " - " + comment.getText() + "\n"); } } } if (getNoteText) { - ret.append("\n"); + ret.append('\n'); } } @@ -271,7 +270,7 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor { // Not currently using _notes, as that can have the notes of // master sheets in. Grab Slide list, then work from there, // but ensure no duplicates - HashSet seenNotes = new HashSet(); + Set seenNotes = new HashSet(); String headerText = ""; String footerText = ""; HeadersFooters hf = _show.getNotesHeadersFooters(); From 8d38e8e67471fbb99ef77d82894efedab7fca2fd Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Mon, 15 Aug 2016 07:27:03 +0000 Subject: [PATCH 049/157] add (meta) unit test for POITestCase git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1756356 13f79535-47bb-0310-9956-ffa450edef68 --- src/testcases/org/apache/poi/POITestCase.java | 16 +++ .../org/apache/poi/TestPOITestCase.java | 126 ++++++++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 src/testcases/org/apache/poi/TestPOITestCase.java diff --git a/src/testcases/org/apache/poi/POITestCase.java b/src/testcases/org/apache/poi/POITestCase.java index 8fa16c88a..786c6e112 100644 --- a/src/testcases/org/apache/poi/POITestCase.java +++ b/src/testcases/org/apache/poi/POITestCase.java @@ -32,13 +32,16 @@ import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Map; import org.apache.poi.util.SuppressForbidden; +import org.apache.poi.util.Internal; /** * Util class for POI JUnit TestCases, which provide additional features */ +@Internal public final class POITestCase { public static void assertContains(String haystack, String needle) { assertNotNull(haystack); @@ -47,6 +50,19 @@ public final class POITestCase { haystack.contains(needle) ); } + + public static void assertContainsIgnoreCase(String haystack, String needle, Locale locale) { + assertNotNull(haystack); + assertNotNull(needle); + String hay = haystack.toLowerCase(locale); + String n = needle.toLowerCase(locale); + assertTrue("Unable to find expected text '" + needle + "' in text:\n" + haystack, + hay.contains(n) + ); + } + public static void assertContainsIgnoreCase(String haystack, String needle) { + assertContainsIgnoreCase(haystack, needle, Locale.ROOT); + } public static void assertNotContained(String haystack, String needle) { assertNotNull(haystack); diff --git a/src/testcases/org/apache/poi/TestPOITestCase.java b/src/testcases/org/apache/poi/TestPOITestCase.java new file mode 100644 index 000000000..fd9f3d1ad --- /dev/null +++ b/src/testcases/org/apache/poi/TestPOITestCase.java @@ -0,0 +1,126 @@ +/* ==================================================================== + 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Collections; +import java.util.Locale; +import java.util.Map; + +import org.apache.poi.POITestCase; +import org.junit.Ignore; +import org.junit.Test; + +/** + * A class for testing the POI Junit TestCase utility class + */ +public final class TestPOITestCase { + @Test + public void assertContains() { + POITestCase.assertContains("There is a needle in this haystack", "needle"); + /*try { + POITestCase.assertContains("There is gold in this haystack", "needle"); + fail("found a needle"); + } catch (final junit.framework.AssertionFailedError e) { + // expected + }*/ + } + + @Test + public void assertContainsIgnoreCase_Locale() { + POITestCase.assertContainsIgnoreCase("There is a Needle in this haystack", "needlE", Locale.ROOT); + // FIXME: test failing case + } + + @Test + public void assertContainsIgnoreCase() { + POITestCase.assertContainsIgnoreCase("There is a Needle in this haystack", "needlE"); + // FIXME: test failing case + } + + @Test + public void assertNotContained() { + POITestCase.assertNotContained("There is a needle in this haystack", "gold"); + // FIXME: test failing case + } + + @Test + public void assertMapContains() { + Map haystack = Collections.singletonMap("needle", "value"); + POITestCase.assertContains(haystack, "needle"); + // FIXME: test failing case + } + + + /** + * Utility method to get the value of a private/protected field. + * Only use this method in test cases!!! + */ + @Ignore + @Test + public void getFieldValue() { + /* + final Class clazz; + final T instance; + final Class fieldType; + final String fieldName; + + final R expected; + final R actual = POITestCase.getFieldValue(clazz, instance, fieldType, fieldName); + assertEquals(expected, actual); + */ + } + + /** + * Utility method to call a private/protected method. + * Only use this method in test cases!!! + */ + @Ignore + @Test + public void callMethod() { + /* + final Class clazz; + final T instance; + final Class returnType; + final String methodName; + final Class[] parameterTypes; + final Object[] parameters; + + final R expected; + final R actual = POITestCase.callMethod(clazz, instance, returnType, methodName, parameterTypes, parameters); + assertEquals(expected, actual); + */ + } + + /** + * Utility method to shallow compare all fields of the objects + * Only use this method in test cases!!! + */ + @Ignore + @Test + public void assertReflectEquals() throws Exception { + /* + final Object expected; + final Object actual; + POITestCase.assertReflectEquals(expected, actual); + */ + } +} From 16be8e597b8df3e8fb63ce9a6e1f7bbf45f59f78 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Mon, 15 Aug 2016 07:31:43 +0000 Subject: [PATCH 050/157] simplify unit test using assertContainsIgnoreCase git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1756357 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/hslf/extractor/TestExtractor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/extractor/TestExtractor.java b/src/scratchpad/testcases/org/apache/poi/hslf/extractor/TestExtractor.java index 5b78d1484..5e6b71928 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/extractor/TestExtractor.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/extractor/TestExtractor.java @@ -18,6 +18,7 @@ package org.apache.poi.hslf.extractor; import static org.apache.poi.POITestCase.assertContains; +import static org.apache.poi.POITestCase.assertContainsIgnoreCase; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -26,7 +27,6 @@ import static org.junit.Assert.assertTrue; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.util.List; -import java.util.Locale; import org.apache.poi.POIDataSamples; import org.apache.poi.hslf.model.OLEShape; @@ -355,7 +355,7 @@ public final class TestExtractor { ppe = new PowerPointExtractor(hslf); text = ppe.getText(); - assertContains(text.toLowerCase(Locale.ROOT), "master"); + assertContainsIgnoreCase(text, "master"); assertContains(text, masterText); } From 7c4e332b61b4a632d2292b3e7b01b4107c43cbae Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Mon, 15 Aug 2016 07:36:22 +0000 Subject: [PATCH 051/157] extract string constant out of code git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1756358 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/org/apache/poi/hslf/model/HeadersFooters.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HeadersFooters.java b/src/scratchpad/src/org/apache/poi/hslf/model/HeadersFooters.java index f34cd4be7..9bfa5f325 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/HeadersFooters.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/HeadersFooters.java @@ -36,6 +36,8 @@ import org.apache.poi.hslf.usermodel.HSLFTextShape; */ public final class HeadersFooters { + private static final String _ppt2007tag = "___PPT12"; + private final HeadersFootersContainer _container; private final HSLFSheet _sheet; private final boolean _ppt2007; @@ -54,7 +56,7 @@ public final class HeadersFooters { // detect if this ppt was saved in Office2007 String tag = ppt.getSlideMasters().get(0).getProgrammableTag(); - _ppt2007 = "___PPT12".equals(tag); + _ppt2007 = _ppt2007tag.equals(tag); SheetContainer sc = _sheet.getSheetContainer(); HeadersFootersContainer hdd = (HeadersFootersContainer)sc.findFirstOfType(RecordTypes.HeadersFooters.typeID); From 4f4941447327cef990eadf2b265741ce78c1b8f8 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Mon, 15 Aug 2016 08:09:32 +0000 Subject: [PATCH 052/157] make member variables final git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1756361 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/hslf/extractor/PowerPointExtractor.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java b/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java index 59434f074..44aa8a2d3 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java +++ b/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java @@ -32,9 +32,9 @@ import org.apache.poi.poifs.filesystem.*; * @author Nick Burch */ public final class PowerPointExtractor extends POIOLE2TextExtractor { - private HSLFSlideShowImpl _hslfshow; - private HSLFSlideShow _show; - private List _slides; + private final HSLFSlideShowImpl _hslfshow; + private final HSLFSlideShow _show; + private final List _slides; private boolean _slidesByDefault = true; private boolean _notesByDefault = false; From 779c0e527a6465f31ef30ac4b2e8875d649fe9a3 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Mon, 15 Aug 2016 16:05:32 +0000 Subject: [PATCH 053/157] bug 60005: fix NPE in XSLFTextParagraph.getDefaultFontSize() git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1756397 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/xslf/usermodel/XSLFTextParagraph.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java index edd17dec5..c5a2ce069 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java @@ -752,6 +752,10 @@ public class XSLFTextParagraph implements TextParagraphnull if + * there are no master slides or the master slides do not contain a text paragraph + */ /* package */ CTTextParagraphProperties getDefaultMasterStyle(){ CTPlaceholder ph = _shape.getCTPlaceholder(); String defaultStyleSelector; @@ -932,7 +936,11 @@ public class XSLFTextParagraph implements TextParagraph Date: Mon, 15 Aug 2016 16:08:11 +0000 Subject: [PATCH 054/157] +svn:eol-style=native git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1756398 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/xslf/usermodel/XSLFTextParagraph.java | 2158 ++++++++--------- 1 file changed, 1079 insertions(+), 1079 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java index c5a2ce069..38c298275 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java @@ -1,1079 +1,1079 @@ -/* ==================================================================== - 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.xslf.usermodel; - -import java.awt.Color; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.poi.sl.draw.DrawPaint; -import org.apache.poi.sl.usermodel.AutoNumberingScheme; -import org.apache.poi.sl.usermodel.PaintStyle; -import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; -import org.apache.poi.sl.usermodel.TextParagraph; -import org.apache.poi.util.Beta; -import org.apache.poi.util.Internal; -import org.apache.poi.util.Units; -import org.apache.poi.xslf.model.ParagraphPropertyFetcher; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextAutonumberBullet; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePercent; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePoint; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharBullet; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacing; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStop; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStopList; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextAutonumberScheme; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextFontAlignType; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; -import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; - -/** - * Represents a paragraph of text within the containing text body. - * The paragraph is the highest level text separation mechanism. - * - * @since POI-3.8 - */ -@Beta -public class XSLFTextParagraph implements TextParagraph { - private final CTTextParagraph _p; - private final List _runs; - private final XSLFTextShape _shape; - - XSLFTextParagraph(CTTextParagraph p, XSLFTextShape shape){ - _p = p; - _runs = new ArrayList(); - _shape = shape; - - for(XmlObject ch : _p.selectPath("*")){ - if(ch instanceof CTRegularTextRun){ - CTRegularTextRun r = (CTRegularTextRun)ch; - _runs.add(newTextRun(r)); - } else if (ch instanceof CTTextLineBreak){ - CTTextLineBreak br = (CTTextLineBreak)ch; - CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); - r.setRPr(br.getRPr()); - r.setT("\n"); - _runs.add(newTextRun(r)); - } else if (ch instanceof CTTextField){ - CTTextField f = (CTTextField)ch; - CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); - r.setRPr(f.getRPr()); - r.setT(f.getT()); - _runs.add(newTextRun(r)); - } - } - } - - public String getText(){ - StringBuilder out = new StringBuilder(); - for (XSLFTextRun r : _runs) { - out.append(r.getRawText()); - } - return out.toString(); - } - - String getRenderableText(){ - StringBuilder out = new StringBuilder(); - for (XSLFTextRun r : _runs) { - out.append(r.getRenderableText()); - } - return out.toString(); - } - - @Internal - public CTTextParagraph getXmlObject(){ - return _p; - } - - public XSLFTextShape getParentShape() { - return _shape; - - } - - @Override - public List getTextRuns(){ - return _runs; - } - - public Iterator iterator(){ - return _runs.iterator(); - } - - /** - * Add a new run of text - * - * @return a new run of text - */ - public XSLFTextRun addNewTextRun(){ - CTRegularTextRun r = _p.addNewR(); - CTTextCharacterProperties rPr = r.addNewRPr(); - rPr.setLang("en-US"); - XSLFTextRun run = newTextRun(r); - _runs.add(run); - return run; - } - - /** - * Insert a line break - * - * @return text run representing this line break ('\n') - */ - public XSLFTextRun addLineBreak(){ - CTTextLineBreak br = _p.addNewBr(); - CTTextCharacterProperties brProps = br.addNewRPr(); - if(_runs.size() > 0){ - // by default line break has the font size of the last text run - CTTextCharacterProperties prevRun = _runs.get(_runs.size() - 1).getRPr(true); - brProps.set(prevRun); - } - CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); - r.setRPr(brProps); - r.setT("\n"); - XSLFTextRun run = new XSLFLineBreak(r, this, brProps); - _runs.add(run); - return run; - } - - @Override - public TextAlign getTextAlign(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetAlgn()){ - TextAlign val = TextAlign.values()[props.getAlgn().intValue() - 1]; - setValue(val); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - @Override - public void setTextAlign(TextAlign align) { - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if(align == null) { - if(pr.isSetAlgn()) pr.unsetAlgn(); - } else { - pr.setAlgn(STTextAlignType.Enum.forInt(align.ordinal() + 1)); - } - } - - @Override - public FontAlign getFontAlign(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetFontAlgn()){ - FontAlign val = FontAlign.values()[props.getFontAlgn().intValue() - 1]; - setValue(val); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - /** - * Specifies the font alignment that is to be applied to the paragraph. - * Possible values for this include auto, top, center, baseline and bottom. - * see {@link org.apache.poi.sl.usermodel.TextParagraph.FontAlign}. - * - * @param align font align - */ - public void setFontAlign(FontAlign align){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if(align == null) { - if(pr.isSetFontAlgn()) pr.unsetFontAlgn(); - } else { - pr.setFontAlgn(STTextFontAlignType.Enum.forInt(align.ordinal() + 1)); - } - } - - - - /** - * @return the font to be used on bullet characters within a given paragraph - */ - public String getBulletFont(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetBuFont()){ - setValue(props.getBuFont().getTypeface()); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - public void setBulletFont(String typeface){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextFont font = pr.isSetBuFont() ? pr.getBuFont() : pr.addNewBuFont(); - font.setTypeface(typeface); - } - - /** - * @return the character to be used in place of the standard bullet point - */ - public String getBulletCharacter(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetBuChar()){ - setValue(props.getBuChar().getChar()); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - public void setBulletCharacter(String str){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextCharBullet c = pr.isSetBuChar() ? pr.getBuChar() : pr.addNewBuChar(); - c.setChar(str); - } - - /** - * - * @return the color of bullet characters within a given paragraph. - * A null value means to use the text font color. - */ - public PaintStyle getBulletFontColor(){ - final XSLFTheme theme = getParentShape().getSheet().getTheme(); - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetBuClr()){ - XSLFColor c = new XSLFColor(props.getBuClr(), theme, null); - setValue(c.getColor()); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - Color col = fetcher.getValue(); - return (col == null) ? null : DrawPaint.createSolidPaint(col); - } - - public void setBulletFontColor(Color color) { - setBulletFontColor(DrawPaint.createSolidPaint(color)); - } - - - /** - * Set the color to be used on bullet characters within a given paragraph. - * - * @param color the bullet color - */ - public void setBulletFontColor(PaintStyle color) { - if (!(color instanceof SolidPaint)) { - throw new IllegalArgumentException("Currently XSLF only supports SolidPaint"); - } - - // TODO: implement setting bullet color to null - SolidPaint sp = (SolidPaint)color; - Color col = DrawPaint.applyColorTransform(sp.getSolidColor()); - - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTColor c = pr.isSetBuClr() ? pr.getBuClr() : pr.addNewBuClr(); - CTSRgbColor clr = c.isSetSrgbClr() ? c.getSrgbClr() : c.addNewSrgbClr(); - clr.setVal(new byte[]{(byte) col.getRed(), (byte) col.getGreen(), (byte) col.getBlue()}); - } - - /** - * Returns the bullet size that is to be used within a paragraph. - * This may be specified in two different ways, percentage spacing and font point spacing: - *

- * If bulletSize >= 0, then bulletSize is a percentage of the font size. - * If bulletSize < 0, then it specifies the size in points - *

- * - * @return the bullet size - */ - public Double getBulletFontSize(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetBuSzPct()){ - setValue(props.getBuSzPct().getVal() * 0.001); - return true; - } - if(props.isSetBuSzPts()){ - setValue( - props.getBuSzPts().getVal() * 0.01); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - /** - * Sets the bullet size that is to be used within a paragraph. - * This may be specified in two different ways, percentage spacing and font point spacing: - *

- * If bulletSize >= 0, then bulletSize is a percentage of the font size. - * If bulletSize < 0, then it specifies the size in points - *

- */ - public void setBulletFontSize(double bulletSize){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - - if(bulletSize >= 0) { - CTTextBulletSizePercent pt = pr.isSetBuSzPct() ? pr.getBuSzPct() : pr.addNewBuSzPct(); - pt.setVal((int)(bulletSize*1000)); - if(pr.isSetBuSzPts()) pr.unsetBuSzPts(); - } else { - CTTextBulletSizePoint pt = pr.isSetBuSzPts() ? pr.getBuSzPts() : pr.addNewBuSzPts(); - pt.setVal((int)(-bulletSize*100)); - if(pr.isSetBuSzPct()) pr.unsetBuSzPct(); - } - } - - /** - * @return the auto numbering scheme, or null if not defined - */ - public AutoNumberingScheme getAutoNumberingScheme() { - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()) { - public boolean fetch(CTTextParagraphProperties props) { - if (props.isSetBuAutoNum()) { - AutoNumberingScheme ans = AutoNumberingScheme.forOoxmlID(props.getBuAutoNum().getType().intValue()); - if (ans != null) { - setValue(ans); - return true; - } - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - /** - * @return the auto numbering starting number, or null if not defined - */ - public Integer getAutoNumberingStartAt() { - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()) { - public boolean fetch(CTTextParagraphProperties props) { - if (props.isSetBuAutoNum()) { - if (props.getBuAutoNum().isSetStartAt()) { - setValue(props.getBuAutoNum().getStartAt()); - return true; - } - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - - @Override - public void setIndent(Double indent){ - if ((indent == null) && !_p.isSetPPr()) return; - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if(indent == null) { - if(pr.isSetIndent()) pr.unsetIndent(); - } else { - pr.setIndent(Units.toEMU(indent)); - } - } - - @Override - public Double getIndent() { - - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetIndent()){ - setValue(Units.toPoints(props.getIndent())); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - - return fetcher.getValue(); - } - - @Override - public void setLeftMargin(Double leftMargin){ - if (leftMargin == null && !_p.isSetPPr()) return; - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if (leftMargin == null) { - if(pr.isSetMarL()) pr.unsetMarL(); - } else { - pr.setMarL(Units.toEMU(leftMargin)); - } - - } - - /** - * @return the left margin (in points) of the paragraph, null if unset - */ - @Override - public Double getLeftMargin(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetMarL()){ - double val = Units.toPoints(props.getMarL()); - setValue(val); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - // if the marL attribute is omitted, then a value of 347663 is implied - return fetcher.getValue(); - } - - @Override - public void setRightMargin(Double rightMargin){ - if (rightMargin == null && !_p.isSetPPr()) return; - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if(rightMargin == null) { - if(pr.isSetMarR()) pr.unsetMarR(); - } else { - pr.setMarR(Units.toEMU(rightMargin)); - } - } - - /** - * - * @return the right margin of the paragraph, null if unset - */ - @Override - public Double getRightMargin(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetMarR()){ - double val = Units.toPoints(props.getMarR()); - setValue(val); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - @Override - public Double getDefaultTabSize(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetDefTabSz()){ - double val = Units.toPoints(props.getDefTabSz()); - setValue(val); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - public double getTabStop(final int idx){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetTabLst()){ - CTTextTabStopList tabStops = props.getTabLst(); - if(idx < tabStops.sizeOfTabArray() ) { - CTTextTabStop ts = tabStops.getTabArray(idx); - double val = Units.toPoints(ts.getPos()); - setValue(val); - return true; - } - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue() == null ? 0. : fetcher.getValue(); - } - - public void addTabStop(double value){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextTabStopList tabStops = pr.isSetTabLst() ? pr.getTabLst() : pr.addNewTabLst(); - tabStops.addNewTab().setPos(Units.toEMU(value)); - } - - @Override - public void setLineSpacing(Double lineSpacing){ - if (lineSpacing == null && !_p.isSetPPr()) return; - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if(lineSpacing == null) { - if (pr.isSetLnSpc()) pr.unsetLnSpc(); - } else { - CTTextSpacing spc = (pr.isSetLnSpc()) ? pr.getLnSpc() : pr.addNewLnSpc(); - if (lineSpacing >= 0) { - (spc.isSetSpcPct() ? spc.getSpcPct() : spc.addNewSpcPct()).setVal((int)(lineSpacing*1000)); - if (spc.isSetSpcPts()) spc.unsetSpcPts(); - } else { - (spc.isSetSpcPts() ? spc.getSpcPts() : spc.addNewSpcPts()).setVal((int)(-lineSpacing*100)); - if (spc.isSetSpcPct()) spc.unsetSpcPct(); - } - } - } - - @Override - public Double getLineSpacing(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetLnSpc()){ - CTTextSpacing spc = props.getLnSpc(); - - if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 ); - else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 ); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - - Double lnSpc = fetcher.getValue(); - if (lnSpc != null && lnSpc > 0) { - // check if the percentage value is scaled - CTTextNormalAutofit normAutofit = getParentShape().getTextBodyPr().getNormAutofit(); - if(normAutofit != null) { - double scale = 1 - (double)normAutofit.getLnSpcReduction() / 100000; - lnSpc *= scale; - } - } - - return lnSpc; - } - - @Override - public void setSpaceBefore(Double spaceBefore){ - if (spaceBefore == null && !_p.isSetPPr()) { - return; - } - - // unset the space before on null input - if (spaceBefore == null) { - if(_p.getPPr().isSetSpcBef()) { - _p.getPPr().unsetSpcBef(); - } - return; - } - - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextSpacing spc = CTTextSpacing.Factory.newInstance(); - - if(spaceBefore >= 0) { - spc.addNewSpcPct().setVal((int)(spaceBefore*1000)); - } else { - spc.addNewSpcPts().setVal((int)(-spaceBefore*100)); - } - pr.setSpcBef(spc); - } - - @Override - public Double getSpaceBefore(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetSpcBef()){ - CTTextSpacing spc = props.getSpcBef(); - - if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 ); - else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 ); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - - return fetcher.getValue(); - } - - @Override - public void setSpaceAfter(Double spaceAfter){ - if (spaceAfter == null && !_p.isSetPPr()) { - return; - } - - // unset the space before on null input - if (spaceAfter == null) { - if(_p.getPPr().isSetSpcAft()) { - _p.getPPr().unsetSpcAft(); - } - return; - } - - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextSpacing spc = CTTextSpacing.Factory.newInstance(); - - if(spaceAfter >= 0) { - spc.addNewSpcPct().setVal((int)(spaceAfter*1000)); - } else { - spc.addNewSpcPts().setVal((int)(-spaceAfter*100)); - } - pr.setSpcAft(spc); - } - - @Override - public Double getSpaceAfter(){ - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetSpcAft()){ - CTTextSpacing spc = props.getSpcAft(); - - if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 ); - else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 ); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue(); - } - - @Override - public void setIndentLevel(int level){ - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - pr.setLvl(level); - } - - @Override - public int getIndentLevel() { - CTTextParagraphProperties pr = _p.getPPr(); - return (pr == null || !pr.isSetLvl()) ? 0 : pr.getLvl(); - } - - /** - * Returns whether this paragraph has bullets - */ - public boolean isBullet() { - ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ - public boolean fetch(CTTextParagraphProperties props){ - if(props.isSetBuNone()) { - setValue(false); - return true; - } - if(props.isSetBuFont() || props.isSetBuChar()){ - setValue(true); - return true; - } - return false; - } - }; - fetchParagraphProperty(fetcher); - return fetcher.getValue() == null ? false : fetcher.getValue(); - } - - /** - * - * @param flag whether text in this paragraph has bullets - */ - public void setBullet(boolean flag) { - if(isBullet() == flag) return; - - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - if(flag) { - pr.addNewBuFont().setTypeface("Arial"); - pr.addNewBuChar().setChar("\u2022"); - } else { - if (pr.isSetBuFont()) pr.unsetBuFont(); - if (pr.isSetBuChar()) pr.unsetBuChar(); - if (pr.isSetBuAutoNum()) pr.unsetBuAutoNum(); - if (pr.isSetBuBlip()) pr.unsetBuBlip(); - if (pr.isSetBuClr()) pr.unsetBuClr(); - if (pr.isSetBuClrTx()) pr.unsetBuClrTx(); - if (pr.isSetBuFont()) pr.unsetBuFont(); - if (pr.isSetBuFontTx()) pr.unsetBuFontTx(); - if (pr.isSetBuSzPct()) pr.unsetBuSzPct(); - if (pr.isSetBuSzPts()) pr.unsetBuSzPts(); - if (pr.isSetBuSzTx()) pr.unsetBuSzTx(); - pr.addNewBuNone(); - } - } - - /** - * Specifies that automatic numbered bullet points should be applied to this paragraph - * - * @param scheme type of auto-numbering - * @param startAt the number that will start number for a given sequence of automatically - numbered bullets (1-based). - */ - public void setBulletAutoNumber(AutoNumberingScheme scheme, int startAt) { - if(startAt < 1) throw new IllegalArgumentException("Start Number must be greater or equal that 1") ; - CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); - CTTextAutonumberBullet lst = pr.isSetBuAutoNum() ? pr.getBuAutoNum() : pr.addNewBuAutoNum(); - lst.setType(STTextAutonumberScheme.Enum.forInt(scheme.ooxmlId)); - lst.setStartAt(startAt); - } - - @Override - public String toString(){ - return "[" + getClass() + "]" + getText(); - } - - - /** - * @return master style text paragraph properties, or null if - * there are no master slides or the master slides do not contain a text paragraph - */ - /* package */ CTTextParagraphProperties getDefaultMasterStyle(){ - CTPlaceholder ph = _shape.getCTPlaceholder(); - String defaultStyleSelector; - switch(ph == null ? -1 : ph.getType().intValue()) { - case STPlaceholderType.INT_TITLE: - case STPlaceholderType.INT_CTR_TITLE: - defaultStyleSelector = "titleStyle"; - break; - case -1: // no placeholder means plain text box - case STPlaceholderType.INT_FTR: - case STPlaceholderType.INT_SLD_NUM: - case STPlaceholderType.INT_DT: - defaultStyleSelector = "otherStyle"; - break; - default: - defaultStyleSelector = "bodyStyle"; - break; - } - int level = getIndentLevel(); - - // wind up and find the root master sheet which must be slide master - final String nsPML = "http://schemas.openxmlformats.org/presentationml/2006/main"; - final String nsDML = "http://schemas.openxmlformats.org/drawingml/2006/main"; - XSLFSheet masterSheet = _shape.getSheet(); - for (XSLFSheet m = masterSheet; m != null; m = (XSLFSheet)m.getMasterSheet()) { - masterSheet = m; - XmlObject xo = masterSheet.getXmlObject(); - XmlCursor cur = xo.newCursor(); - try { - cur.push(); - if ((cur.toChild(nsPML, "txStyles") && cur.toChild(nsPML, defaultStyleSelector)) || - (cur.pop() && cur.toChild(nsPML, "notesStyle"))) { - while (level >= 0) { - cur.push(); - if (cur.toChild(nsDML, "lvl" +(level+1)+ "pPr")) { - return (CTTextParagraphProperties)cur.getObject(); - } - cur.pop(); - level--; - } - } - } finally { - cur.dispose(); - } - } - - return null; - } - - private boolean fetchParagraphProperty(ParagraphPropertyFetcher visitor){ - boolean ok = false; - XSLFTextShape shape = getParentShape(); - XSLFSheet sheet = shape.getSheet(); - - if(_p.isSetPPr()) ok = visitor.fetch(_p.getPPr()); - if (ok) return true; - - ok = shape.fetchShapeProperty(visitor); - if (ok) return true; - - - CTPlaceholder ph = shape.getCTPlaceholder(); - if(ph == null){ - // if it is a plain text box then take defaults from presentation.xml - @SuppressWarnings("resource") - XMLSlideShow ppt = sheet.getSlideShow(); - CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(getIndentLevel()); - if (themeProps != null) ok = visitor.fetch(themeProps); - } - if (ok) return true; - - // defaults for placeholders are defined in the slide master - CTTextParagraphProperties defaultProps = getDefaultMasterStyle(); - // TODO: determine master shape - if(defaultProps != null) ok = visitor.fetch(defaultProps); - if (ok) return true; - - return false; - } - - void copy(XSLFTextParagraph other){ - if (other == this) return; - - CTTextParagraph thisP = getXmlObject(); - CTTextParagraph otherP = other.getXmlObject(); - - if (thisP.isSetPPr()) thisP.unsetPPr(); - if (thisP.isSetEndParaRPr()) thisP.unsetEndParaRPr(); - - _runs.clear(); - for (int i=thisP.sizeOfBrArray(); i>0; i--) { - thisP.removeBr(i-1); - } - for (int i=thisP.sizeOfRArray(); i>0; i--) { - thisP.removeR(i-1); - } - for (int i=thisP.sizeOfFldArray(); i>0; i--) { - thisP.removeFld(i-1); - } - - XmlCursor thisC = thisP.newCursor(); - thisC.toEndToken(); - XmlCursor otherC = otherP.newCursor(); - otherC.copyXmlContents(thisC); - otherC.dispose(); - thisC.dispose(); - - List otherRs = other.getTextRuns(); - int i=0; - for(CTRegularTextRun rtr : thisP.getRArray()) { - XSLFTextRun run = newTextRun(rtr); - run.copy(otherRs.get(i++)); - _runs.add(run); - } - - - // set properties again, in case we are based on a different - // template - TextAlign srcAlign = other.getTextAlign(); - if(srcAlign != getTextAlign()){ - setTextAlign(srcAlign); - } - - boolean isBullet = other.isBullet(); - if(isBullet != isBullet()){ - setBullet(isBullet); - if(isBullet) { - String buFont = other.getBulletFont(); - if(buFont != null && !buFont.equals(getBulletFont())){ - setBulletFont(buFont); - } - String buChar = other.getBulletCharacter(); - if(buChar != null && !buChar.equals(getBulletCharacter())){ - setBulletCharacter(buChar); - } - PaintStyle buColor = other.getBulletFontColor(); - if(buColor != null && !buColor.equals(getBulletFontColor())){ - setBulletFontColor(buColor); - } - Double buSize = other.getBulletFontSize(); - if(!doubleEquals(buSize, getBulletFontSize())){ - setBulletFontSize(buSize); - } - } - } - - Double leftMargin = other.getLeftMargin(); - if (!doubleEquals(leftMargin, getLeftMargin())){ - setLeftMargin(leftMargin); - } - - Double indent = other.getIndent(); - if (!doubleEquals(indent, getIndent())) { - setIndent(indent); - } - - Double spaceAfter = other.getSpaceAfter(); - if (!doubleEquals(spaceAfter, getSpaceAfter())) { - setSpaceAfter(spaceAfter); - } - - Double spaceBefore = other.getSpaceBefore(); - if (!doubleEquals(spaceBefore, getSpaceBefore())) { - setSpaceBefore(spaceBefore); - } - - Double lineSpacing = other.getLineSpacing(); - if (!doubleEquals(lineSpacing, getLineSpacing())) { - setLineSpacing(lineSpacing); - } - } - - private static boolean doubleEquals(Double d1, Double d2) { - return (d1 == d2 || (d1 != null && d1.equals(d2))); - } - - @Override - public Double getDefaultFontSize() { - CTTextCharacterProperties endPr = _p.getEndParaRPr(); - if (endPr == null || !endPr.isSetSz()) { - // inherit the font size from the master style - CTTextParagraphProperties masterStyle = getDefaultMasterStyle(); - if (masterStyle != null) { - endPr = masterStyle.getDefRPr(); - } - } - return (endPr == null || !endPr.isSetSz()) ? 12 : (endPr.getSz() / 100.); - } - - @Override - public String getDefaultFontFamily() { - return (_runs.isEmpty() ? "Arial" : _runs.get(0).getFontFamily()); - } - - @Override - public BulletStyle getBulletStyle() { - if (!isBullet()) return null; - return new BulletStyle(){ - @Override - public String getBulletCharacter() { - return XSLFTextParagraph.this.getBulletCharacter(); - } - - @Override - public String getBulletFont() { - return XSLFTextParagraph.this.getBulletFont(); - } - - @Override - public Double getBulletFontSize() { - return XSLFTextParagraph.this.getBulletFontSize(); - } - - @Override - public PaintStyle getBulletFontColor() { - return XSLFTextParagraph.this.getBulletFontColor(); - } - - @Override - public void setBulletFontColor(Color color) { - setBulletFontColor(DrawPaint.createSolidPaint(color)); - } - - @Override - public void setBulletFontColor(PaintStyle color) { - XSLFTextParagraph.this.setBulletFontColor(color); - } - - @Override - public AutoNumberingScheme getAutoNumberingScheme() { - return XSLFTextParagraph.this.getAutoNumberingScheme(); - } - - @Override - public Integer getAutoNumberingStartAt() { - return XSLFTextParagraph.this.getAutoNumberingStartAt(); - } - - }; - } - - @Override - public void setBulletStyle(Object... styles) { - if (styles.length == 0) { - setBullet(false); - } else { - setBullet(true); - for (Object ostyle : styles) { - if (ostyle instanceof Number) { - setBulletFontSize(((Number)ostyle).doubleValue()); - } else if (ostyle instanceof Color) { - setBulletFontColor((Color)ostyle); - } else if (ostyle instanceof Character) { - setBulletCharacter(ostyle.toString()); - } else if (ostyle instanceof String) { - setBulletFont((String)ostyle); - } else if (ostyle instanceof AutoNumberingScheme) { - setBulletAutoNumber((AutoNumberingScheme)ostyle, 0); - } - } - } - } - - /** - * Helper method for appending text and keeping paragraph and character properties. - * The character properties are moved to the end paragraph marker - */ - /* package */ void clearButKeepProperties() { - CTTextParagraph thisP = getXmlObject(); - for (int i=thisP.sizeOfBrArray(); i>0; i--) { - thisP.removeBr(i-1); - } - for (int i=thisP.sizeOfFldArray(); i>0; i--) { - thisP.removeFld(i-1); - } - if (!_runs.isEmpty()) { - int size = _runs.size(); - XSLFTextRun lastRun = _runs.get(size-1); - CTTextCharacterProperties cpOther = lastRun.getRPr(false); - if (cpOther != null) { - if (thisP.isSetEndParaRPr()) { - thisP.unsetEndParaRPr(); - } - CTTextCharacterProperties cp = thisP.addNewEndParaRPr(); - cp.set(cpOther); - } - for (int i=size; i>0; i--) { - thisP.removeR(i-1); - } - _runs.clear(); - } - } - - @Override - public boolean isHeaderOrFooter() { - CTPlaceholder ph = _shape.getCTPlaceholder(); - int phId = (ph == null ? -1 : ph.getType().intValue()); - switch (phId) { - case STPlaceholderType.INT_SLD_NUM: - case STPlaceholderType.INT_DT: - case STPlaceholderType.INT_FTR: - case STPlaceholderType.INT_HDR: - return true; - default: - return false; - } - } - - /** - * Helper method to allow subclasses to provide their own text run - * - * @param r the xml reference - * - * @return a new text paragraph - * - * @since POI 3.15-beta2 - */ - protected XSLFTextRun newTextRun(CTRegularTextRun r) { - return new XSLFTextRun(r, this); - } -} +/* ==================================================================== + 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.xslf.usermodel; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.poi.sl.draw.DrawPaint; +import org.apache.poi.sl.usermodel.AutoNumberingScheme; +import org.apache.poi.sl.usermodel.PaintStyle; +import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; +import org.apache.poi.sl.usermodel.TextParagraph; +import org.apache.poi.util.Beta; +import org.apache.poi.util.Internal; +import org.apache.poi.util.Units; +import org.apache.poi.xslf.model.ParagraphPropertyFetcher; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlObject; +import org.openxmlformats.schemas.drawingml.x2006.main.CTColor; +import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; +import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextAutonumberBullet; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePercent; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePoint; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharBullet; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacing; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStop; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStopList; +import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType; +import org.openxmlformats.schemas.drawingml.x2006.main.STTextAutonumberScheme; +import org.openxmlformats.schemas.drawingml.x2006.main.STTextFontAlignType; +import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; +import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; + +/** + * Represents a paragraph of text within the containing text body. + * The paragraph is the highest level text separation mechanism. + * + * @since POI-3.8 + */ +@Beta +public class XSLFTextParagraph implements TextParagraph { + private final CTTextParagraph _p; + private final List _runs; + private final XSLFTextShape _shape; + + XSLFTextParagraph(CTTextParagraph p, XSLFTextShape shape){ + _p = p; + _runs = new ArrayList(); + _shape = shape; + + for(XmlObject ch : _p.selectPath("*")){ + if(ch instanceof CTRegularTextRun){ + CTRegularTextRun r = (CTRegularTextRun)ch; + _runs.add(newTextRun(r)); + } else if (ch instanceof CTTextLineBreak){ + CTTextLineBreak br = (CTTextLineBreak)ch; + CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); + r.setRPr(br.getRPr()); + r.setT("\n"); + _runs.add(newTextRun(r)); + } else if (ch instanceof CTTextField){ + CTTextField f = (CTTextField)ch; + CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); + r.setRPr(f.getRPr()); + r.setT(f.getT()); + _runs.add(newTextRun(r)); + } + } + } + + public String getText(){ + StringBuilder out = new StringBuilder(); + for (XSLFTextRun r : _runs) { + out.append(r.getRawText()); + } + return out.toString(); + } + + String getRenderableText(){ + StringBuilder out = new StringBuilder(); + for (XSLFTextRun r : _runs) { + out.append(r.getRenderableText()); + } + return out.toString(); + } + + @Internal + public CTTextParagraph getXmlObject(){ + return _p; + } + + public XSLFTextShape getParentShape() { + return _shape; + + } + + @Override + public List getTextRuns(){ + return _runs; + } + + public Iterator iterator(){ + return _runs.iterator(); + } + + /** + * Add a new run of text + * + * @return a new run of text + */ + public XSLFTextRun addNewTextRun(){ + CTRegularTextRun r = _p.addNewR(); + CTTextCharacterProperties rPr = r.addNewRPr(); + rPr.setLang("en-US"); + XSLFTextRun run = newTextRun(r); + _runs.add(run); + return run; + } + + /** + * Insert a line break + * + * @return text run representing this line break ('\n') + */ + public XSLFTextRun addLineBreak(){ + CTTextLineBreak br = _p.addNewBr(); + CTTextCharacterProperties brProps = br.addNewRPr(); + if(_runs.size() > 0){ + // by default line break has the font size of the last text run + CTTextCharacterProperties prevRun = _runs.get(_runs.size() - 1).getRPr(true); + brProps.set(prevRun); + } + CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); + r.setRPr(brProps); + r.setT("\n"); + XSLFTextRun run = new XSLFLineBreak(r, this, brProps); + _runs.add(run); + return run; + } + + @Override + public TextAlign getTextAlign(){ + ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ + public boolean fetch(CTTextParagraphProperties props){ + if(props.isSetAlgn()){ + TextAlign val = TextAlign.values()[props.getAlgn().intValue() - 1]; + setValue(val); + return true; + } + return false; + } + }; + fetchParagraphProperty(fetcher); + return fetcher.getValue(); + } + + @Override + public void setTextAlign(TextAlign align) { + CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); + if(align == null) { + if(pr.isSetAlgn()) pr.unsetAlgn(); + } else { + pr.setAlgn(STTextAlignType.Enum.forInt(align.ordinal() + 1)); + } + } + + @Override + public FontAlign getFontAlign(){ + ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ + public boolean fetch(CTTextParagraphProperties props){ + if(props.isSetFontAlgn()){ + FontAlign val = FontAlign.values()[props.getFontAlgn().intValue() - 1]; + setValue(val); + return true; + } + return false; + } + }; + fetchParagraphProperty(fetcher); + return fetcher.getValue(); + } + + /** + * Specifies the font alignment that is to be applied to the paragraph. + * Possible values for this include auto, top, center, baseline and bottom. + * see {@link org.apache.poi.sl.usermodel.TextParagraph.FontAlign}. + * + * @param align font align + */ + public void setFontAlign(FontAlign align){ + CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); + if(align == null) { + if(pr.isSetFontAlgn()) pr.unsetFontAlgn(); + } else { + pr.setFontAlgn(STTextFontAlignType.Enum.forInt(align.ordinal() + 1)); + } + } + + + + /** + * @return the font to be used on bullet characters within a given paragraph + */ + public String getBulletFont(){ + ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ + public boolean fetch(CTTextParagraphProperties props){ + if(props.isSetBuFont()){ + setValue(props.getBuFont().getTypeface()); + return true; + } + return false; + } + }; + fetchParagraphProperty(fetcher); + return fetcher.getValue(); + } + + public void setBulletFont(String typeface){ + CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); + CTTextFont font = pr.isSetBuFont() ? pr.getBuFont() : pr.addNewBuFont(); + font.setTypeface(typeface); + } + + /** + * @return the character to be used in place of the standard bullet point + */ + public String getBulletCharacter(){ + ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ + public boolean fetch(CTTextParagraphProperties props){ + if(props.isSetBuChar()){ + setValue(props.getBuChar().getChar()); + return true; + } + return false; + } + }; + fetchParagraphProperty(fetcher); + return fetcher.getValue(); + } + + public void setBulletCharacter(String str){ + CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); + CTTextCharBullet c = pr.isSetBuChar() ? pr.getBuChar() : pr.addNewBuChar(); + c.setChar(str); + } + + /** + * + * @return the color of bullet characters within a given paragraph. + * A null value means to use the text font color. + */ + public PaintStyle getBulletFontColor(){ + final XSLFTheme theme = getParentShape().getSheet().getTheme(); + ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ + public boolean fetch(CTTextParagraphProperties props){ + if(props.isSetBuClr()){ + XSLFColor c = new XSLFColor(props.getBuClr(), theme, null); + setValue(c.getColor()); + return true; + } + return false; + } + }; + fetchParagraphProperty(fetcher); + Color col = fetcher.getValue(); + return (col == null) ? null : DrawPaint.createSolidPaint(col); + } + + public void setBulletFontColor(Color color) { + setBulletFontColor(DrawPaint.createSolidPaint(color)); + } + + + /** + * Set the color to be used on bullet characters within a given paragraph. + * + * @param color the bullet color + */ + public void setBulletFontColor(PaintStyle color) { + if (!(color instanceof SolidPaint)) { + throw new IllegalArgumentException("Currently XSLF only supports SolidPaint"); + } + + // TODO: implement setting bullet color to null + SolidPaint sp = (SolidPaint)color; + Color col = DrawPaint.applyColorTransform(sp.getSolidColor()); + + CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); + CTColor c = pr.isSetBuClr() ? pr.getBuClr() : pr.addNewBuClr(); + CTSRgbColor clr = c.isSetSrgbClr() ? c.getSrgbClr() : c.addNewSrgbClr(); + clr.setVal(new byte[]{(byte) col.getRed(), (byte) col.getGreen(), (byte) col.getBlue()}); + } + + /** + * Returns the bullet size that is to be used within a paragraph. + * This may be specified in two different ways, percentage spacing and font point spacing: + *

+ * If bulletSize >= 0, then bulletSize is a percentage of the font size. + * If bulletSize < 0, then it specifies the size in points + *

+ * + * @return the bullet size + */ + public Double getBulletFontSize(){ + ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ + public boolean fetch(CTTextParagraphProperties props){ + if(props.isSetBuSzPct()){ + setValue(props.getBuSzPct().getVal() * 0.001); + return true; + } + if(props.isSetBuSzPts()){ + setValue( - props.getBuSzPts().getVal() * 0.01); + return true; + } + return false; + } + }; + fetchParagraphProperty(fetcher); + return fetcher.getValue(); + } + + /** + * Sets the bullet size that is to be used within a paragraph. + * This may be specified in two different ways, percentage spacing and font point spacing: + *

+ * If bulletSize >= 0, then bulletSize is a percentage of the font size. + * If bulletSize < 0, then it specifies the size in points + *

+ */ + public void setBulletFontSize(double bulletSize){ + CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); + + if(bulletSize >= 0) { + CTTextBulletSizePercent pt = pr.isSetBuSzPct() ? pr.getBuSzPct() : pr.addNewBuSzPct(); + pt.setVal((int)(bulletSize*1000)); + if(pr.isSetBuSzPts()) pr.unsetBuSzPts(); + } else { + CTTextBulletSizePoint pt = pr.isSetBuSzPts() ? pr.getBuSzPts() : pr.addNewBuSzPts(); + pt.setVal((int)(-bulletSize*100)); + if(pr.isSetBuSzPct()) pr.unsetBuSzPct(); + } + } + + /** + * @return the auto numbering scheme, or null if not defined + */ + public AutoNumberingScheme getAutoNumberingScheme() { + ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()) { + public boolean fetch(CTTextParagraphProperties props) { + if (props.isSetBuAutoNum()) { + AutoNumberingScheme ans = AutoNumberingScheme.forOoxmlID(props.getBuAutoNum().getType().intValue()); + if (ans != null) { + setValue(ans); + return true; + } + } + return false; + } + }; + fetchParagraphProperty(fetcher); + return fetcher.getValue(); + } + + /** + * @return the auto numbering starting number, or null if not defined + */ + public Integer getAutoNumberingStartAt() { + ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()) { + public boolean fetch(CTTextParagraphProperties props) { + if (props.isSetBuAutoNum()) { + if (props.getBuAutoNum().isSetStartAt()) { + setValue(props.getBuAutoNum().getStartAt()); + return true; + } + } + return false; + } + }; + fetchParagraphProperty(fetcher); + return fetcher.getValue(); + } + + + @Override + public void setIndent(Double indent){ + if ((indent == null) && !_p.isSetPPr()) return; + CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); + if(indent == null) { + if(pr.isSetIndent()) pr.unsetIndent(); + } else { + pr.setIndent(Units.toEMU(indent)); + } + } + + @Override + public Double getIndent() { + + ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ + public boolean fetch(CTTextParagraphProperties props){ + if(props.isSetIndent()){ + setValue(Units.toPoints(props.getIndent())); + return true; + } + return false; + } + }; + fetchParagraphProperty(fetcher); + + return fetcher.getValue(); + } + + @Override + public void setLeftMargin(Double leftMargin){ + if (leftMargin == null && !_p.isSetPPr()) return; + CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); + if (leftMargin == null) { + if(pr.isSetMarL()) pr.unsetMarL(); + } else { + pr.setMarL(Units.toEMU(leftMargin)); + } + + } + + /** + * @return the left margin (in points) of the paragraph, null if unset + */ + @Override + public Double getLeftMargin(){ + ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ + public boolean fetch(CTTextParagraphProperties props){ + if(props.isSetMarL()){ + double val = Units.toPoints(props.getMarL()); + setValue(val); + return true; + } + return false; + } + }; + fetchParagraphProperty(fetcher); + // if the marL attribute is omitted, then a value of 347663 is implied + return fetcher.getValue(); + } + + @Override + public void setRightMargin(Double rightMargin){ + if (rightMargin == null && !_p.isSetPPr()) return; + CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); + if(rightMargin == null) { + if(pr.isSetMarR()) pr.unsetMarR(); + } else { + pr.setMarR(Units.toEMU(rightMargin)); + } + } + + /** + * + * @return the right margin of the paragraph, null if unset + */ + @Override + public Double getRightMargin(){ + ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ + public boolean fetch(CTTextParagraphProperties props){ + if(props.isSetMarR()){ + double val = Units.toPoints(props.getMarR()); + setValue(val); + return true; + } + return false; + } + }; + fetchParagraphProperty(fetcher); + return fetcher.getValue(); + } + + @Override + public Double getDefaultTabSize(){ + ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ + public boolean fetch(CTTextParagraphProperties props){ + if(props.isSetDefTabSz()){ + double val = Units.toPoints(props.getDefTabSz()); + setValue(val); + return true; + } + return false; + } + }; + fetchParagraphProperty(fetcher); + return fetcher.getValue(); + } + + public double getTabStop(final int idx){ + ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ + public boolean fetch(CTTextParagraphProperties props){ + if(props.isSetTabLst()){ + CTTextTabStopList tabStops = props.getTabLst(); + if(idx < tabStops.sizeOfTabArray() ) { + CTTextTabStop ts = tabStops.getTabArray(idx); + double val = Units.toPoints(ts.getPos()); + setValue(val); + return true; + } + } + return false; + } + }; + fetchParagraphProperty(fetcher); + return fetcher.getValue() == null ? 0. : fetcher.getValue(); + } + + public void addTabStop(double value){ + CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); + CTTextTabStopList tabStops = pr.isSetTabLst() ? pr.getTabLst() : pr.addNewTabLst(); + tabStops.addNewTab().setPos(Units.toEMU(value)); + } + + @Override + public void setLineSpacing(Double lineSpacing){ + if (lineSpacing == null && !_p.isSetPPr()) return; + CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); + if(lineSpacing == null) { + if (pr.isSetLnSpc()) pr.unsetLnSpc(); + } else { + CTTextSpacing spc = (pr.isSetLnSpc()) ? pr.getLnSpc() : pr.addNewLnSpc(); + if (lineSpacing >= 0) { + (spc.isSetSpcPct() ? spc.getSpcPct() : spc.addNewSpcPct()).setVal((int)(lineSpacing*1000)); + if (spc.isSetSpcPts()) spc.unsetSpcPts(); + } else { + (spc.isSetSpcPts() ? spc.getSpcPts() : spc.addNewSpcPts()).setVal((int)(-lineSpacing*100)); + if (spc.isSetSpcPct()) spc.unsetSpcPct(); + } + } + } + + @Override + public Double getLineSpacing(){ + ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ + public boolean fetch(CTTextParagraphProperties props){ + if(props.isSetLnSpc()){ + CTTextSpacing spc = props.getLnSpc(); + + if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 ); + else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 ); + return true; + } + return false; + } + }; + fetchParagraphProperty(fetcher); + + Double lnSpc = fetcher.getValue(); + if (lnSpc != null && lnSpc > 0) { + // check if the percentage value is scaled + CTTextNormalAutofit normAutofit = getParentShape().getTextBodyPr().getNormAutofit(); + if(normAutofit != null) { + double scale = 1 - (double)normAutofit.getLnSpcReduction() / 100000; + lnSpc *= scale; + } + } + + return lnSpc; + } + + @Override + public void setSpaceBefore(Double spaceBefore){ + if (spaceBefore == null && !_p.isSetPPr()) { + return; + } + + // unset the space before on null input + if (spaceBefore == null) { + if(_p.getPPr().isSetSpcBef()) { + _p.getPPr().unsetSpcBef(); + } + return; + } + + CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); + CTTextSpacing spc = CTTextSpacing.Factory.newInstance(); + + if(spaceBefore >= 0) { + spc.addNewSpcPct().setVal((int)(spaceBefore*1000)); + } else { + spc.addNewSpcPts().setVal((int)(-spaceBefore*100)); + } + pr.setSpcBef(spc); + } + + @Override + public Double getSpaceBefore(){ + ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ + public boolean fetch(CTTextParagraphProperties props){ + if(props.isSetSpcBef()){ + CTTextSpacing spc = props.getSpcBef(); + + if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 ); + else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 ); + return true; + } + return false; + } + }; + fetchParagraphProperty(fetcher); + + return fetcher.getValue(); + } + + @Override + public void setSpaceAfter(Double spaceAfter){ + if (spaceAfter == null && !_p.isSetPPr()) { + return; + } + + // unset the space before on null input + if (spaceAfter == null) { + if(_p.getPPr().isSetSpcAft()) { + _p.getPPr().unsetSpcAft(); + } + return; + } + + CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); + CTTextSpacing spc = CTTextSpacing.Factory.newInstance(); + + if(spaceAfter >= 0) { + spc.addNewSpcPct().setVal((int)(spaceAfter*1000)); + } else { + spc.addNewSpcPts().setVal((int)(-spaceAfter*100)); + } + pr.setSpcAft(spc); + } + + @Override + public Double getSpaceAfter(){ + ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ + public boolean fetch(CTTextParagraphProperties props){ + if(props.isSetSpcAft()){ + CTTextSpacing spc = props.getSpcAft(); + + if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 ); + else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 ); + return true; + } + return false; + } + }; + fetchParagraphProperty(fetcher); + return fetcher.getValue(); + } + + @Override + public void setIndentLevel(int level){ + CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); + pr.setLvl(level); + } + + @Override + public int getIndentLevel() { + CTTextParagraphProperties pr = _p.getPPr(); + return (pr == null || !pr.isSetLvl()) ? 0 : pr.getLvl(); + } + + /** + * Returns whether this paragraph has bullets + */ + public boolean isBullet() { + ParagraphPropertyFetcher fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ + public boolean fetch(CTTextParagraphProperties props){ + if(props.isSetBuNone()) { + setValue(false); + return true; + } + if(props.isSetBuFont() || props.isSetBuChar()){ + setValue(true); + return true; + } + return false; + } + }; + fetchParagraphProperty(fetcher); + return fetcher.getValue() == null ? false : fetcher.getValue(); + } + + /** + * + * @param flag whether text in this paragraph has bullets + */ + public void setBullet(boolean flag) { + if(isBullet() == flag) return; + + CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); + if(flag) { + pr.addNewBuFont().setTypeface("Arial"); + pr.addNewBuChar().setChar("\u2022"); + } else { + if (pr.isSetBuFont()) pr.unsetBuFont(); + if (pr.isSetBuChar()) pr.unsetBuChar(); + if (pr.isSetBuAutoNum()) pr.unsetBuAutoNum(); + if (pr.isSetBuBlip()) pr.unsetBuBlip(); + if (pr.isSetBuClr()) pr.unsetBuClr(); + if (pr.isSetBuClrTx()) pr.unsetBuClrTx(); + if (pr.isSetBuFont()) pr.unsetBuFont(); + if (pr.isSetBuFontTx()) pr.unsetBuFontTx(); + if (pr.isSetBuSzPct()) pr.unsetBuSzPct(); + if (pr.isSetBuSzPts()) pr.unsetBuSzPts(); + if (pr.isSetBuSzTx()) pr.unsetBuSzTx(); + pr.addNewBuNone(); + } + } + + /** + * Specifies that automatic numbered bullet points should be applied to this paragraph + * + * @param scheme type of auto-numbering + * @param startAt the number that will start number for a given sequence of automatically + numbered bullets (1-based). + */ + public void setBulletAutoNumber(AutoNumberingScheme scheme, int startAt) { + if(startAt < 1) throw new IllegalArgumentException("Start Number must be greater or equal that 1") ; + CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); + CTTextAutonumberBullet lst = pr.isSetBuAutoNum() ? pr.getBuAutoNum() : pr.addNewBuAutoNum(); + lst.setType(STTextAutonumberScheme.Enum.forInt(scheme.ooxmlId)); + lst.setStartAt(startAt); + } + + @Override + public String toString(){ + return "[" + getClass() + "]" + getText(); + } + + + /** + * @return master style text paragraph properties, or null if + * there are no master slides or the master slides do not contain a text paragraph + */ + /* package */ CTTextParagraphProperties getDefaultMasterStyle(){ + CTPlaceholder ph = _shape.getCTPlaceholder(); + String defaultStyleSelector; + switch(ph == null ? -1 : ph.getType().intValue()) { + case STPlaceholderType.INT_TITLE: + case STPlaceholderType.INT_CTR_TITLE: + defaultStyleSelector = "titleStyle"; + break; + case -1: // no placeholder means plain text box + case STPlaceholderType.INT_FTR: + case STPlaceholderType.INT_SLD_NUM: + case STPlaceholderType.INT_DT: + defaultStyleSelector = "otherStyle"; + break; + default: + defaultStyleSelector = "bodyStyle"; + break; + } + int level = getIndentLevel(); + + // wind up and find the root master sheet which must be slide master + final String nsPML = "http://schemas.openxmlformats.org/presentationml/2006/main"; + final String nsDML = "http://schemas.openxmlformats.org/drawingml/2006/main"; + XSLFSheet masterSheet = _shape.getSheet(); + for (XSLFSheet m = masterSheet; m != null; m = (XSLFSheet)m.getMasterSheet()) { + masterSheet = m; + XmlObject xo = masterSheet.getXmlObject(); + XmlCursor cur = xo.newCursor(); + try { + cur.push(); + if ((cur.toChild(nsPML, "txStyles") && cur.toChild(nsPML, defaultStyleSelector)) || + (cur.pop() && cur.toChild(nsPML, "notesStyle"))) { + while (level >= 0) { + cur.push(); + if (cur.toChild(nsDML, "lvl" +(level+1)+ "pPr")) { + return (CTTextParagraphProperties)cur.getObject(); + } + cur.pop(); + level--; + } + } + } finally { + cur.dispose(); + } + } + + return null; + } + + private boolean fetchParagraphProperty(ParagraphPropertyFetcher visitor){ + boolean ok = false; + XSLFTextShape shape = getParentShape(); + XSLFSheet sheet = shape.getSheet(); + + if(_p.isSetPPr()) ok = visitor.fetch(_p.getPPr()); + if (ok) return true; + + ok = shape.fetchShapeProperty(visitor); + if (ok) return true; + + + CTPlaceholder ph = shape.getCTPlaceholder(); + if(ph == null){ + // if it is a plain text box then take defaults from presentation.xml + @SuppressWarnings("resource") + XMLSlideShow ppt = sheet.getSlideShow(); + CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(getIndentLevel()); + if (themeProps != null) ok = visitor.fetch(themeProps); + } + if (ok) return true; + + // defaults for placeholders are defined in the slide master + CTTextParagraphProperties defaultProps = getDefaultMasterStyle(); + // TODO: determine master shape + if(defaultProps != null) ok = visitor.fetch(defaultProps); + if (ok) return true; + + return false; + } + + void copy(XSLFTextParagraph other){ + if (other == this) return; + + CTTextParagraph thisP = getXmlObject(); + CTTextParagraph otherP = other.getXmlObject(); + + if (thisP.isSetPPr()) thisP.unsetPPr(); + if (thisP.isSetEndParaRPr()) thisP.unsetEndParaRPr(); + + _runs.clear(); + for (int i=thisP.sizeOfBrArray(); i>0; i--) { + thisP.removeBr(i-1); + } + for (int i=thisP.sizeOfRArray(); i>0; i--) { + thisP.removeR(i-1); + } + for (int i=thisP.sizeOfFldArray(); i>0; i--) { + thisP.removeFld(i-1); + } + + XmlCursor thisC = thisP.newCursor(); + thisC.toEndToken(); + XmlCursor otherC = otherP.newCursor(); + otherC.copyXmlContents(thisC); + otherC.dispose(); + thisC.dispose(); + + List otherRs = other.getTextRuns(); + int i=0; + for(CTRegularTextRun rtr : thisP.getRArray()) { + XSLFTextRun run = newTextRun(rtr); + run.copy(otherRs.get(i++)); + _runs.add(run); + } + + + // set properties again, in case we are based on a different + // template + TextAlign srcAlign = other.getTextAlign(); + if(srcAlign != getTextAlign()){ + setTextAlign(srcAlign); + } + + boolean isBullet = other.isBullet(); + if(isBullet != isBullet()){ + setBullet(isBullet); + if(isBullet) { + String buFont = other.getBulletFont(); + if(buFont != null && !buFont.equals(getBulletFont())){ + setBulletFont(buFont); + } + String buChar = other.getBulletCharacter(); + if(buChar != null && !buChar.equals(getBulletCharacter())){ + setBulletCharacter(buChar); + } + PaintStyle buColor = other.getBulletFontColor(); + if(buColor != null && !buColor.equals(getBulletFontColor())){ + setBulletFontColor(buColor); + } + Double buSize = other.getBulletFontSize(); + if(!doubleEquals(buSize, getBulletFontSize())){ + setBulletFontSize(buSize); + } + } + } + + Double leftMargin = other.getLeftMargin(); + if (!doubleEquals(leftMargin, getLeftMargin())){ + setLeftMargin(leftMargin); + } + + Double indent = other.getIndent(); + if (!doubleEquals(indent, getIndent())) { + setIndent(indent); + } + + Double spaceAfter = other.getSpaceAfter(); + if (!doubleEquals(spaceAfter, getSpaceAfter())) { + setSpaceAfter(spaceAfter); + } + + Double spaceBefore = other.getSpaceBefore(); + if (!doubleEquals(spaceBefore, getSpaceBefore())) { + setSpaceBefore(spaceBefore); + } + + Double lineSpacing = other.getLineSpacing(); + if (!doubleEquals(lineSpacing, getLineSpacing())) { + setLineSpacing(lineSpacing); + } + } + + private static boolean doubleEquals(Double d1, Double d2) { + return (d1 == d2 || (d1 != null && d1.equals(d2))); + } + + @Override + public Double getDefaultFontSize() { + CTTextCharacterProperties endPr = _p.getEndParaRPr(); + if (endPr == null || !endPr.isSetSz()) { + // inherit the font size from the master style + CTTextParagraphProperties masterStyle = getDefaultMasterStyle(); + if (masterStyle != null) { + endPr = masterStyle.getDefRPr(); + } + } + return (endPr == null || !endPr.isSetSz()) ? 12 : (endPr.getSz() / 100.); + } + + @Override + public String getDefaultFontFamily() { + return (_runs.isEmpty() ? "Arial" : _runs.get(0).getFontFamily()); + } + + @Override + public BulletStyle getBulletStyle() { + if (!isBullet()) return null; + return new BulletStyle(){ + @Override + public String getBulletCharacter() { + return XSLFTextParagraph.this.getBulletCharacter(); + } + + @Override + public String getBulletFont() { + return XSLFTextParagraph.this.getBulletFont(); + } + + @Override + public Double getBulletFontSize() { + return XSLFTextParagraph.this.getBulletFontSize(); + } + + @Override + public PaintStyle getBulletFontColor() { + return XSLFTextParagraph.this.getBulletFontColor(); + } + + @Override + public void setBulletFontColor(Color color) { + setBulletFontColor(DrawPaint.createSolidPaint(color)); + } + + @Override + public void setBulletFontColor(PaintStyle color) { + XSLFTextParagraph.this.setBulletFontColor(color); + } + + @Override + public AutoNumberingScheme getAutoNumberingScheme() { + return XSLFTextParagraph.this.getAutoNumberingScheme(); + } + + @Override + public Integer getAutoNumberingStartAt() { + return XSLFTextParagraph.this.getAutoNumberingStartAt(); + } + + }; + } + + @Override + public void setBulletStyle(Object... styles) { + if (styles.length == 0) { + setBullet(false); + } else { + setBullet(true); + for (Object ostyle : styles) { + if (ostyle instanceof Number) { + setBulletFontSize(((Number)ostyle).doubleValue()); + } else if (ostyle instanceof Color) { + setBulletFontColor((Color)ostyle); + } else if (ostyle instanceof Character) { + setBulletCharacter(ostyle.toString()); + } else if (ostyle instanceof String) { + setBulletFont((String)ostyle); + } else if (ostyle instanceof AutoNumberingScheme) { + setBulletAutoNumber((AutoNumberingScheme)ostyle, 0); + } + } + } + } + + /** + * Helper method for appending text and keeping paragraph and character properties. + * The character properties are moved to the end paragraph marker + */ + /* package */ void clearButKeepProperties() { + CTTextParagraph thisP = getXmlObject(); + for (int i=thisP.sizeOfBrArray(); i>0; i--) { + thisP.removeBr(i-1); + } + for (int i=thisP.sizeOfFldArray(); i>0; i--) { + thisP.removeFld(i-1); + } + if (!_runs.isEmpty()) { + int size = _runs.size(); + XSLFTextRun lastRun = _runs.get(size-1); + CTTextCharacterProperties cpOther = lastRun.getRPr(false); + if (cpOther != null) { + if (thisP.isSetEndParaRPr()) { + thisP.unsetEndParaRPr(); + } + CTTextCharacterProperties cp = thisP.addNewEndParaRPr(); + cp.set(cpOther); + } + for (int i=size; i>0; i--) { + thisP.removeR(i-1); + } + _runs.clear(); + } + } + + @Override + public boolean isHeaderOrFooter() { + CTPlaceholder ph = _shape.getCTPlaceholder(); + int phId = (ph == null ? -1 : ph.getType().intValue()); + switch (phId) { + case STPlaceholderType.INT_SLD_NUM: + case STPlaceholderType.INT_DT: + case STPlaceholderType.INT_FTR: + case STPlaceholderType.INT_HDR: + return true; + default: + return false; + } + } + + /** + * Helper method to allow subclasses to provide their own text run + * + * @param r the xml reference + * + * @return a new text paragraph + * + * @since POI 3.15-beta2 + */ + protected XSLFTextRun newTextRun(CTRegularTextRun r) { + return new XSLFTextRun(r, this); + } +} From 403db2b86638df9c39e3a008d4a4ee251e0de323 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Mon, 15 Aug 2016 17:17:06 +0000 Subject: [PATCH 055/157] decrease TestSXSSFSheetAutoSizeColumn COLUMN_WIDTH_THRESHOLD_BETWEEN_SHORT_AND_LONG so that poi-ooxml-schemas can be built on 'Java: 1.8.0_101/1.8.0_101-b13/25.101-b13/OpenJDK 64-Bit Server VM from Oracle Corporation on Linux: 4.7.0-1-default' git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1756402 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/xssf/streaming/TestSXSSFSheetAutoSizeColumn.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheetAutoSizeColumn.java b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheetAutoSizeColumn.java index 9685b950b..15acbfca0 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheetAutoSizeColumn.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheetAutoSizeColumn.java @@ -63,7 +63,7 @@ public class TestSXSSFSheetAutoSizeColumn { // longCellValue ends up with approx. column width 10_000 (on my machine) // so shortCellValue can be expected to be < 5000 for all fonts // and longCellValue can be expected to be > 5000 for all fonts - private static final int COLUMN_WIDTH_THRESHOLD_BETWEEN_SHORT_AND_LONG = 5000; + private static final int COLUMN_WIDTH_THRESHOLD_BETWEEN_SHORT_AND_LONG = 4000; private static final int MAX_COLUMN_WIDTH = 255*256; private static final SortedSet columns; From f7bf4150851c21f0febb37c6828826285ce214b4 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Tue, 16 Aug 2016 21:43:31 +0000 Subject: [PATCH 056/157] revert r1753048 due to AIOOB regression git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1756552 13f79535-47bb-0310-9956-ffa450edef68 --- .../hwpf/sprm/SectionSprmUncompressor.java | 98 +++++++++---------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/src/scratchpad/src/org/apache/poi/hwpf/sprm/SectionSprmUncompressor.java b/src/scratchpad/src/org/apache/poi/hwpf/sprm/SectionSprmUncompressor.java index bc578720e..0b186b56b 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/sprm/SectionSprmUncompressor.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/sprm/SectionSprmUncompressor.java @@ -24,11 +24,12 @@ import org.apache.poi.util.Internal; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; + @Internal public final class SectionSprmUncompressor extends SprmUncompressor { private static final POILogger logger = POILogFactory.getLogger(SectionSprmUncompressor.class); - + public SectionSprmUncompressor() { } @@ -58,15 +59,14 @@ public final class SectionSprmUncompressor extends SprmUncompressor */ static void unCompressSEPOperation (SectionProperties newSEP, SprmOperation sprm) { - final int operation = sprm.getOperation(); - final int operand = sprm.getOperand(); + int operation = sprm.getOperation(); switch (operation) { case 0: - newSEP.setCnsPgn ((byte) operand); + newSEP.setCnsPgn ((byte) sprm.getOperand()); break; case 0x1: - newSEP.setIHeadingPgn ((byte) operand); + newSEP.setIHeadingPgn ((byte) sprm.getOperand()); break; case 0x2: byte[] buf = new byte[sprm.size() - 3]; @@ -80,110 +80,110 @@ public final class SectionSprmUncompressor extends SprmUncompressor //not quite sure break; case 0x5: - newSEP.setFEvenlySpaced (getFlag (operand)); + newSEP.setFEvenlySpaced (getFlag (sprm.getOperand())); break; case 0x6: - newSEP.setFUnlocked (getFlag (operand)); + newSEP.setFUnlocked (getFlag (sprm.getOperand())); break; case 0x7: - newSEP.setDmBinFirst ((short) operand); + newSEP.setDmBinFirst ((short) sprm.getOperand()); break; case 0x8: - newSEP.setDmBinOther ((short) operand); + newSEP.setDmBinOther ((short) sprm.getOperand()); break; case 0x9: - newSEP.setBkc ((byte) operand); + newSEP.setBkc ((byte) sprm.getOperand()); break; case 0xa: - newSEP.setFTitlePage (getFlag (operand)); + newSEP.setFTitlePage (getFlag (sprm.getOperand())); break; case 0xb: - newSEP.setCcolM1 ((short) operand); + newSEP.setCcolM1 ((short) sprm.getOperand()); break; case 0xc: - newSEP.setDxaColumns (operand); + newSEP.setDxaColumns (sprm.getOperand()); break; case 0xd: - newSEP.setFAutoPgn (getFlag (operand)); + newSEP.setFAutoPgn (getFlag (sprm.getOperand())); break; case 0xe: - newSEP.setNfcPgn ((byte) operand); + newSEP.setNfcPgn ((byte) sprm.getOperand()); break; case 0xf: - newSEP.setDyaPgn ((short) operand); + newSEP.setDyaPgn ((short) sprm.getOperand()); break; case 0x10: - newSEP.setDxaPgn ((short) operand); + newSEP.setDxaPgn ((short) sprm.getOperand()); break; case 0x11: - newSEP.setFPgnRestart (getFlag (operand)); + newSEP.setFPgnRestart (getFlag (sprm.getOperand())); break; case 0x12: - newSEP.setFEndNote (getFlag (operand)); + newSEP.setFEndNote (getFlag (sprm.getOperand())); break; case 0x13: - newSEP.setLnc ((byte) operand); + newSEP.setLnc ((byte) sprm.getOperand()); break; case 0x14: - newSEP.setGrpfIhdt ((byte) operand); + newSEP.setGrpfIhdt ((byte) sprm.getOperand()); break; case 0x15: - newSEP.setNLnnMod ((short) operand); + newSEP.setNLnnMod ((short) sprm.getOperand()); break; case 0x16: - newSEP.setDxaLnn (operand); + newSEP.setDxaLnn (sprm.getOperand()); break; case 0x17: - newSEP.setDyaHdrTop (operand); + newSEP.setDyaHdrTop (sprm.getOperand()); break; case 0x18: - newSEP.setDyaHdrBottom (operand); + newSEP.setDyaHdrBottom (sprm.getOperand()); break; case 0x19: - newSEP.setFLBetween (getFlag (operand)); + newSEP.setFLBetween (getFlag (sprm.getOperand())); break; case 0x1a: - newSEP.setVjc ((byte) operand); + newSEP.setVjc ((byte) sprm.getOperand()); break; case 0x1b: - newSEP.setLnnMin ((short) operand); + newSEP.setLnnMin ((short) sprm.getOperand()); break; case 0x1c: - newSEP.setPgnStart ((short) operand); + newSEP.setPgnStart ((short) sprm.getOperand()); break; case 0x1d: - newSEP.setDmOrientPage( operand != 0 ); + newSEP.setDmOrientPage( sprm.getOperand() != 0 ); break; case 0x1e: //nothing break; case 0x1f: - newSEP.setXaPage (operand); + newSEP.setXaPage (sprm.getOperand()); break; case 0x20: - newSEP.setYaPage (operand); + newSEP.setYaPage (sprm.getOperand()); break; case 0x21: - newSEP.setDxaLeft (operand); + newSEP.setDxaLeft (sprm.getOperand()); break; case 0x22: - newSEP.setDxaRight (operand); + newSEP.setDxaRight (sprm.getOperand()); break; case 0x23: - newSEP.setDyaTop (operand); + newSEP.setDyaTop (sprm.getOperand()); break; case 0x24: - newSEP.setDyaBottom (operand); + newSEP.setDyaBottom (sprm.getOperand()); break; case 0x25: - newSEP.setDzaGutter (operand); + newSEP.setDzaGutter (sprm.getOperand()); break; case 0x26: - newSEP.setDmPaperReq ((short) operand); + newSEP.setDmPaperReq ((short) sprm.getOperand()); break; case 0x27: - newSEP.setFPropMark (getFlag (operand)); + newSEP.setFPropMark (getFlag (sprm.getOperand())); break; case 0x28: break; @@ -204,40 +204,40 @@ public final class SectionSprmUncompressor extends SprmUncompressor newSEP.setBrcRight(new BorderCode(sprm.getGrpprl(), sprm.getGrpprlOffset())); break; case 0x2f: - newSEP.setPgbProp (operand); + newSEP.setPgbProp (sprm.getOperand()); break; case 0x30: - newSEP.setDxtCharSpace (operand); + newSEP.setDxtCharSpace (sprm.getOperand()); break; case 0x31: - newSEP.setDyaLinePitch (operand); + newSEP.setDyaLinePitch (sprm.getOperand()); break; case 0x33: - newSEP.setWTextFlow ((short) operand); + newSEP.setWTextFlow ((short) sprm.getOperand()); break; case 0x3C: // [MS-DOC], v20140721, 2.6.4, sprmSRncFtn - newSEP.setRncFtn((short) operand); + newSEP.setRncFtn((short) sprm.getOperand()); break; case 0x3E: // [MS-DOC], v20140721, 2.6.4, sprmSRncEdn - newSEP.setRncEdn((short) operand); + newSEP.setRncEdn((short) sprm.getOperand()); break; case 0x3F: // [MS-DOC], v20140721, 2.6.4, sprmSNFtn - newSEP.setNFtn(operand); + newSEP.setNFtn((int) sprm.getOperand()); break; case 0x40: // [MS-DOC], v20140721, 2.6.4, sprmSNFtnRef - newSEP.setNfcFtnRef(operand); + newSEP.setNfcFtnRef((int) sprm.getOperand()); break; case 0x41: // [MS-DOC], v20140721, 2.6.4, sprmSNEdn - newSEP.setNEdn(operand); + newSEP.setNEdn((int) sprm.getOperand()); break; case 0x42: // [MS-DOC], v20140721, 2.6.4, sprmSNEdnRef - newSEP.setNfcEdnRef(operand); + newSEP.setNfcEdnRef((int) sprm.getOperand()); break; default: logger.log(POILogger.INFO, "Unsupported Sprm operation: " + operation + " (" + HexDump.byteToHex(operation) + ")"); From 3d87a1f00209fed4db995dc36edcdff41022463f Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Sun, 21 Aug 2016 11:19:42 +0000 Subject: [PATCH 057/157] changed expiration date of kiwiwings@apache.org git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1757046 13f79535-47bb-0310-9956-ffa450edef68 --- KEYS | 55 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/KEYS b/KEYS index 811af6f51..6767cb00a 100644 --- a/KEYS +++ b/KEYS @@ -1753,10 +1753,11 @@ W45jdvBkYoPdQtS+8Vy+q0997zobctz8i5hfXzxg51/IuSU4uNtgr26XapsoLDur 7PoqJGZ6UdBVwyb0qZqs6KLGQkEyJ8358ivjJsjxUR8diK027wWnW/s= =/Vu1 -----END PGP PUBLIC KEY BLOCK----- -pub 2048R/26062CE3 2014-08-17 [expires: 2016-08-16] -uid Andreas Beeker -uid Andreas Beeker (kiwiwings) -sub 2048R/EE864ED6 2014-08-17 [expires: 2016-08-16] + +pub rsa2048/26062CE3 2014-08-17 [expires: 2018-08-21] +uid [ultimate] Andreas Beeker +uid [ultimate] Andreas Beeker (kiwiwings) +sub rsa2048/EE864ED6 2014-08-17 [expires: 2018-08-21] -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v2 @@ -1767,14 +1768,14 @@ ODjjNQtn+nYmOu7a8Xg3g3vTnikkuHZqWvK0O0VYouW/p1NHelUejQbOPuUKukD1 omzskuYgteTZ9Jn8efJMIymg9dGubuvN4HvUdEO0/u6K2MCZjIqNEPeqWIuZXeMb +4nGv2r0jSQAU94g3hueooqbUf+Mk2+H5O1d/h2Cii9qVvi6gELdVw9H+5Ir9AFc ynsmvxrPIxraBMPgrXmvPFOTlqlizyFv2O7pABEBAAG0JUFuZHJlYXMgQmVla2Vy -IDxraXdpd2luZ3NAYXBhY2hlLm9yZz6JAUEEEwECACsCGwMFCQPCZwAGCwkIBwMC -BhUIAgkKCwQWAgMBAh4BAheABQJUS6SzAhkBAAoJEKk+HEsmBizjjdYIALH3trht -6JTfPz2UsltFTcjzqLXG/I8Vq5hkr0s4ex1V7oNDXrBRBb1WC1pcEe1xqvQmoTyP -dUoX8lCyLOrt3IRpgjnH/4ACyenfOw6yHl6aaXX3HvseL3oHQTMpzkny+xVsrUzJ -wVCRVACPM49L6nRj4YRYaZqAn42x2peYHNcfFrvKsDtTnt4SbFQBlmuiDtlePM6a -9wzqXMFkX+9hcHp/SgOwDalpameoRQ/Itf1w2hN9dxYuaUWojo6b0XpChzkCHKix -uEKtjJXTovRlc6DzxT2Z5JMPhATiN3ZCo88lfd/kK8aMZgV4fruaq/QQRjNK/Hgn -6fP9jPARncSFHkCJAT4EEwECACgFAlPxECkCGwMFCQPCZwAGCwkIBwMCBhUIAgkK +IDxraXdpd2luZ3NAYXBhY2hlLm9yZz6JAUEEEwECACsCGwMGCwkIBwMCBhUIAgkK +CwQWAgMBAh4BAheAAhkBBQJXuYpTBQkHizsfAAoJEKk+HEsmBizjNa0H/AjJPguQ +WIn9AV/jstRN4OPM6eY7VUMG1DYoABRQSVsksPki5jZii0bI9VB3AUFgfXj0y6qk +CwQyKCJwZjcP3JuciJ5brQr/7D12hoTkYSCzCaECIpMoB7HWCpdoFusrgU2PUUwJ +i8xBTC+sLxIn3h5abTU68tnynCYhlA0mJ8zZ8CTvQJyEjidY1UgSohXClG2k/mo7 +z/IyW16x4dlpdkNfiBhL2v/5Ol7Vuz9g1lXvWvMdNQZ2PVK6w5dmCziCkih/qRgK +SUzn65ASEKiCN7afzUkCTdzrI71r3rOkJtlT1NWn2RAv6xT6AuhCPZzH2I3ImuFI +mkUKYhKzRN6AdmCJAT4EEwECACgFAlPxECkCGwMFCQPCZwAGCwkIBwMCBhUIAgkK CwQWAgMBAh4BAheAAAoJEKk+HEsmBizjvfYIALS1vlaqN/f7/YzpnOwlH2Wo4jpI jBrG7SqcdVQk3NGsXTXzzq5p7uTTzpEJW8ReZLGeYaTzqh1vH97uAPR6wL3GjHMZ F2jkC0wSHXxvh9Gyrdx3LA8NSO+BAG9ZfD6OGklsl7tFFEplLpfR1EsAKfbi0bAY @@ -1782,13 +1783,13 @@ F2jkC0wSHXxvh9Gyrdx3LA8NSO+BAG9ZfD6OGklsl7tFFEplLpfR1EsAKfbi0bAY 019qP30afGkvw+ZbIq8qbxJItObMuhn5xdI0YaMm2yudCfm2aGYSCnkrgNfuWzH6 WZ8n1fv45TGBUd2R6zPr13eH73AG1WXpapoD45yf/TFavRfnknU6xb7U3ZK0MkFu ZHJlYXMgQmVla2VyIChraXdpd2luZ3MpIDxhbmRyZWFzLmJlZWtlckBnbXguZGU+ -iQE+BBMBAgAoBQJT8LY0AhsDBQkDwmcABgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIX -gAAKCRCpPhxLJgYs4wvFB/9hEV8LzHUpD0X/vM9pfW1ZbTl2GNiZfuMh6/KlqB3C -4gL3SLLRlk4mEPM3qlZWCqZiWVp5zz1C/j/+BLJW3c+j3rCUEAsobsR6HkxBr7N0 -LUnurbMXyiOvdg4lAS42Vi1JrydFdih1HCI3NiGMHAV/8NEdtmLt7Ue8Opx01R6r -wXBomX5BHJXnzbZRbCbdor/UnO8ff5K4jwd6yhY0BV+bI2uD+vGq9nMld0JGj7W7 -qB+HzOAxpINtHksQhtTV/PBWjHTCNhOdGh1zyoyvJSshm1NkvwBVZYMs/0ujApcq -xAXytGXonLiMmZMECOjxAigph8T4PCEKdIqdsVxkC2ybiQIcBBABCgAGBQJV5hIJ +iQE+BBMBAgAoAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAUCV7mKXAUJB4s7 +HwAKCRCpPhxLJgYs4zheCACgc3m2FH5kmXtYO44BdYYwdV2dyLMCxvVl7GUWqJF8 +wKmDWlUxBwrpzDBQXpmHyb+rqX/kvfEkH2wb9TZwginLecbZbMKubNUWUqGJBHQo +CaV8o6L/iEUJa5NXzY2OJCp32CHsmpefYkU+WgAnmTVe8Se7JEmJeu+2OfStV5m6 +zVK5xzlciYSc29LpA3dsv5hxE6YZ8kJBJaFyv2AvVzaouSR7nPNrdw3/jXaOz+Hb +VpP/CEf5IdvF/o37sv8o7WWcH1AjvMdGQNp6Zr5Te2E35V8PmpqLH4Z8W0/PXij2 +67i565JZc1Kmpqxm59jg1vs2X7rHNn0k+r9BFiCQC1LKiQIcBBABCgAGBQJV5hIJ AAoJEOGWdUUnufY1qh8P/03uvjuU1V9UZY9t/4J/K0wbU8Re9c/HfgmJrCn+wvDI OtxpOg3m07ZoIrosYEA2CIm+kLCYuNbzGSz6ZPZlpoq5FvxzO9OAYMO76r3ktxUw Snbxd9TCkjCCQ8RMxT/JGDBU77nAJPyhCUZF2/SyrXnexloNP9TR/IDQZNOXzlxR @@ -1805,14 +1806,14 @@ ulDgtZwWSin3Kd40VZDyKi6mqOp5ldz6AsZ2CSx1GfI9iVhfuFqOaiBLqpNpdvf9 nGL9OVoy1SdwTXgnboiIFtbTG3sVwD4x4qTRbmT22Ln/mIAICR2wxFBkzpbIQ7Mf R/zEgRh2VlRUUrWUsnYdOh0xfxuYgsnPCjpTY8hvEno3H6kzXKmj2GQJtawMVs5b Ro/GCM9lBBR/PAhB65ACzLmUUSsxjlmjZw0tCcOufg1RyAF/l6YVw1UOJaqXBfSP -eZkLQBj9p8VNpasX/acIfpEaZLE8QhoO11ajABEBAAGJASUEGAECAA8FAlPwtjQC -GwwFCQPCZwAACgkQqT4cSyYGLOPzLggAjHrdpMjZrHM5WqnxkJ1Eib1g14aScMGd -OIw9NOSQ2AGvJjbSy4xyMEUg3S14I73JGYtJu8g9YvCHbuWiyzySBIuGNinMI/Zj -ET/w1noqoNaSlIY4UfFh30g+OikEzP9WXmo0Scg0XH/fJhX1wCpM/TVlphX0yNGm -mkNBBqerRXC7Md4XOy001vvXZGM7vy+xOotyBOy/D4WNERSz3GVS3juCQGMWvMdq -KQa+qoiVaXWfFHwg8u4bSHunrzNja17GyaZHdCEmM9vFzlaqBkoLWCMwIcaKnX9s -tQJpFZwpzgut7DanaPcCDk7LMBbntaJwRC72M0qcj16SUAdAuGt1yQ== -=IonN +eZkLQBj9p8VNpasX/acIfpEaZLE8QhoO11ajABEBAAGJASUEGAECAA8CGwwFAle5 +inIFCQeLOz4ACgkQqT4cSyYGLOMvsAf+J2EyV9+GNqT8UmEU6OFnw/sdR1oE+vZ9 +fe4mifAfjQ+SKYf+MS0lU3lTuwcQKwFklePoYsvJEO7jNEgjTQ+zKiDSlV5yufSn +Idy8+sCYygPn5fSjGdRaMpCCfs5xrljLUPK5U8+vjeteRJW0o2/wmsYdHRz6A74B +kRq8kYu1M8VgZ6JD1YI/mp0mHTTB+H69/DNo6cA+7W/CibeTrffbJ35+OXGsJxqJ +b/QH/4lqsceNJtJThkHPQeM18R7/4t7Vhb5htOk2eB7coKzdYRKpHMzkm7elm8bI +uwsky9+6hIUMKD5hhc8G7g9lWOLSXCeNRUdqWTOfZaU5KOK70kKUeQ== +=PCbZ -----END PGP PUBLIC KEY BLOCK----- pub 4096R/B4812553 2014-02-26 [expires: 2019-02-25] From 497c5b9e16e1465926f91fa59a3406698d7fa4bd Mon Sep 17 00:00:00 2001 From: David North Date: Sun, 21 Aug 2016 21:18:07 +0000 Subject: [PATCH 058/157] release prepare for 3.15 - updating build.xml and status.xml git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1757083 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.xml b/build.xml index f40ff4c77..887cffe15 100644 --- a/build.xml +++ b/build.xml @@ -40,7 +40,7 @@ under the License. The Apache POI project Ant build. - + @@ -2390,13 +2390,13 @@ under the License. - + From e6384056ec323cbce15bfe835c28f629d425086a Mon Sep 17 00:00:00 2001 From: David North Date: Sun, 21 Aug 2016 21:33:03 +0000 Subject: [PATCH 059/157] Revert accidental edits git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1757084 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.xml b/build.xml index 887cffe15..f40ff4c77 100644 --- a/build.xml +++ b/build.xml @@ -40,7 +40,7 @@ under the License. The Apache POI project Ant build. - + @@ -2390,13 +2390,13 @@ under the License. - + From 0014635baca8af659efd5d12d481fe3638a80428 Mon Sep 17 00:00:00 2001 From: David North Date: Sun, 21 Aug 2016 21:33:14 +0000 Subject: [PATCH 060/157] release prepare for 3.15 - updating build.xml and status.xml git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1757085 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index f40ff4c77..143b6f234 100644 --- a/build.xml +++ b/build.xml @@ -40,7 +40,7 @@ under the License. The Apache POI project Ant build. - + From c059198e5a80242384c16cdd584fa023a54d3ede Mon Sep 17 00:00:00 2001 From: David North Date: Sun, 21 Aug 2016 21:34:52 +0000 Subject: [PATCH 061/157] "release prepare for 3.15 - pin documentation git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1757086 13f79535-47bb-0310-9956-ffa450edef68 From f43de7b5164dade6c961ebdc65987e232692c13e Mon Sep 17 00:00:00 2001 From: David North Date: Sun, 21 Aug 2016 21:37:21 +0000 Subject: [PATCH 062/157] Undo another iffy attempt git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1757088 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index 143b6f234..f40ff4c77 100644 --- a/build.xml +++ b/build.xml @@ -40,7 +40,7 @@ under the License. The Apache POI project Ant build. - + From b3504854b8de3307a1d9a509f585e2a3fe1a5c7c Mon Sep 17 00:00:00 2001 From: David North Date: Sun, 21 Aug 2016 21:43:38 +0000 Subject: [PATCH 063/157] Svn commit via calling the binary. Doing it via ant fails every single time for me on two different environments with: svn: E200007: Commit failed (details follow): svn: E200007: CHECKOUT can only be performed on a version resource [at this time]. more investigation required. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1757089 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/build.xml b/build.xml index f40ff4c77..fb5646af3 100644 --- a/build.xml +++ b/build.xml @@ -2390,17 +2390,19 @@ under the License. + - + + - + @@ -2430,12 +2432,13 @@ under the License. - + + From 6fc298d0ae84621b625a3a75a17d40436ffc9649 Mon Sep 17 00:00:00 2001 From: David North Date: Sun, 21 Aug 2016 21:43:48 +0000 Subject: [PATCH 064/157] release prepare for 3.15 - updating build.xml and status.xml git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1757090 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index fb5646af3..545a8d153 100644 --- a/build.xml +++ b/build.xml @@ -40,7 +40,7 @@ under the License. The Apache POI project Ant build. - + From e3fadb214d70262dd2a83c7c9aa8d38df51c32f0 Mon Sep 17 00:00:00 2001 From: David North Date: Sun, 21 Aug 2016 21:44:42 +0000 Subject: [PATCH 065/157] prepare for 3.16-beta1 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1757092 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 +- sonar/examples/pom.xml | 2 +- sonar/excelant/pom.xml | 2 +- sonar/main/pom.xml | 2 +- sonar/ooxml-schema-encryption/pom.xml | 2 +- sonar/ooxml-schema-security/pom.xml | 2 +- sonar/ooxml-schema/pom.xml | 2 +- sonar/ooxml/pom.xml | 2 +- sonar/pom.xml | 2 +- sonar/scratchpad/pom.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/build.xml b/build.xml index 545a8d153..633607618 100644 --- a/build.xml +++ b/build.xml @@ -40,7 +40,7 @@ under the License. The Apache POI project Ant build. - + diff --git a/sonar/examples/pom.xml b/sonar/examples/pom.xml index cac1dc446..ea53c0597 100644 --- a/sonar/examples/pom.xml +++ b/sonar/examples/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 3.15-beta4-SNAPSHOT + 3.16-beta1-SNAPSHOT poi-examples jar diff --git a/sonar/excelant/pom.xml b/sonar/excelant/pom.xml index 2cbeec728..a7b9408dc 100644 --- a/sonar/excelant/pom.xml +++ b/sonar/excelant/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 3.15-beta4-SNAPSHOT + 3.16-beta1-SNAPSHOT poi-excelant jar diff --git a/sonar/main/pom.xml b/sonar/main/pom.xml index 26a8f2ba4..36422a83c 100644 --- a/sonar/main/pom.xml +++ b/sonar/main/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 3.15-beta4-SNAPSHOT + 3.16-beta1-SNAPSHOT poi-main jar diff --git a/sonar/ooxml-schema-encryption/pom.xml b/sonar/ooxml-schema-encryption/pom.xml index d704a6525..cbb2eff7d 100644 --- a/sonar/ooxml-schema-encryption/pom.xml +++ b/sonar/ooxml-schema-encryption/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 3.15-beta4-SNAPSHOT + 3.16-beta1-SNAPSHOT .. poi-ooxml-schema-encryption diff --git a/sonar/ooxml-schema-security/pom.xml b/sonar/ooxml-schema-security/pom.xml index 7aae600f4..a822c7343 100644 --- a/sonar/ooxml-schema-security/pom.xml +++ b/sonar/ooxml-schema-security/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 3.15-beta4-SNAPSHOT + 3.16-beta1-SNAPSHOT .. poi-ooxml-schema-security diff --git a/sonar/ooxml-schema/pom.xml b/sonar/ooxml-schema/pom.xml index e1d6526da..5e2b9fef5 100644 --- a/sonar/ooxml-schema/pom.xml +++ b/sonar/ooxml-schema/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 3.15-beta4-SNAPSHOT + 3.16-beta1-SNAPSHOT .. poi-ooxml-schema diff --git a/sonar/ooxml/pom.xml b/sonar/ooxml/pom.xml index 305695ff1..27636cdfa 100644 --- a/sonar/ooxml/pom.xml +++ b/sonar/ooxml/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 3.15-beta4-SNAPSHOT + 3.16-beta1-SNAPSHOT poi-ooxml jar diff --git a/sonar/pom.xml b/sonar/pom.xml index 5acb3a5da..8e2a9fc42 100644 --- a/sonar/pom.xml +++ b/sonar/pom.xml @@ -3,7 +3,7 @@ org.apache.poi poi-parent pom - 3.15-beta4-SNAPSHOT + 3.16-beta1-SNAPSHOT Apache POI - the Java API for Microsoft Documents Maven build of Apache POI for Sonar checks http://poi.apache.org/ diff --git a/sonar/scratchpad/pom.xml b/sonar/scratchpad/pom.xml index 91ede69a1..6760762d6 100644 --- a/sonar/scratchpad/pom.xml +++ b/sonar/scratchpad/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 3.15-beta4-SNAPSHOT + 3.16-beta1-SNAPSHOT poi-scratchpad jar From 3f4612ffcb754abefa71067ef015704b1f281a9d Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Mon, 22 Aug 2016 17:57:45 +0000 Subject: [PATCH 066/157] bug 59791: improve Cell.CELL_TYPE_* backwards compatibility git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1757235 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/ss/usermodel/Cell.java | 12 ++++---- .../TestHSSFConditionalFormatting.java | 18 +++++------ .../apache/poi/ss/usermodel/BaseTestCell.java | 30 +++++++++++++++++++ 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/java/org/apache/poi/ss/usermodel/Cell.java b/src/java/org/apache/poi/ss/usermodel/Cell.java index 95840a6c0..e333f8528 100644 --- a/src/java/org/apache/poi/ss/usermodel/Cell.java +++ b/src/java/org/apache/poi/ss/usermodel/Cell.java @@ -46,7 +46,7 @@ public interface Cell { * @see #getCellType() * @deprecated POI 3.15 beta 3. Use {@link CellType#NUMERIC} instead. */ - CellType CELL_TYPE_NUMERIC = CellType.NUMERIC; + int CELL_TYPE_NUMERIC = 0; //CellType.NUMERIC.getCode(); /** * String Cell type (1) @@ -54,7 +54,7 @@ public interface Cell { * @see #getCellType() * @deprecated POI 3.15 beta 3. Use {@link CellType#STRING} instead. */ - CellType CELL_TYPE_STRING = CellType.STRING; + int CELL_TYPE_STRING = 1; //CellType.STRING.getCode(); /** * Formula Cell type (2) @@ -62,7 +62,7 @@ public interface Cell { * @see #getCellType() * @deprecated POI 3.15 beta 3. Use {@link CellType#FORMULA} instead. */ - CellType CELL_TYPE_FORMULA = CellType.FORMULA; + int CELL_TYPE_FORMULA = 2; //CellType.FORMULA.getCode(); /** * Blank Cell type (3) @@ -70,7 +70,7 @@ public interface Cell { * @see #getCellType() * @deprecated POI 3.15 beta 3. Use {@link CellType#BLANK} instead. */ - CellType CELL_TYPE_BLANK = CellType.BLANK; + int CELL_TYPE_BLANK = 3; //CellType.BLANK.getCode(); /** * Boolean Cell type (4) @@ -78,7 +78,7 @@ public interface Cell { * @see #getCellType() * @deprecated POI 3.15 beta 3. Use {@link CellType#BOOLEAN} instead. */ - CellType CELL_TYPE_BOOLEAN = CellType.BOOLEAN; + int CELL_TYPE_BOOLEAN = 4; //CellType.BOOLEAN.getCode(); /** * Error Cell type (5) @@ -86,7 +86,7 @@ public interface Cell { * @see #getCellType() * @deprecated POI 3.15 beta 3. Use {@link CellType#ERROR} instead. */ - CellType CELL_TYPE_ERROR = CellType.ERROR; + int CELL_TYPE_ERROR = 5; //CellType.ERROR.getCode(); /** * Returns column index of this cell diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFConditionalFormatting.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFConditionalFormatting.java index ede6a6df1..e594fdec9 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFConditionalFormatting.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFConditionalFormatting.java @@ -136,45 +136,45 @@ public final class TestHSSFConditionalFormatting extends BaseTestConditionalForm Row row = sheet.createRow(0); Cell cell0 = row.createCell(0); - cell0.setCellType(org.apache.poi.ss.usermodel.Cell.CELL_TYPE_NUMERIC); + cell0.setCellType(CellType.NUMERIC); cell0.setCellValue(100); Cell cell1 = row.createCell(1); - cell1.setCellType(org.apache.poi.ss.usermodel.Cell.CELL_TYPE_NUMERIC); + cell1.setCellType(CellType.NUMERIC); cell1.setCellValue(120); Cell cell2 = row.createCell(2); - cell2.setCellType(org.apache.poi.ss.usermodel.Cell.CELL_TYPE_NUMERIC); + cell2.setCellType(CellType.NUMERIC); cell2.setCellValue(130); // row 1 row = sheet.createRow(1); cell0 = row.createCell(0); - cell0.setCellType(org.apache.poi.ss.usermodel.Cell.CELL_TYPE_NUMERIC); + cell0.setCellType(CellType.NUMERIC); cell0.setCellValue(200); cell1 = row.createCell(1); - cell1.setCellType(org.apache.poi.ss.usermodel.Cell.CELL_TYPE_NUMERIC); + cell1.setCellType(CellType.NUMERIC); cell1.setCellValue(220); cell2 = row.createCell(2); - cell2.setCellType(org.apache.poi.ss.usermodel.Cell.CELL_TYPE_NUMERIC); + cell2.setCellType(CellType.NUMERIC); cell2.setCellValue(230); // row 2 row = sheet.createRow(2); cell0 = row.createCell(0); - cell0.setCellType(org.apache.poi.ss.usermodel.Cell.CELL_TYPE_NUMERIC); + cell0.setCellType(CellType.NUMERIC); cell0.setCellValue(300); cell1 = row.createCell(1); - cell1.setCellType(org.apache.poi.ss.usermodel.Cell.CELL_TYPE_NUMERIC); + cell1.setCellType(CellType.NUMERIC); cell1.setCellValue(320); cell2 = row.createCell(2); - cell2.setCellType(org.apache.poi.ss.usermodel.Cell.CELL_TYPE_NUMERIC); + cell2.setCellType(CellType.NUMERIC); cell2.setCellValue(330); // Create conditional formatting, CELL1 should be yellow if CELL0 is not blank. diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java index b2ae06cb9..db46687c1 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java @@ -1015,4 +1015,34 @@ public abstract class BaseTestCell { wb.close(); } + + @Test + public void primitiveToEnumReplacementDoesNotBreakBackwardsCompatibility() { + // bug 59836 + // until we have changes POI from working on primitives (int) to enums, + // we should make sure we minimize backwards compatibility breakages. + // This method tests the old way of working with cell types, alignment, etc. + Workbook wb = _testDataProvider.createWorkbook(); + Sheet sheet = wb.createSheet(); + Row row = sheet.createRow(0); + Cell cell = row.createCell(0); + + // Cell.CELL_TYPE_* -> CellType.* + cell.setCellValue(5.0); + assertEquals(Cell.CELL_TYPE_NUMERIC, cell.getCellType()); + assertEquals(CellType.NUMERIC, cell.getCellTypeEnum()); // make sure old way and new way are compatible + + // make sure switch(int|Enum) still works. Cases must be statically resolvable in Java 6 ("constant expression required") + switch(cell.getCellType()) { + case Cell.CELL_TYPE_NUMERIC: + // expected + break; + case Cell.CELL_TYPE_STRING: + case Cell.CELL_TYPE_ERROR: + case Cell.CELL_TYPE_FORMULA: + case Cell.CELL_TYPE_BLANK: + default: + fail("unexpected cell type: " + cell.getCellType()); + } + } } From 75b943d69c7f41c2c1cc6f566a3709754b97022b Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Mon, 22 Aug 2016 18:14:46 +0000 Subject: [PATCH 067/157] bug 59791: make sure hard-coded int literals work for cell type git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1757237 13f79535-47bb-0310-9956-ffa450edef68 --- src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java index db46687c1..406816958 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java @@ -1030,6 +1030,7 @@ public abstract class BaseTestCell { // Cell.CELL_TYPE_* -> CellType.* cell.setCellValue(5.0); assertEquals(Cell.CELL_TYPE_NUMERIC, cell.getCellType()); + assertEquals(0, cell.getCellType()); //make sure that hard-coded int literals still work, even though users should be using the named constants assertEquals(CellType.NUMERIC, cell.getCellTypeEnum()); // make sure old way and new way are compatible // make sure switch(int|Enum) still works. Cases must be statically resolvable in Java 6 ("constant expression required") @@ -1038,6 +1039,7 @@ public abstract class BaseTestCell { // expected break; case Cell.CELL_TYPE_STRING: + case Cell.CELL_TYPE_BOOLEAN: case Cell.CELL_TYPE_ERROR: case Cell.CELL_TYPE_FORMULA: case Cell.CELL_TYPE_BLANK: From 9665b9859a8b7977a4db18495c12711587adca3d Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Mon, 22 Aug 2016 18:25:45 +0000 Subject: [PATCH 068/157] bug 59791: add @Removal tags to Cell.CELL_TYPE_* constants, deprecated by CellType enum git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1757239 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/ss/usermodel/Cell.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/java/org/apache/poi/ss/usermodel/Cell.java b/src/java/org/apache/poi/ss/usermodel/Cell.java index e333f8528..48b74789a 100644 --- a/src/java/org/apache/poi/ss/usermodel/Cell.java +++ b/src/java/org/apache/poi/ss/usermodel/Cell.java @@ -24,6 +24,7 @@ import org.apache.poi.ss.formula.FormulaParseException; import org.apache.poi.ss.util.CellAddress; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.util.Internal; +import org.apache.poi.util.Removal; /** * High level representation of a cell in a row of a spreadsheet. @@ -46,6 +47,7 @@ public interface Cell { * @see #getCellType() * @deprecated POI 3.15 beta 3. Use {@link CellType#NUMERIC} instead. */ + @Removal(version="4.0") int CELL_TYPE_NUMERIC = 0; //CellType.NUMERIC.getCode(); /** @@ -54,6 +56,7 @@ public interface Cell { * @see #getCellType() * @deprecated POI 3.15 beta 3. Use {@link CellType#STRING} instead. */ + @Removal(version="4.0") int CELL_TYPE_STRING = 1; //CellType.STRING.getCode(); /** @@ -62,6 +65,7 @@ public interface Cell { * @see #getCellType() * @deprecated POI 3.15 beta 3. Use {@link CellType#FORMULA} instead. */ + @Removal(version="4.0") int CELL_TYPE_FORMULA = 2; //CellType.FORMULA.getCode(); /** @@ -70,6 +74,7 @@ public interface Cell { * @see #getCellType() * @deprecated POI 3.15 beta 3. Use {@link CellType#BLANK} instead. */ + @Removal(version="4.0") int CELL_TYPE_BLANK = 3; //CellType.BLANK.getCode(); /** @@ -78,6 +83,7 @@ public interface Cell { * @see #getCellType() * @deprecated POI 3.15 beta 3. Use {@link CellType#BOOLEAN} instead. */ + @Removal(version="4.0") int CELL_TYPE_BOOLEAN = 4; //CellType.BOOLEAN.getCode(); /** @@ -86,6 +92,7 @@ public interface Cell { * @see #getCellType() * @deprecated POI 3.15 beta 3. Use {@link CellType#ERROR} instead. */ + @Removal(version="4.0") int CELL_TYPE_ERROR = 5; //CellType.ERROR.getCode(); /** @@ -136,6 +143,7 @@ public interface Cell { * @see CellType#ERROR * @deprecated POI 3.15 beta 3. Use {@link #setCellType(CellType)} instead. */ + @Removal(version="4.0") void setCellType(int cellType); /** * Set the cells type (numeric, formula or string). @@ -155,7 +163,7 @@ public interface Cell { /** * Return the cell type. * - * Will return {@link CellType} in a future version of POI. + * Will return {@link CellType} in version 4.0 of POI. * For forwards compatibility, do not hard-code cell type literals in your code. * * @return the cell type @@ -168,9 +176,10 @@ public interface Cell { * @return the cell type * @since POI 3.15 beta 3 * @deprecated POI 3.15 beta 3 - * Will be deleted when we make the CellType enum transition. See bug 59791. + * Will be renamed to getCellType() when we make the CellType enum transition in POI 4.0. See bug 59791. */ @Internal(since="POI 3.15 beta 3") + @Removal(version="4.2") CellType getCellTypeEnum(); /** @@ -192,7 +201,7 @@ public interface Cell { * on the cached value of the formula * @since POI 3.15 beta 3 * @deprecated POI 3.15 beta 3 - * Will be deleted when we make the CellType enum transition. See bug 59791. + * Will be renamed to getCachedFormulaResultType() when we make the CellType enum transition in POI 4.0. See bug 59791. */ @Internal(since="POI 3.15 beta 3") CellType getCachedFormulaResultTypeEnum(); From bc1f9dfb27c32aad87add2566bf6cd5d37015560 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 24 Aug 2016 03:47:21 +0000 Subject: [PATCH 069/157] Remove unnecessary short cast. This closes #37 on github git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1757457 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/xssf/usermodel/examples/FillsAndColors.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/examples/src/org/apache/poi/xssf/usermodel/examples/FillsAndColors.java b/src/examples/src/org/apache/poi/xssf/usermodel/examples/FillsAndColors.java index 019e14d1c..f5edd4a8e 100644 --- a/src/examples/src/org/apache/poi/xssf/usermodel/examples/FillsAndColors.java +++ b/src/examples/src/org/apache/poi/xssf/usermodel/examples/FillsAndColors.java @@ -32,13 +32,13 @@ public class FillsAndColors { Sheet sheet = wb.createSheet("new sheet"); // Create a row and put some cells in it. Rows are 0 based. - Row row = sheet.createRow((short) 1); + Row row = sheet.createRow(1); // Aqua background CellStyle style = wb.createCellStyle(); style.setFillBackgroundColor(IndexedColors.AQUA.getIndex()); style.setFillPattern(CellStyle.BIG_SPOTS); - Cell cell = row.createCell((short) 1); + Cell cell = row.createCell(1); cell.setCellValue(new XSSFRichTextString("X")); cell.setCellStyle(style); @@ -46,7 +46,7 @@ public class FillsAndColors { style = wb.createCellStyle(); style.setFillForegroundColor(IndexedColors.ORANGE.getIndex()); style.setFillPattern(CellStyle.SOLID_FOREGROUND); - cell = row.createCell((short) 2); + cell = row.createCell(2); cell.setCellValue(new XSSFRichTextString("X")); cell.setCellStyle(style); From 7f7eba3d0419ee7b6c420eab654172c9c10d9907 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 24 Aug 2016 03:54:55 +0000 Subject: [PATCH 070/157] Update CreatePivotTable with non-deprecated constructor. This closes #36 on github. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1757458 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/xssf/usermodel/examples/CreatePivotTable.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreatePivotTable.java b/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreatePivotTable.java index 518ec37f4..6549f482d 100644 --- a/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreatePivotTable.java +++ b/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreatePivotTable.java @@ -21,6 +21,7 @@ import java.io.FileOutputStream; import java.io.IOException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.DataConsolidateFunction; import org.apache.poi.ss.usermodel.Row; @@ -39,7 +40,8 @@ public class CreatePivotTable { //Create some data to build the pivot table on setCellData(sheet); - XSSFPivotTable pivotTable = sheet.createPivotTable(new AreaReference("A1:D4"), new CellReference("H5")); + AreaReference area = new AreaReference("A1:D4", SpreadsheetVersion.EXCEL2007); + XSSFPivotTable pivotTable = sheet.createPivotTable(area, new CellReference("H5")); //Configure the pivot table //Use first column as row label pivotTable.addRowLabel(0); @@ -98,4 +100,4 @@ public class CreatePivotTable { Cell cell44 = row4.createCell(3); cell44.setCellValue("No"); } -} \ No newline at end of file +} From cd7b5359f8a7649d398113effb2862d56d2d830f Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 24 Aug 2016 04:03:26 +0000 Subject: [PATCH 071/157] make CreatePivotTable self-explaining with better variable names git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1757459 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/xssf/usermodel/examples/CreatePivotTable.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreatePivotTable.java b/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreatePivotTable.java index 6549f482d..a855feeda 100644 --- a/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreatePivotTable.java +++ b/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreatePivotTable.java @@ -40,8 +40,11 @@ public class CreatePivotTable { //Create some data to build the pivot table on setCellData(sheet); - AreaReference area = new AreaReference("A1:D4", SpreadsheetVersion.EXCEL2007); - XSSFPivotTable pivotTable = sheet.createPivotTable(area, new CellReference("H5")); + AreaReference source = new AreaReference("A1:D4", SpreadsheetVersion.EXCEL2007); + CellReference position = new CellReference("H5"); + // Create a pivot table on this sheet, with H5 as the top-left cell.. + // The pivot table's data source is on the same sheet in A1:D4 + XSSFPivotTable pivotTable = sheet.createPivotTable(source, position); //Configure the pivot table //Use first column as row label pivotTable.addRowLabel(0); From 5747e871a1180d278f6833d44612092e512350d7 Mon Sep 17 00:00:00 2001 From: Tim Allison Date: Fri, 9 Sep 2016 18:41:37 +0000 Subject: [PATCH 072/157] poi-60044 small typo in last update to BuiltinFormats git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760102 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/ss/usermodel/BuiltinFormats.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java/org/apache/poi/ss/usermodel/BuiltinFormats.java b/src/java/org/apache/poi/ss/usermodel/BuiltinFormats.java index 708f2f66a..8d1188178 100644 --- a/src/java/org/apache/poi/ss/usermodel/BuiltinFormats.java +++ b/src/java/org/apache/poi/ss/usermodel/BuiltinFormats.java @@ -75,7 +75,7 @@ public final class BuiltinFormats { "#,##0.00", "\"$\"#,##0_);(\"$\"#,##0)", "\"$\"#,##0_);[Red](\"$\"#,##0)", - "\"$\"#,##,00_);(\"$\"#,##0.00)", + "\"$\"#,##0.00_);(\"$\"#,##0.00)", "\"$\"#,##0.00_);[Red](\"$\"#,##0.00)", "0%", "0.00%", From e1b5ed4c14b35556ff2dcd26eebec0cc538c0aeb Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Sat, 10 Sep 2016 05:22:58 +0000 Subject: [PATCH 073/157] Add comments describing purpose of each unit test git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760130 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java index 028735323..3e2cd5403 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java @@ -51,6 +51,7 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows { // TODO - support shifting of page breaks } + /** Error occurred at FormulaShifter#rowMoveAreaPtg while shift rows upward. */ @Test public void testBug54524() throws IOException { XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("54524.xlsx"); @@ -66,6 +67,7 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows { workbook.close(); } + /** negative row shift causes corrupted data or throws exception */ @Test public void testBug53798() throws IOException { // NOTE that for HSSF (.xls) negative shifts combined with positive ones do work as expected @@ -124,6 +126,7 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows { } } + /** negative row shift causes corrupted data or throws exception */ @Test public void testBug53798a() throws IOException { Workbook wb = XSSFTestDataSamples.openSampleWorkbook("53798.xlsx"); @@ -152,6 +155,7 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows { read.close(); } + /** Shifting rows with comment result - Unreadable content error and comment deletion */ @Test public void testBug56017() throws IOException { Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56017.xlsx"); @@ -193,6 +197,7 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows { wbBack.close(); } + /** Moving the active sheet and deleting the others results in a corrupted file */ @Test public void test57171() throws IOException { Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57171_57163_57165.xlsx"); @@ -210,6 +215,7 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows { wbRead.close(); } + /** Cannot delete an arbitrary sheet in an XLS workbook (only the last one) */ @Test public void test57163() throws IOException { Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57171_57163_57165.xlsx"); @@ -314,6 +320,7 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows { wb.close(); } + /** Failed to clone a sheet from an Excel 2010 */ @Test public void test57165() throws IOException { Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57171_57163_57165.xlsx"); @@ -341,6 +348,7 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows { } } + /** Shifting rows with cell comments only shifts comments from first such cell. Other cell comments not shifted */ @Test public void testBug57828_OnlyOneCommentShiftedInRow() throws IOException { XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57828.xlsx"); From 7dabe1b1012d349ea7ae5c3e189f1ae1427bdb6d Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Sat, 10 Sep 2016 18:47:00 +0000 Subject: [PATCH 074/157] move duplicated NullOutputStream classes to test suite utilities git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760203 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/xssf/streaming/TestSXSSFWorkbook.java | 1 + .../org/apache/poi/ddf/TestEscherDump.java | 22 +--------- .../poi/hssf/dev/BaseXLSIteratingTest.java | 20 +-------- .../poi/ss/usermodel/BaseTestWorkbook.java | 10 +---- .../org/apache/poi/util/NullOutputStream.java | 41 +++++++++++++++++++ 5 files changed, 46 insertions(+), 48 deletions(-) create mode 100644 src/testcases/org/apache/poi/util/NullOutputStream.java diff --git a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbook.java b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbook.java index 67ebe1ef0..bdd858b06 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbook.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbook.java @@ -43,6 +43,7 @@ import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; import org.apache.poi.ss.util.CellReference; +import org.apache.poi.util.NullOutputStream; import org.apache.poi.xssf.SXSSFITestDataProvider; import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.model.SharedStringsTable; diff --git a/src/testcases/org/apache/poi/ddf/TestEscherDump.java b/src/testcases/org/apache/poi/ddf/TestEscherDump.java index 9b72d9acd..95b074520 100644 --- a/src/testcases/org/apache/poi/ddf/TestEscherDump.java +++ b/src/testcases/org/apache/poi/ddf/TestEscherDump.java @@ -20,9 +20,7 @@ package org.apache.poi.ddf; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; -import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.io.PrintStream; import java.io.UnsupportedEncodingException; @@ -30,6 +28,7 @@ import org.apache.poi.POIDataSamples; import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.util.IOUtils; import org.apache.poi.util.LocaleUtil; +import org.apache.poi.util.NullOutputStream; import org.junit.BeforeClass; import org.junit.Test; @@ -83,23 +82,6 @@ public class TestEscherDump { @SuppressWarnings("resource") private NullPrinterStream() throws UnsupportedEncodingException { super(new NullOutputStream(),true,LocaleUtil.CHARSET_1252.name()); - } - /** - * Implementation of an OutputStream which does nothing, used - * to redirect stdout to avoid spamming the console with output - */ - private static class NullOutputStream extends OutputStream { - @Override - public void write(byte[] b, int off, int len) { - } - - @Override - public void write(int b) { - } - - @Override - public void write(byte[] b) throws IOException { - } - } + } } } diff --git a/src/testcases/org/apache/poi/hssf/dev/BaseXLSIteratingTest.java b/src/testcases/org/apache/poi/hssf/dev/BaseXLSIteratingTest.java index 5f471d5b6..e69c700de 100644 --- a/src/testcases/org/apache/poi/hssf/dev/BaseXLSIteratingTest.java +++ b/src/testcases/org/apache/poi/hssf/dev/BaseXLSIteratingTest.java @@ -21,7 +21,6 @@ import static org.junit.Assert.assertNotNull; import java.io.File; import java.io.FileInputStream; import java.io.FilenameFilter; -import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; @@ -32,6 +31,7 @@ import java.util.Map; import org.apache.poi.POIDataSamples; import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.util.NullOutputStream; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -119,22 +119,4 @@ public abstract class BaseXLSIteratingTest { } abstract void runOneFile(File pFile) throws Exception; - - /** - * Implementation of an OutputStream which does nothing, used - * to redirect stdout to avoid spamming the console with output - */ - private static class NullOutputStream extends OutputStream { - @Override - public void write(byte[] b, int off, int len) { - } - - @Override - public void write(int b) { - } - - @Override - public void write(byte[] b) throws IOException { - } - } } diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestWorkbook.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestWorkbook.java index 6290119f5..52f542281 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestWorkbook.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestWorkbook.java @@ -34,6 +34,7 @@ import java.util.Iterator; import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.ss.ITestDataProvider; import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.util.NullOutputStream; import org.junit.Test; public abstract class BaseTestWorkbook { @@ -781,15 +782,6 @@ public abstract class BaseTestWorkbook { } } - protected static class NullOutputStream extends OutputStream { - public NullOutputStream() { - } - - @Override - public void write(int b) throws IOException { - } - } - @Test public void test58499() throws IOException { Workbook workbook = _testDataProvider.createWorkbook(); diff --git a/src/testcases/org/apache/poi/util/NullOutputStream.java b/src/testcases/org/apache/poi/util/NullOutputStream.java new file mode 100644 index 000000000..ac76123a3 --- /dev/null +++ b/src/testcases/org/apache/poi/util/NullOutputStream.java @@ -0,0 +1,41 @@ +/* ==================================================================== + 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.io.OutputStream; + +/** + * Implementation of an OutputStream which does nothing, used + * to redirect stdout to avoid spamming the console with output + */ +public final class NullOutputStream extends OutputStream { + public NullOutputStream() { + } + + @Override + public void write(byte[] b, int off, int len) { + } + + @Override + public void write(int b) { + } + + @Override + public void write(byte[] b) { + } +} From d9cfcbdd189ef2d3a2796b648ddb5b84619912b9 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Sat, 10 Sep 2016 19:33:32 +0000 Subject: [PATCH 075/157] bug 60102: throw IOException when writing a closed document git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760206 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/poi/POIXMLDocument.java | 10 +++-- .../org/apache/poi/TestPOIXMLDocument.java | 37 ++++++++++++++++++- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocument.java b/src/ooxml/java/org/apache/poi/POIXMLDocument.java index 4ec3d442e..93afa6163 100644 --- a/src/ooxml/java/org/apache/poi/POIXMLDocument.java +++ b/src/ooxml/java/org/apache/poi/POIXMLDocument.java @@ -40,6 +40,7 @@ import org.apache.xmlbeans.impl.common.SystemCache; /** * This holds the common functionality for all POI OOXML Document classes. */ +// TODO: implements AutoCloseable in Java 7+ when POI drops support for Java 6. public abstract class POIXMLDocument extends POIXMLDocumentPart implements Closeable { public static final String DOCUMENT_CREATOR = "Apache POI"; @@ -230,6 +231,11 @@ public abstract class POIXMLDocument extends POIXMLDocumentPart implements Close */ @SuppressWarnings("resource") public final void write(OutputStream stream) throws IOException { + OPCPackage p = getPackage(); + if(p == null) { + throw new IOException("Cannot write data, document seems to have been closed already"); + } + //force all children to commit their changes into the underlying OOXML Package // TODO Shouldn't they be committing to the new one instead? Set context = new HashSet(); @@ -239,10 +245,6 @@ public abstract class POIXMLDocument extends POIXMLDocumentPart implements Close //save extended and custom properties getProperties().commit(); - OPCPackage p = getPackage(); - if(p == null) { - throw new IOException("Cannot write data, document seems to have been closed already"); - } p.save(stream); } } diff --git a/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java b/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java index 9d25d8e05..16b28a450 100644 --- a/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java +++ b/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; +import static org.junit.Assert.fail; import java.io.File; import java.io.FileOutputStream; @@ -33,9 +34,11 @@ import java.util.HashSet; import java.util.List; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackageRelationshipTypes; +import org.apache.poi.util.NullOutputStream; import org.apache.poi.util.PackageHelper; import org.apache.poi.util.TempFile; import org.junit.Test; @@ -120,12 +123,43 @@ public final class TestPOIXMLDocument { FileOutputStream out = new FileOutputStream(tmp); doc.write(out); out.close(); + + // Should not be able to write to an output stream that has been closed + try { + doc.write(out); + fail("Should not be able to write to an output stream that has been closed."); + } catch (final OpenXML4JRuntimeException e) { + // FIXME: A better exception class (IOException?) and message should be raised + // indicating that the document could not be written because the output stream is closed. + // see {@link org.apache.poi.openxml4j.opc.ZipPackage#saveImpl(java.io.OutputStream)} + if (e.getMessage().matches("Fail to save: an error occurs while saving the package : The part .+ fail to be saved in the stream with marshaller .+")) { + // expected + } else { + throw e; + } + } + + // Should not be able to write a document that has been closed doc.close(); + try { + doc.write(new NullOutputStream()); + fail("Should not be able to write a document that has been closed."); + } catch (final IOException e) { + if (e.getMessage().equals("Cannot write data, document seems to have been closed already")) { + // expected + } else { + throw e; + } + } + + // Should be able to close a document multiple times, though subsequent closes will have no effect. + doc.close(); + @SuppressWarnings("resource") OPCPackage pkg2 = OPCPackage.open(tmp.getAbsolutePath()); + doc = new OPCParser(pkg1); try { - doc = new OPCParser(pkg1); doc.parse(new TestFactory()); context = new HashMap(); traverse(doc, context); @@ -150,6 +184,7 @@ public final class TestPOIXMLDocument { } } finally { doc.close(); + pkg1.close(); pkg2.close(); } } From 6146860a5ea1be6851e90b37a042773a9a177dbf Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Sun, 11 Sep 2016 02:02:56 +0000 Subject: [PATCH 076/157] bug 59958: Add cells on the fly to the evaluation sheet cache on cache miss; patch from Tomasz Stanczak git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760213 13f79535-47bb-0310-9956-ffa450edef68 --- .../xssf/usermodel/XSSFEvaluationSheet.java | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationSheet.java index c25dfb5d6..7d9d0286f 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationSheet.java @@ -67,7 +67,28 @@ final class XSSFEvaluationSheet implements EvaluationSheet { } } - return _cellCache.get(new CellKey(rowIndex, columnIndex)); + final CellKey key = new CellKey(rowIndex, columnIndex); + EvaluationCell evalcell = _cellCache.get(key); + + // If cache is stale, update cache with this one cell + // This is a compromise between rebuilding the entire cache + // (which would quickly defeat the benefit of the cache) + // and not caching at all. + // See bug 59958: Add cells on the fly to the evaluation sheet cache on cache miss + if (evalcell == null) { + XSSFRow row = _xs.getRow(rowIndex); + if (row == null) { + return null; + } + XSSFCell cell = row.getCell(columnIndex); + if (cell == null) { + return null; + } + evalcell = new XSSFEvaluationCell(cell, this); + _cellCache.put(key, evalcell); + } + + return evalcell; } private static class CellKey { From 050010094fdedb067e72762b721453fbd5f9e4c2 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Sun, 11 Sep 2016 02:52:29 +0000 Subject: [PATCH 077/157] add unit test class for XSLFTableRow git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760216 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/xslf/usermodel/TestXSLFTableRow.java | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTableRow.java diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTableRow.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTableRow.java new file mode 100644 index 000000000..6ef84ac26 --- /dev/null +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTableRow.java @@ -0,0 +1,112 @@ +/* ==================================================================== + 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.xslf.usermodel; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.List; + +import org.apache.poi.xslf.XSLFTestDataSamples; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow; + +public class TestXSLFTableRow { + + private static XMLSlideShow ppt; + private static XSLFTable tbl; + private static XSLFTableRow row; + + /** Copied from {@link TestXSLFTable#testRead()} */ + @Before + public void setUp() throws IOException { + ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx"); + + XSLFSlide slide = ppt.getSlides().get(3); + List shapes = slide.getShapes(); + tbl = (XSLFTable)shapes.get(0); + List rows = tbl.getRows(); + row = rows.get(0); + } + + @After + public void tearDown() throws IOException { + ppt.getPackage().revert(); + ppt.close(); + } + + + @Test + public void constructor() { + XSLFTableRow row2 = new XSLFTableRow(row.getXmlObject(), tbl); + assertSame(row.getXmlObject(), row2.getXmlObject()); + assertEquals(row.getHeight(), row2.getHeight(), 1e-16); + } + + @Test + public void testHeight() { + final double h = 10.0; + row.setHeight(h); + assertEquals(h, row.getHeight(), 1e-16); + } + + /** copied from {@link TestXSLFTable#testCreate()} */ + @Test + public void getCells() { + List cells = row.getCells(); + assertNotNull(cells); + assertEquals(3, cells.size()); + } + + @Test + public void testIterator() { + int i = 0; + for (XSLFTableCell cell : row) { + i++; + assertEquals("header"+i, cell.getText()); + } + assertEquals(3, i); + } + + /** copied from {@link TestXSLFTable#testCreate()} */ + @Test + public void addCell() { + XSLFTableCell cell = row.addCell(); + assertNotNull(cell); + + assertNotNull(cell.getXmlObject()); + // by default table cell has no borders + CTTableCell tc = (CTTableCell)cell.getXmlObject(); + assertTrue(tc.getTcPr().getLnB().isSetNoFill()); + assertTrue(tc.getTcPr().getLnT().isSetNoFill()); + assertTrue(tc.getTcPr().getLnL().isSetNoFill()); + assertTrue(tc.getTcPr().getLnR().isSetNoFill()); + } + + @Test + public void getXmlObject() { + CTTableRow ctrow = row.getXmlObject(); + assertNotNull(ctrow); + } + +} From 540909592361e8a67192864fb74fdb7fed3e3302 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Sun, 11 Sep 2016 03:21:33 +0000 Subject: [PATCH 078/157] bug 58191: Support merge cells within a table row; patch from Mark Olesen git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760217 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/xslf/usermodel/XSLFTableRow.java | 29 +++++++++++++++++-- .../poi/xslf/usermodel/TestXSLFTableRow.java | 19 ++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableRow.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableRow.java index 5326d9e78..c4529c4aa 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableRow.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableRow.java @@ -32,9 +32,9 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow; * Represents a table in a .pptx presentation */ public class XSLFTableRow implements Iterable { - private CTTableRow _row; - private List _cells; - private XSLFTable _table; + private final CTTableRow _row; + private final List _cells; + private final XSLFTable _table; /*package*/ XSLFTableRow(CTTableRow row, XSLFTable table){ _row = row; @@ -78,6 +78,29 @@ public class XSLFTableRow implements Iterable { _table.updateRowColIndexes(); return cell; } + + /** + * Merge cells of a table row, inclusive. + * Indices are 0-based. + * + * @param firstCol 0-based index of first column to merge, inclusive + * @param lastCol 0-based index of last column to merge, inclusive + */ + public void mergeCells(int firstCol, int lastCol) + { + if (firstCol >= lastCol) { + throw new IllegalArgumentException( + "Cannot merge, first column >= last column : " + + firstCol + " >= " + lastCol + ); + } + final int colSpan = (lastCol - firstCol) + 1; + + _cells.get(firstCol).setGridSpan(colSpan); + for (final XSLFTableCell cell : _cells.subList(firstCol+1, lastCol+1)) { + cell.setHMerge(true); + } + } } diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTableRow.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTableRow.java index 6ef84ac26..8a0892819 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTableRow.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTableRow.java @@ -17,9 +17,11 @@ package org.apache.poi.xslf.usermodel; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.io.IOException; import java.util.List; @@ -103,6 +105,23 @@ public class TestXSLFTableRow { assertTrue(tc.getTcPr().getLnR().isSetNoFill()); } + @Test + public void mergeCells() { + try { + row.mergeCells(0, 0); + fail("expected IllegalArgumentException when merging fewer than 2 columns"); + } catch (final IllegalArgumentException e) { + // expected + } + + row.mergeCells(0, 1); + List cells = row.getCells(); + //the top-left cell of a merged region is not regarded as merged + assertFalse("top-left cell of merged region", cells.get(0).isMerged()); + assertTrue("inside merged region", cells.get(1).isMerged()); + assertFalse("outside merged region", cells.get(2).isMerged()); + } + @Test public void getXmlObject() { CTTableRow ctrow = row.getXmlObject(); From adfd0d7f6c9e9ed1a0e83011f695f76ecab84a13 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Sun, 11 Sep 2016 03:37:56 +0000 Subject: [PATCH 079/157] bug 60025: DataFormatter should print booleans as TRUE/FALSE, not true/false git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760219 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/ss/usermodel/DataFormatter.java | 2 +- .../poi/ss/usermodel/TestDataFormatter.java | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java index ee6583937..61a5092f2 100644 --- a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java +++ b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java @@ -895,7 +895,7 @@ public class DataFormatter implements Observer { return cell.getRichStringCellValue().getString(); case BOOLEAN : - return String.valueOf(cell.getBooleanCellValue()); + return cell.getBooleanCellValue() ? "TRUE" : "FALSE"; case BLANK : return ""; case ERROR: diff --git a/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java b/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java index 649bddf9b..50276ae28 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java +++ b/src/testcases/org/apache/poi/ss/usermodel/TestDataFormatter.java @@ -597,6 +597,27 @@ public class TestDataFormatter { } } + @Test + public void testBoolean() throws IOException { + DataFormatter formatter = new DataFormatter(); + + // Create a spreadsheet with some TRUE/FALSE boolean values in it + Workbook wb = new HSSFWorkbook(); + try { + Sheet s = wb.createSheet(); + Row r = s.createRow(0); + Cell c = r.createCell(0); + + c.setCellValue(true); + assertEquals("TRUE", formatter.formatCellValue(c)); + + c.setCellValue(false); + assertEquals("FALSE", formatter.formatCellValue(c)); + } finally { + wb.close(); + } + } + /** * While we don't currently support using a locale code at * the start of a format string to format it differently, we From abe46f40ed865255bf4cce97d82f02b9ba0f0935 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Sun, 11 Sep 2016 04:05:42 +0000 Subject: [PATCH 080/157] bug 52425: Error adding Comments into cloned Sheets; patch from Daniel git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760221 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/xssf/usermodel/XSSFSheet.java | 7 +-- .../poi/xssf/usermodel/TestXSSFSheet.java | 45 ++++++++++++++++++ test-data/spreadsheet/52425.xlsx | Bin 0 -> 9439 bytes 3 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 test-data/spreadsheet/52425.xlsx diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java index 5f1da12ec..98711c9dd 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java @@ -591,20 +591,21 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { } } else { //search the referenced drawing in the list of the sheet's relations + final String id = ctDrawing.getId(); for (RelationPart rp : getRelationParts()){ POIXMLDocumentPart p = rp.getDocumentPart(); if(p instanceof XSSFVMLDrawing) { XSSFVMLDrawing dr = (XSSFVMLDrawing)p; String drId = rp.getRelationship().getId(); - if(drId.equals(ctDrawing.getId())){ + if (drId.equals(id)) { drawing = dr; break; } - break; + // do not break here since drawing has not been found yet (see bug 52425) } } if(drawing == null){ - logger.log(POILogger.ERROR, "Can't find VML drawing with id=" + ctDrawing.getId() + " in the list of the sheet's relationships"); + logger.log(POILogger.ERROR, "Can't find VML drawing with id=" + id + " in the list of the sheet's relationships"); } } return drawing; diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java index 689e999bc..3f7be066d 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java @@ -47,6 +47,9 @@ import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellCopyPolicy; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.ClientAnchor; +import org.apache.poi.ss.usermodel.Comment; +import org.apache.poi.ss.usermodel.CreationHelper; +import org.apache.poi.ss.usermodel.Drawing; import org.apache.poi.ss.usermodel.FormulaError; import org.apache.poi.ss.usermodel.IgnoredErrorType; import org.apache.poi.ss.usermodel.IndexedColors; @@ -1975,4 +1978,46 @@ public final class TestXSSFSheet extends BaseTestXSheet { wb.close(); } } + + /** + * See bug #52425 + */ + @Test + public void testInsertCommentsToClonedSheet() { + Workbook wb = XSSFTestDataSamples.openSampleWorkbook("52425.xlsx"); + CreationHelper helper = wb.getCreationHelper(); + Sheet sheet2 = wb.createSheet("Sheet 2"); + Sheet sheet3 = wb.cloneSheet(0); + wb.setSheetName(2, "Sheet 3"); + + // Adding Comment to new created Sheet 2 + addComments(helper, sheet2); + // Adding Comment to cloned Sheet 3 + addComments(helper, sheet3); + } + + private void addComments(CreationHelper helper, Sheet sheet) { + Drawing drawing = sheet.createDrawingPatriarch(); + + for (int i = 0; i < 2; i++) { + ClientAnchor anchor = helper.createClientAnchor(); + anchor.setCol1(0); + anchor.setRow1(0 + i); + anchor.setCol2(2); + anchor.setRow2(3 + i); + + Comment comment = drawing.createCellComment(anchor); + comment.setString(helper.createRichTextString("BugTesting")); + + Row row = sheet.getRow(0 + i); + if (row == null) + row = sheet.createRow(0 + i); + Cell cell = row.getCell(0); + if (cell == null) + cell = row.createCell(0); + + cell.setCellComment(comment); + } + + } } diff --git a/test-data/spreadsheet/52425.xlsx b/test-data/spreadsheet/52425.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..0659822f641489044f8688834d4691477ad54ce1 GIT binary patch literal 9439 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 Date: Sun, 11 Sep 2016 18:48:11 +0000 Subject: [PATCH 081/157] release prepare for 3.15 - updating build.xml and status.xml git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760270 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index 633607618..545a8d153 100644 --- a/build.xml +++ b/build.xml @@ -40,7 +40,7 @@ under the License. The Apache POI project Ant build. - + From b0215121b20a4483f9e8c1ea0ac12a5fcce048b2 Mon Sep 17 00:00:00 2001 From: David North Date: Sun, 11 Sep 2016 18:50:26 +0000 Subject: [PATCH 082/157] prepare for 3.16-beta1 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760273 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index 545a8d153..633607618 100644 --- a/build.xml +++ b/build.xml @@ -40,7 +40,7 @@ under the License. The Apache POI project Ant build. - + From 494b54161aef665c9e8bc681d9aca1949e6e36bb Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Mon, 12 Sep 2016 23:10:27 +0000 Subject: [PATCH 083/157] Disabled unit test for #60010 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760458 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/xssf/streaming/TestSXSSFWorkbook.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbook.java b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbook.java index bdd858b06..7b5a67de5 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbook.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbook.java @@ -25,6 +25,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; @@ -35,6 +36,8 @@ import java.util.Arrays; import org.apache.poi.POIDataSamples; import org.apache.poi.POITestCase; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.openxml4j.opc.PackageAccess; import org.apache.poi.ss.usermodel.BaseTestXWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; @@ -536,4 +539,40 @@ public final class TestSXSSFWorkbook extends BaseTestXWorkbook { swb.dispose(); swb.close(); } + + /** + * To avoid accident changes to the template, you should be able + * to create a SXSSFWorkbook from a read-only XSSF one, then + * change + save that (only). See bug #60010 + * TODO Fix this to work! + */ + @Test + @Ignore + public void createFromReadOnlyWorkbook() throws Exception { + File input = XSSFTestDataSamples.getSampleFile("sample.xlsx"); + OPCPackage pkg = OPCPackage.open(input, PackageAccess.READ); + XSSFWorkbook xssf = new XSSFWorkbook(pkg); + SXSSFWorkbook wb = new SXSSFWorkbook(xssf, 2); + + String sheetName = "Test SXSSF"; + Sheet s = wb.createSheet(sheetName); + for (int i=0; i<10; i++) { + Row r = s.createRow(i); + r.createCell(0).setCellValue(true); + r.createCell(1).setCellValue(2.4); + r.createCell(2).setCellValue("Test Row " + i); + } + assertEquals(10, s.getLastRowNum()); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + wb.write(bos); + wb.dispose(); + wb.close(); + + xssf = new XSSFWorkbook(new ByteArrayInputStream(bos.toByteArray())); + s = xssf.getSheet(sheetName); + assertEquals(10, s.getLastRowNum()); + assertEquals(true, s.getRow(0).getCell(0).getBooleanCellValue()); + assertEquals("Test Row 9", s.getRow(9).getCell(2).getStringCellValue()); + } } From 3c97d9700ae96e1b19de2eebda6501bb52ecac70 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Tue, 13 Sep 2016 23:24:56 +0000 Subject: [PATCH 084/157] change CellValue#getCellType() to return an int instead of an enum for backwards compatibility (source and binary) with POI 3.14. This reverts the behavior introduced in POI 3.15 beta 3 in r1751237. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760607 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/hssf/usermodel/HSSFFormulaEvaluator.java | 4 ++-- .../poi/ss/formula/BaseFormulaEvaluator.java | 2 +- .../org/apache/poi/ss/usermodel/CellValue.java | 14 +++++++++++++- .../poi/ss/usermodel/charts/DataSources.java | 4 ++-- .../xssf/usermodel/BaseXSSFFormulaEvaluator.java | 4 ++-- .../poi/ss/formula/TestStructuredReferences.java | 4 ++-- .../poi/ss/formula/functions/TestProper.java | 2 +- .../xssf/usermodel/TestFormulaEvaluatorOnXSSF.java | 10 +++++----- .../TestMultiSheetFormulaEvaluatorOnXSSF.java | 10 +++++----- .../apache/poi/xssf/usermodel/TestXSSFBugs.java | 4 ++-- .../poi/hssf/model/TestFormulaParserEval.java | 2 +- .../poi/hssf/record/TestSharedFormulaRecord.java | 2 +- .../hssf/usermodel/TestHSSFFormulaEvaluator.java | 4 ++-- .../poi/ss/formula/TestWorkbookEvaluator.java | 12 ++++++------ .../org/apache/poi/ss/formula/atp/TestIfError.java | 6 +++--- .../formula/eval/BaseTestCircularReferences.java | 14 +++++++------- .../poi/ss/formula/eval/TestFormulaBugs.java | 8 ++++---- .../formula/eval/TestFormulasFromSpreadsheet.java | 10 +++++----- .../poi/ss/formula/eval/TestMultiSheetEval.java | 10 +++++----- .../poi/ss/formula/eval/TestPercentEval.java | 2 +- .../BaseTestFunctionsFromSpreadsheet.java | 6 +++--- .../poi/ss/formula/functions/TestAddress.java | 2 +- .../functions/TestCalendarFieldFunction.java | 2 +- .../apache/poi/ss/formula/functions/TestClean.java | 2 +- .../apache/poi/ss/formula/functions/TestDate.java | 2 +- .../apache/poi/ss/formula/functions/TestFind.java | 4 ++-- .../apache/poi/ss/formula/functions/TestFixed.java | 4 ++-- .../poi/ss/formula/functions/TestIndirect.java | 4 ++-- .../apache/poi/ss/formula/functions/TestIrr.java | 2 +- .../poi/ss/formula/functions/TestIsBlank.java | 4 ++-- .../apache/poi/ss/formula/functions/TestMirr.java | 2 +- .../poi/ss/usermodel/BaseTestBugzillaIssues.java | 4 ++-- 32 files changed, 89 insertions(+), 77 deletions(-) diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java index 8d7d781f9..a0a932d07 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java @@ -163,7 +163,7 @@ public class HSSFFormulaEvaluator extends BaseFormulaEvaluator { CellValue cv = evaluateFormulaCellValue(cell); // cell remains a formula cell, but the cached value is changed setCellValue(cell, cv); - return cv.getCellType(); + return cv.getCellTypeEnum(); } /** @@ -196,7 +196,7 @@ public class HSSFFormulaEvaluator extends BaseFormulaEvaluator { } private static void setCellValue(Cell cell, CellValue cv) { - CellType cellType = cv.getCellType(); + CellType cellType = cv.getCellTypeEnum(); switch (cellType) { case BOOLEAN: cell.setCellValue(cv.getBooleanValue()); diff --git a/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java b/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java index 8746ba7fa..fb0c4d68d 100644 --- a/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java +++ b/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java @@ -132,7 +132,7 @@ public abstract class BaseFormulaEvaluator implements FormulaEvaluator, Workbook } protected static void setCellType(Cell cell, CellValue cv) { - CellType cellType = cv.getCellType(); + CellType cellType = cv.getCellTypeEnum(); switch (cellType) { case BOOLEAN: case ERROR: diff --git a/src/java/org/apache/poi/ss/usermodel/CellValue.java b/src/java/org/apache/poi/ss/usermodel/CellValue.java index 52fea225a..301accfca 100644 --- a/src/java/org/apache/poi/ss/usermodel/CellValue.java +++ b/src/java/org/apache/poi/ss/usermodel/CellValue.java @@ -78,10 +78,22 @@ public final class CellValue { } /** * @return Returns the cellType. + * @since POI 3.15 */ - public CellType getCellType() { + public CellType getCellTypeEnum() { return _cellType; } + /** + * @return Returns the cellType. + * @deprecated POI 3.15. Use {@link #getCellTypeEnum()} instead. + * In the future, the signature of this method will be changed to return a + * {@link CellType}. + */ + @Deprecated + public int getCellType() { + return _cellType.getCode(); + } + /** * @return Returns the errorValue. */ diff --git a/src/java/org/apache/poi/ss/usermodel/charts/DataSources.java b/src/java/org/apache/poi/ss/usermodel/charts/DataSources.java index 3bf891e0a..75e7fd9a8 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/DataSources.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/DataSources.java @@ -42,7 +42,7 @@ public class DataSources { return new AbstractCellRangeDataSource(sheet, cellRangeAddress) { public Number getPointAt(int index) { CellValue cellValue = getCellValueAt(index); - if (cellValue != null && cellValue.getCellType() == CellType.NUMERIC) { + if (cellValue != null && cellValue.getCellTypeEnum() == CellType.NUMERIC) { return Double.valueOf(cellValue.getNumberValue()); } else { return null; @@ -59,7 +59,7 @@ public class DataSources { return new AbstractCellRangeDataSource(sheet, cellRangeAddress) { public String getPointAt(int index) { CellValue cellValue = getCellValueAt(index); - if (cellValue != null && cellValue.getCellType() == CellType.STRING) { + if (cellValue != null && cellValue.getCellTypeEnum() == CellType.STRING) { return cellValue.getStringValue(); } else { return null; diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java index c6c030b95..726ae87e4 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java @@ -77,7 +77,7 @@ public abstract class BaseXSSFFormulaEvaluator extends BaseFormulaEvaluator { CellValue cv = evaluateFormulaCellValue(cell); // cell remains a formula cell, but the cached value is changed setCellValue(cell, cv); - return cv.getCellType(); + return cv.getCellTypeEnum(); } /** @@ -97,7 +97,7 @@ public abstract class BaseXSSFFormulaEvaluator extends BaseFormulaEvaluator { } private static void setCellValue(Cell cell, CellValue cv) { - CellType cellType = cv.getCellType(); + CellType cellType = cv.getCellTypeEnum(); switch (cellType) { case BOOLEAN: cell.setCellValue(cv.getBooleanValue()); diff --git a/src/ooxml/testcases/org/apache/poi/ss/formula/TestStructuredReferences.java b/src/ooxml/testcases/org/apache/poi/ss/formula/TestStructuredReferences.java index 4e176257f..b60664ad0 100644 --- a/src/ooxml/testcases/org/apache/poi/ss/formula/TestStructuredReferences.java +++ b/src/ooxml/testcases/org/apache/poi/ss/formula/TestStructuredReferences.java @@ -110,7 +110,7 @@ public class TestStructuredReferences { private static void confirm(FormulaEvaluator fe, Cell cell, double expectedResult) { fe.clearAllCachedResultValues(); CellValue cv = fe.evaluate(cell); - if (cv.getCellType() != CellType.NUMERIC) { + if (cv.getCellTypeEnum() != CellType.NUMERIC) { fail("expected numeric cell type but got " + cv.formatAsString()); } assertEquals(expectedResult, cv.getNumberValue(), 0.0); @@ -119,7 +119,7 @@ public class TestStructuredReferences { private static void confirm(FormulaEvaluator fe, Cell cell, String expectedResult) { fe.clearAllCachedResultValues(); CellValue cv = fe.evaluate(cell); - if (cv.getCellType() != CellType.STRING) { + if (cv.getCellTypeEnum() != CellType.STRING) { fail("expected String cell type but got " + cv.formatAsString()); } assertEquals(expectedResult, cv.getStringValue()); diff --git a/src/ooxml/testcases/org/apache/poi/ss/formula/functions/TestProper.java b/src/ooxml/testcases/org/apache/poi/ss/formula/functions/TestProper.java index d86079eca..a24fd8879 100644 --- a/src/ooxml/testcases/org/apache/poi/ss/formula/functions/TestProper.java +++ b/src/ooxml/testcases/org/apache/poi/ss/formula/functions/TestProper.java @@ -96,7 +96,7 @@ public final class TestProper { cell11.setCellFormula(formulaText); evaluator.clearAllCachedResultValues(); CellValue cv = evaluator.evaluate(cell11); - if (cv.getCellType() != CellType.STRING) { + if (cv.getCellTypeEnum() != CellType.STRING) { throw new AssertionFailedError("Wrong result type: " + cv.formatAsString()); } String actualValue = cv.getStringValue(); 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 4cbc7c4e6..ad8b49028 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestFormulaEvaluatorOnXSSF.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestFormulaEvaluatorOnXSSF.java @@ -205,14 +205,14 @@ public final class TestFormulaEvaluatorOnXSSF { final CellType expectedCellType = expValue.getCellTypeEnum(); switch (expectedCellType) { case BLANK: - assertEquals(msg, CellType.BLANK, actValue.getCellType()); + assertEquals(msg, CellType.BLANK, actValue.getCellTypeEnum()); break; case BOOLEAN: - assertEquals(msg, CellType.BOOLEAN, actValue.getCellType()); + assertEquals(msg, CellType.BOOLEAN, actValue.getCellTypeEnum()); assertEquals(msg, expValue.getBooleanCellValue(), actValue.getBooleanValue()); break; case ERROR: - assertEquals(msg, CellType.ERROR, actValue.getCellType()); + assertEquals(msg, CellType.ERROR, actValue.getCellTypeEnum()); // if(false) { // TODO: fix ~45 functions which are currently returning incorrect error values // assertEquals(msg, expValue.getErrorCellValue(), actValue.getErrorValue()); // } @@ -220,14 +220,14 @@ public final class TestFormulaEvaluatorOnXSSF { case FORMULA: // will never be used, since we will call method after formula evaluation fail("Cannot expect formula as result of formula evaluation: " + msg); case NUMERIC: - assertEquals(msg, CellType.NUMERIC, actValue.getCellType()); + assertEquals(msg, CellType.NUMERIC, actValue.getCellTypeEnum()); 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 STRING: - assertEquals(msg, CellType.STRING, actValue.getCellType()); + assertEquals(msg, CellType.STRING, actValue.getCellTypeEnum()); assertEquals(msg, expValue.getRichStringCellValue().getString(), actValue.getStringValue()); break; default: diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestMultiSheetFormulaEvaluatorOnXSSF.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestMultiSheetFormulaEvaluatorOnXSSF.java index f33d96e63..b8926a3cf 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestMultiSheetFormulaEvaluatorOnXSSF.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestMultiSheetFormulaEvaluatorOnXSSF.java @@ -188,14 +188,14 @@ public final class TestMultiSheetFormulaEvaluatorOnXSSF { final CellType expectedCellType = expValue.getCellTypeEnum(); switch (expectedCellType) { case BLANK: - assertEquals(msg, CellType.BLANK, actValue.getCellType()); + assertEquals(msg, CellType.BLANK, actValue.getCellTypeEnum()); break; case BOOLEAN: - assertEquals(msg, CellType.BOOLEAN, actValue.getCellType()); + assertEquals(msg, CellType.BOOLEAN, actValue.getCellTypeEnum()); assertEquals(msg, expValue.getBooleanCellValue(), actValue.getBooleanValue()); break; case ERROR: - assertEquals(msg, CellType.ERROR, actValue.getCellType()); + assertEquals(msg, CellType.ERROR, actValue.getCellTypeEnum()); // if(false) { // TODO: fix ~45 functions which are currently returning incorrect error values // assertEquals(msg, expected.getErrorCellValue(), actual.getErrorValue()); // } @@ -203,14 +203,14 @@ public final class TestMultiSheetFormulaEvaluatorOnXSSF { case FORMULA: // will never be used, since we will call method after formula evaluation fail("Cannot expect formula as result of formula evaluation: " + msg); case NUMERIC: - assertEquals(msg, CellType.NUMERIC, actValue.getCellType()); + assertEquals(msg, CellType.NUMERIC, actValue.getCellTypeEnum()); TestMathX.assertEquals(msg, expValue.getNumericCellValue(), actValue.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 STRING: - assertEquals(msg, CellType.STRING, actValue.getCellType()); + assertEquals(msg, CellType.STRING, actValue.getCellTypeEnum()); assertEquals(msg, expValue.getRichStringCellValue().getString(), actValue.getStringValue()); break; default: 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 2be21e830..e695f385f 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java @@ -304,7 +304,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { if(c.getCellTypeEnum() == CellType.FORMULA) { CellValue cv = eval.evaluate(c); - if(cv.getCellType() == CellType.NUMERIC) { + if(cv.getCellTypeEnum() == CellType.NUMERIC) { // assert that the calculated value agrees with // the cached formula result calculated by Excel String formula = c.getCellFormula(); @@ -2187,7 +2187,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertEquals("E4+E5", cell.getCellFormula()); CellValue value = evaluator.evaluate(cell); - assertEquals(CellType.ERROR, value.getCellType()); + assertEquals(CellType.ERROR, value.getCellTypeEnum()); assertEquals(-60, value.getErrorValue()); assertEquals("~CIRCULAR~REF~", FormulaError.forInt(value.getErrorValue()).getString()); assertEquals("CIRCULAR_REF", FormulaError.forInt(value.getErrorValue()).toString()); diff --git a/src/testcases/org/apache/poi/hssf/model/TestFormulaParserEval.java b/src/testcases/org/apache/poi/hssf/model/TestFormulaParserEval.java index 53f5f4ac7..291b3a500 100644 --- a/src/testcases/org/apache/poi/hssf/model/TestFormulaParserEval.java +++ b/src/testcases/org/apache/poi/hssf/model/TestFormulaParserEval.java @@ -99,7 +99,7 @@ public final class TestFormulaParserEval extends TestCase { } throw e; } - assertEquals(CellType.NUMERIC, result.getCellType()); + assertEquals(CellType.NUMERIC, result.getCellTypeEnum()); assertEquals(42.0, result.getNumberValue(), 0.0); } } diff --git a/src/testcases/org/apache/poi/hssf/record/TestSharedFormulaRecord.java b/src/testcases/org/apache/poi/hssf/record/TestSharedFormulaRecord.java index bf7b813d0..b61f9ed67 100644 --- a/src/testcases/org/apache/poi/hssf/record/TestSharedFormulaRecord.java +++ b/src/testcases/org/apache/poi/hssf/record/TestSharedFormulaRecord.java @@ -228,7 +228,7 @@ public final class TestSharedFormulaRecord extends TestCase { private static void confirmCellEvaluation(HSSFWorkbook wb, HSSFCell cell, double expectedValue) { HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb); CellValue cv = fe.evaluate(cell); - assertEquals(CellType.NUMERIC, cv.getCellType()); + assertEquals(CellType.NUMERIC, cv.getCellTypeEnum()); assertEquals(expectedValue, cv.getNumberValue(), 0.0); } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFFormulaEvaluator.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFFormulaEvaluator.java index 4c762fa90..d8987496f 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFFormulaEvaluator.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFFormulaEvaluator.java @@ -55,7 +55,7 @@ public final class TestHSSFFormulaEvaluator extends BaseTestFormulaEvaluator { HSSFCell cell = sheet.getRow(8).getCell(0); HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb); CellValue cv = fe.evaluate(cell); - assertEquals(CellType.NUMERIC, cv.getCellType()); + assertEquals(CellType.NUMERIC, cv.getCellTypeEnum()); assertEquals(3.72, cv.getNumberValue(), 0.0); wb.close(); } @@ -127,7 +127,7 @@ public final class TestHSSFFormulaEvaluator extends BaseTestFormulaEvaluator { try { value = hsf.evaluate(cellA1); - assertEquals(CellType.NUMERIC, value.getCellType()); + assertEquals(CellType.NUMERIC, value.getCellTypeEnum()); assertEquals(5.33, value.getNumberValue(), 0.0); } catch (RuntimeException e) { diff --git a/src/testcases/org/apache/poi/ss/formula/TestWorkbookEvaluator.java b/src/testcases/org/apache/poi/ss/formula/TestWorkbookEvaluator.java index c97face94..7c8936362 100644 --- a/src/testcases/org/apache/poi/ss/formula/TestWorkbookEvaluator.java +++ b/src/testcases/org/apache/poi/ss/formula/TestWorkbookEvaluator.java @@ -203,7 +203,7 @@ public class TestWorkbookEvaluator { } catch (RuntimeException e) { fail("Missing arg result not being handled correctly."); } - assertEquals(CellType.NUMERIC, cv.getCellType()); + assertEquals(CellType.NUMERIC, cv.getCellTypeEnum()); // adding blank to 1.0 gives 1.0 assertEquals(1.0, cv.getNumberValue(), 0.0); @@ -211,7 +211,7 @@ public class TestWorkbookEvaluator { cell.setCellFormula("\"abc\"&IF(1,,)"); fe.notifySetFormula(cell); cv = fe.evaluate(cell); - assertEquals(CellType.STRING, cv.getCellType()); + assertEquals(CellType.STRING, cv.getCellTypeEnum()); // adding blank to "abc" gives "abc" assertEquals("abc", cv.getStringValue()); @@ -219,7 +219,7 @@ public class TestWorkbookEvaluator { cell.setCellFormula("\"abc\"&CHOOSE(2,5,,9)"); fe.notifySetFormula(cell); cv = fe.evaluate(cell); - assertEquals(CellType.STRING, cv.getCellType()); + assertEquals(CellType.STRING, cv.getCellTypeEnum()); // adding blank to "abc" gives "abc" assertEquals("abc", cv.getStringValue()); } @@ -245,14 +245,14 @@ public class TestWorkbookEvaluator { } throw new RuntimeException(e); } - assertEquals(CellType.ERROR, cv.getCellType()); + assertEquals(CellType.ERROR, cv.getCellTypeEnum()); assertEquals(ErrorEval.VALUE_INVALID.getErrorCode(), cv.getErrorValue()); // verify circular refs are still detected properly fe.clearAllCachedResultValues(); cell.setCellFormula("OFFSET(A1,0,0)"); cv = fe.evaluate(cell); - assertEquals(CellType.ERROR, cv.getCellType()); + assertEquals(CellType.ERROR, cv.getCellTypeEnum()); assertEquals(ErrorEval.CIRCULAR_REF_ERROR.getErrorCode(), cv.getErrorValue()); } finally { wb.close(); @@ -396,7 +396,7 @@ public class TestWorkbookEvaluator { assertEquals(CellType.FORMULA, D1.getCellTypeEnum()); assertEquals(expectedFormula, D1.getCellFormula()); - assertEquals(CellType.NUMERIC, result.getCellType()); + assertEquals(CellType.NUMERIC, result.getCellTypeEnum()); assertEquals(expectedResult, result.getNumberValue(), EPSILON); testIFEqualsFormulaEvaluation_teardown(wb); diff --git a/src/testcases/org/apache/poi/ss/formula/atp/TestIfError.java b/src/testcases/org/apache/poi/ss/formula/atp/TestIfError.java index 1d956c76f..ebf6951f0 100644 --- a/src/testcases/org/apache/poi/ss/formula/atp/TestIfError.java +++ b/src/testcases/org/apache/poi/ss/formula/atp/TestIfError.java @@ -78,18 +78,18 @@ public class TestIfError extends TestCase { FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); assertEquals("Checks that the cell is numeric", - CellType.NUMERIC, evaluator.evaluate(cell1).getCellType()); + CellType.NUMERIC, evaluator.evaluate(cell1).getCellTypeEnum()); assertEquals("Divides 210 by 35 and returns 6.0", 6.0, evaluator.evaluate(cell1).getNumberValue(), accuracy); assertEquals("Checks that the cell is numeric", - CellType.STRING, evaluator.evaluate(cell2).getCellType()); + CellType.STRING, evaluator.evaluate(cell2).getCellTypeEnum()); assertEquals("Rounds -10 to a nearest multiple of -3 (-9)", "Error in calculation", evaluator.evaluate(cell2).getStringValue()); assertEquals("Check that C1 returns string", - CellType.STRING, evaluator.evaluate(cell3).getCellType()); + CellType.STRING, evaluator.evaluate(cell3).getCellTypeEnum()); assertEquals("Check that C1 returns string \"error\"", "error", evaluator.evaluate(cell3).getStringValue()); } diff --git a/src/testcases/org/apache/poi/ss/formula/eval/BaseTestCircularReferences.java b/src/testcases/org/apache/poi/ss/formula/eval/BaseTestCircularReferences.java index 4c0223afd..ec3aa9107 100644 --- a/src/testcases/org/apache/poi/ss/formula/eval/BaseTestCircularReferences.java +++ b/src/testcases/org/apache/poi/ss/formula/eval/BaseTestCircularReferences.java @@ -66,7 +66,7 @@ public abstract class BaseTestCircularReferences { * Makes sure that the specified evaluated cell value represents a circular reference error. */ private static void confirmCycleErrorCode(CellValue cellValue) { - assertTrue(cellValue.getCellType() == CellType.ERROR); + assertTrue(cellValue.getCellTypeEnum() == CellType.ERROR); assertEquals(ErrorEval.CIRCULAR_REF_ERROR.getErrorCode(), cellValue.getErrorValue()); } @@ -96,7 +96,7 @@ public abstract class BaseTestCircularReferences { CellValue cellValue = evaluateWithCycles(wb, testCell); - assertTrue(cellValue.getCellType() == CellType.NUMERIC); + assertTrue(cellValue.getCellTypeEnum() == CellType.NUMERIC); assertEquals(2, cellValue.getNumberValue(), 0); wb.close(); } @@ -166,24 +166,24 @@ public abstract class BaseTestCircularReferences { // Happy day flow - evaluate A1 first cv = fe.evaluate(cellA1); - assertEquals(CellType.NUMERIC, cv.getCellType()); + assertEquals(CellType.NUMERIC, cv.getCellTypeEnum()); assertEquals(42.0, cv.getNumberValue(), 0.0); cv = fe.evaluate(cellB1); // no circ-ref-error because A1 result is cached - assertEquals(CellType.NUMERIC, cv.getCellType()); + assertEquals(CellType.NUMERIC, cv.getCellTypeEnum()); assertEquals(46.0, cv.getNumberValue(), 0.0); // Show the bug - evaluate another cell from the loop first fe.clearAllCachedResultValues(); cv = fe.evaluate(cellB1); // Identified bug 46898 - assertNotEquals(cv.getCellType(), ErrorEval.CIRCULAR_REF_ERROR.getErrorCode()); - assertEquals(CellType.NUMERIC, cv.getCellType()); + assertNotEquals(cv.getCellTypeEnum(), ErrorEval.CIRCULAR_REF_ERROR.getErrorCode()); + assertEquals(CellType.NUMERIC, cv.getCellTypeEnum()); assertEquals(46.0, cv.getNumberValue(), 0.0); // start evaluation on another cell fe.clearAllCachedResultValues(); cv = fe.evaluate(cellE1); - assertEquals(CellType.NUMERIC, cv.getCellType()); + assertEquals(CellType.NUMERIC, cv.getCellTypeEnum()); assertEquals(43.0, cv.getNumberValue(), 0.0); wb.close(); diff --git a/src/testcases/org/apache/poi/ss/formula/eval/TestFormulaBugs.java b/src/testcases/org/apache/poi/ss/formula/eval/TestFormulaBugs.java index 561ce4bfd..98fe73169 100644 --- a/src/testcases/org/apache/poi/ss/formula/eval/TestFormulaBugs.java +++ b/src/testcases/org/apache/poi/ss/formula/eval/TestFormulaBugs.java @@ -58,7 +58,7 @@ public final class TestFormulaBugs { FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator(); CellValue cv = fe.evaluate(cell); - assertEquals(CellType.NUMERIC, cv.getCellType()); + assertEquals(CellType.NUMERIC, cv.getCellTypeEnum()); assertEquals(3.0, cv.getNumberValue(), 0.0); wb.close(); @@ -106,11 +106,11 @@ public final class TestFormulaBugs { FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator(); CellValue cv; cv = fe.evaluate(cell); - assertEquals(CellType.NUMERIC, cv.getCellType()); + assertEquals(CellType.NUMERIC, cv.getCellTypeEnum()); assertEquals(1.0, cv.getNumberValue(), 0.0); cv = fe.evaluate(row.getCell(1)); - assertEquals(CellType.BOOLEAN, cv.getCellType()); + assertEquals(CellType.BOOLEAN, cv.getCellTypeEnum()); assertEquals(true, cv.getBooleanValue()); wb.close(); @@ -161,7 +161,7 @@ public final class TestFormulaBugs { FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator(); CellValue cv = fe.evaluate(cell); - assertEquals(CellType.NUMERIC, cv.getCellType()); + assertEquals(CellType.NUMERIC, cv.getCellTypeEnum()); assertEquals(expectedResult, cv.getNumberValue(), 0.0); wb.close(); diff --git a/src/testcases/org/apache/poi/ss/formula/eval/TestFormulasFromSpreadsheet.java b/src/testcases/org/apache/poi/ss/formula/eval/TestFormulasFromSpreadsheet.java index fb3b6a928..9ce0488f9 100644 --- a/src/testcases/org/apache/poi/ss/formula/eval/TestFormulasFromSpreadsheet.java +++ b/src/testcases/org/apache/poi/ss/formula/eval/TestFormulasFromSpreadsheet.java @@ -190,24 +190,24 @@ public final class TestFormulasFromSpreadsheet { final CellType cellType = expValue.getCellTypeEnum(); switch (cellType) { case BLANK: - assertEquals(msg, CellType.BLANK, actValue.getCellType()); + assertEquals(msg, CellType.BLANK, actValue.getCellTypeEnum()); break; case BOOLEAN: - assertEquals(msg, CellType.BOOLEAN, actValue.getCellType()); + assertEquals(msg, CellType.BOOLEAN, actValue.getCellTypeEnum()); assertEquals(msg, expValue.getBooleanCellValue(), actValue.getBooleanValue()); break; case ERROR: - assertEquals(msg, CellType.ERROR, actValue.getCellType()); + assertEquals(msg, CellType.ERROR, actValue.getCellTypeEnum()); assertEquals(msg, ErrorEval.getText(expValue.getErrorCellValue()), ErrorEval.getText(actValue.getErrorValue())); break; case FORMULA: // will never be used, since we will call method after formula evaluation fail("Cannot expect formula as result of formula evaluation: " + msg); case NUMERIC: - assertEquals(msg, CellType.NUMERIC, actValue.getCellType()); + assertEquals(msg, CellType.NUMERIC, actValue.getCellTypeEnum()); TestMathX.assertEquals(msg, expValue.getNumericCellValue(), actValue.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR); break; case STRING: - assertEquals(msg, CellType.STRING, actValue.getCellType()); + assertEquals(msg, CellType.STRING, actValue.getCellTypeEnum()); assertEquals(msg, expValue.getRichStringCellValue().getString(), actValue.getStringValue()); break; default: diff --git a/src/testcases/org/apache/poi/ss/formula/eval/TestMultiSheetEval.java b/src/testcases/org/apache/poi/ss/formula/eval/TestMultiSheetEval.java index 429f5616e..b1b66c00d 100644 --- a/src/testcases/org/apache/poi/ss/formula/eval/TestMultiSheetEval.java +++ b/src/testcases/org/apache/poi/ss/formula/eval/TestMultiSheetEval.java @@ -110,24 +110,24 @@ public final class TestMultiSheetEval extends TestCase { switch (cellType) { case BLANK: - assertEquals(msg, CellType.BLANK, actual.getCellType()); + assertEquals(msg, CellType.BLANK, actual.getCellTypeEnum()); break; case BOOLEAN: - assertEquals(msg, CellType.BOOLEAN, actual.getCellType()); + assertEquals(msg, CellType.BOOLEAN, actual.getCellTypeEnum()); assertEquals(msg, expected.getBooleanCellValue(), actual.getBooleanValue()); break; case ERROR: - assertEquals(msg, CellType.ERROR, actual.getCellType()); + assertEquals(msg, CellType.ERROR, actual.getCellTypeEnum()); assertEquals(msg, ErrorEval.getText(expected.getErrorCellValue()), ErrorEval.getText(actual.getErrorValue())); break; case 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 NUMERIC: - assertEquals(msg, CellType.NUMERIC, actual.getCellType()); + assertEquals(msg, CellType.NUMERIC, actual.getCellTypeEnum()); TestMathX.assertEquals(msg, expected.getNumericCellValue(), actual.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR); break; case STRING: - assertEquals(msg, CellType.STRING, actual.getCellType()); + assertEquals(msg, CellType.STRING, actual.getCellTypeEnum()); assertEquals(msg, expected.getRichStringCellValue().getString(), actual.getStringValue()); break; default: diff --git a/src/testcases/org/apache/poi/ss/formula/eval/TestPercentEval.java b/src/testcases/org/apache/poi/ss/formula/eval/TestPercentEval.java index c3a5eec23..71cf649dd 100644 --- a/src/testcases/org/apache/poi/ss/formula/eval/TestPercentEval.java +++ b/src/testcases/org/apache/poi/ss/formula/eval/TestPercentEval.java @@ -78,7 +78,7 @@ public final class TestPercentEval extends TestCase { // else some other unexpected error throw e; } - assertEquals(CellType.NUMERIC, cv.getCellType()); + assertEquals(CellType.NUMERIC, cv.getCellTypeEnum()); assertEquals(0.5, cv.getNumberValue(), 0.0); } } diff --git a/src/testcases/org/apache/poi/ss/formula/functions/BaseTestFunctionsFromSpreadsheet.java b/src/testcases/org/apache/poi/ss/formula/functions/BaseTestFunctionsFromSpreadsheet.java index 8c40581e4..e32f3e05b 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/BaseTestFunctionsFromSpreadsheet.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/BaseTestFunctionsFromSpreadsheet.java @@ -155,7 +155,7 @@ public abstract class BaseTestFunctionsFromSpreadsheet { if (expectedCell.getCellTypeEnum() == CellType.ERROR) { int expectedErrorCode = expectedCell.getErrorCellValue(); - assertEquals(msg, CellType.ERROR, actualValue.getCellType()); + assertEquals(msg, CellType.ERROR, actualValue.getCellTypeEnum()); assertEquals(msg, ErrorEval.getText(expectedErrorCode), actualValue.formatAsString()); assertEquals(msg, expectedErrorCode, actualValue.getErrorValue()); assertEquals(msg, ErrorEval.getText(expectedErrorCode), ErrorEval.getText(actualValue.getErrorValue())); @@ -163,11 +163,11 @@ public abstract class BaseTestFunctionsFromSpreadsheet { } // unexpected error - assertNotEquals(msg, CellType.ERROR, actualValue.getCellType()); + assertNotEquals(msg, CellType.ERROR, actualValue.getCellTypeEnum()); assertNotEquals(msg, formatValue(expectedCell), ErrorEval.getText(actualValue.getErrorValue())); // wrong type error - assertEquals(msg, expectedCell.getCellTypeEnum(), actualValue.getCellType()); + assertEquals(msg, expectedCell.getCellTypeEnum(), actualValue.getCellTypeEnum()); final CellType expectedCellType = expectedCell.getCellTypeEnum(); switch (expectedCellType) { diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestAddress.java b/src/testcases/org/apache/poi/ss/formula/functions/TestAddress.java index 8f3951aa9..84c1778f3 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestAddress.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestAddress.java @@ -73,7 +73,7 @@ public final class TestAddress extends TestCase { cell.setCellFormula(formulaText); fe.notifyUpdateCell(cell); CellValue result = fe.evaluate(cell); - assertEquals(result.getCellType(), CellType.STRING); + assertEquals(result.getCellTypeEnum(), CellType.STRING); assertEquals(expectedResult, result.getStringValue()); } } diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestCalendarFieldFunction.java b/src/testcases/org/apache/poi/ss/formula/functions/TestCalendarFieldFunction.java index 3f8823729..337ad8518 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestCalendarFieldFunction.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestCalendarFieldFunction.java @@ -103,7 +103,7 @@ public final class TestCalendarFieldFunction extends TestCase { cell11.setCellFormula(formulaText); evaluator.clearAllCachedResultValues(); CellValue cv = evaluator.evaluate(cell11); - if (cv.getCellType() != CellType.NUMERIC) { + if (cv.getCellTypeEnum() != CellType.NUMERIC) { throw new AssertionFailedError("Wrong result type: " + cv.formatAsString()); } double actualValue = cv.getNumberValue(); diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestClean.java b/src/testcases/org/apache/poi/ss/formula/functions/TestClean.java index fe6c6a6ed..e0137aee4 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestClean.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestClean.java @@ -60,7 +60,7 @@ public final class TestClean extends TestCase { cell.setCellFormula(formulaText); fe.notifyUpdateCell(cell); CellValue result = fe.evaluate(cell); - assertEquals(result.getCellType(), CellType.STRING); + assertEquals(result.getCellTypeEnum(), CellType.STRING); assertEquals(expectedResult, result.getStringValue()); } } diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestDate.java b/src/testcases/org/apache/poi/ss/formula/functions/TestDate.java index db0f6b080..0051f72e7 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestDate.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestDate.java @@ -81,7 +81,7 @@ public final class TestDate extends TestCase { cell11.setCellFormula(formulaText); evaluator.clearAllCachedResultValues(); CellValue cv = evaluator.evaluate(cell11); - if (cv.getCellType() != CellType.NUMERIC) { + if (cv.getCellTypeEnum() != CellType.NUMERIC) { throw new AssertionFailedError("Wrong result type: " + cv.formatAsString()); } double actualValue = cv.getNumberValue(); diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestFind.java b/src/testcases/org/apache/poi/ss/formula/functions/TestFind.java index 0bfff626a..5ac75d62a 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestFind.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestFind.java @@ -66,7 +66,7 @@ public final class TestFind { cell.setCellFormula(formulaText); fe.notifyUpdateCell(cell); CellValue result = fe.evaluate(cell); - assertEquals(result.getCellType(), CellType.NUMERIC); + assertEquals(result.getCellTypeEnum(), CellType.NUMERIC); assertEquals(expectedResult, result.getNumberValue(), 0.0); } @@ -75,7 +75,7 @@ public final class TestFind { cell.setCellFormula(formulaText); fe.notifyUpdateCell(cell); CellValue result = fe.evaluate(cell); - assertEquals(result.getCellType(), CellType.ERROR); + assertEquals(result.getCellTypeEnum(), CellType.ERROR); assertEquals(expectedErrorCode.getCode(), result.getErrorValue()); } } diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestFixed.java b/src/testcases/org/apache/poi/ss/formula/functions/TestFixed.java index e14ea3c45..f6e1f3809 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestFixed.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestFixed.java @@ -117,7 +117,7 @@ public final class TestFixed { cell11.setCellFormula(formulaText); evaluator.clearAllCachedResultValues(); CellValue cv = evaluator.evaluate(cell11); - assertEquals("Wrong result type: " + cv.formatAsString(), CellType.STRING, cv.getCellType()); + assertEquals("Wrong result type: " + cv.formatAsString(), CellType.STRING, cv.getCellTypeEnum()); String actualValue = cv.getStringValue(); assertEquals(expectedResult, actualValue); } @@ -127,7 +127,7 @@ public final class TestFixed { evaluator.clearAllCachedResultValues(); CellValue cv = evaluator.evaluate(cell11); assertTrue("Wrong result type: " + cv.formatAsString(), - cv.getCellType() == CellType.ERROR + cv.getCellTypeEnum() == CellType.ERROR && cv.getErrorValue() == FormulaError.VALUE.getCode()); } } diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestIndirect.java b/src/testcases/org/apache/poi/ss/formula/functions/TestIndirect.java index ea5ac9c7a..99d370bd6 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestIndirect.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestIndirect.java @@ -185,7 +185,7 @@ public final class TestIndirect { fe.clearAllCachedResultValues(); cell.setCellFormula(formula); CellValue cv = fe.evaluate(cell); - if (cv.getCellType() != CellType.NUMERIC) { + if (cv.getCellTypeEnum() != CellType.NUMERIC) { fail("expected numeric cell type but got " + cv.formatAsString()); } assertEquals(expectedResult, cv.getNumberValue(), 0.0); @@ -196,7 +196,7 @@ public final class TestIndirect { fe.clearAllCachedResultValues(); cell.setCellFormula(formula); CellValue cv = fe.evaluate(cell); - if (cv.getCellType() != CellType.ERROR) { + if (cv.getCellTypeEnum() != CellType.ERROR) { fail("expected error cell type but got " + cv.formatAsString()); } int expCode = expectedResult.getErrorCode(); diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestIrr.java b/src/testcases/org/apache/poi/ss/formula/functions/TestIrr.java index 2fb108ead..40fac0dea 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestIrr.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestIrr.java @@ -128,7 +128,7 @@ public final class TestIrr extends TestCase { private static void assertFormulaResult(CellValue cv, HSSFCell cell){ double actualValue = cv.getNumberValue(); double expectedValue = cell.getNumericCellValue(); // cached formula result calculated by Excel - assertEquals("Invalid formula result: " + cv.toString(), CellType.NUMERIC, cv.getCellType()); + assertEquals("Invalid formula result: " + cv.toString(), CellType.NUMERIC, cv.getCellTypeEnum()); assertEquals(expectedValue, actualValue, 1E-4); // should agree within 0.01% } } diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestIsBlank.java b/src/testcases/org/apache/poi/ss/formula/functions/TestIsBlank.java index 51b80876e..e723711cc 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestIsBlank.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestIsBlank.java @@ -47,13 +47,13 @@ public final class TestIsBlank extends TestCase { HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb); CellValue result = fe.evaluate(cell); - assertEquals(CellType.BOOLEAN, result.getCellType()); + assertEquals(CellType.BOOLEAN, result.getCellTypeEnum()); assertEquals(true, result.getBooleanValue()); cell.setCellFormula("isblank(D7:D7)"); result = fe.evaluate(cell); - assertEquals(CellType.BOOLEAN, result.getCellType()); + assertEquals(CellType.BOOLEAN, result.getCellTypeEnum()); assertEquals(true, result.getBooleanValue()); } } diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestMirr.java b/src/testcases/org/apache/poi/ss/formula/functions/TestMirr.java index fc4c3c927..6a925511f 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestMirr.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestMirr.java @@ -162,7 +162,7 @@ public final class TestMirr extends TestCase { private static void assertFormulaResult(CellValue cv, HSSFCell cell) { double actualValue = cv.getNumberValue(); double expectedValue = cell.getNumericCellValue(); // cached formula result calculated by Excel - assertEquals("Invalid formula result: " + cv.toString(), CellType.NUMERIC, cv.getCellType()); + assertEquals("Invalid formula result: " + cv.toString(), CellType.NUMERIC, cv.getCellTypeEnum()); assertEquals(expectedValue, actualValue, 1E-8); } } diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java index bdd09bfd6..f9725ba8a 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java @@ -1133,8 +1133,8 @@ public abstract class BaseTestBugzillaIssues { cfs.setCellFormula("B1"); FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator(); - assertEquals(CellType.NUMERIC, fe.evaluate(cfn).getCellType()); - assertEquals(CellType.STRING, fe.evaluate(cfs).getCellType()); + assertEquals(CellType.NUMERIC, fe.evaluate(cfn).getCellTypeEnum()); + assertEquals(CellType.STRING, fe.evaluate(cfs).getCellTypeEnum()); fe.evaluateFormulaCellEnum(cfn); fe.evaluateFormulaCellEnum(cfs); From 0977e51818d0e0ba6b6788232684886f0a8d5e58 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 02:41:01 +0000 Subject: [PATCH 085/157] bug 59907: restore ClientAnchor#setAnchorType(int) that was removed in POI 3.14 beta 1 and broke backwards compatibility without a 2 release deprecation notice git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760617 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/hssf/usermodel/HSSFClientAnchor.java | 10 ++++++++++ .../org/apache/poi/ss/usermodel/ClientAnchor.java | 8 ++++++++ .../apache/poi/xssf/usermodel/XSSFClientAnchor.java | 12 ++++++++++++ 3 files changed, 30 insertions(+) diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java b/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java index 4b8a25e30..e71e362b8 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java @@ -250,6 +250,7 @@ public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor { /** * Gets the anchor type + * Changed from returning an int to an enum in POI 3.14 beta 1. * @return the anchor type */ @Override @@ -260,11 +261,20 @@ public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor { /** * Sets the anchor type * @param anchorType the anchor type to set + * @since POI 3.14 */ @Override public void setAnchorType(AnchorType anchorType) { _escherClientAnchor.setFlag(anchorType.value); } + /** + * Sets the anchor type + * @param anchorType the anchor type to set + * @deprecated POI 3.15. Use {@link #setAnchorType(AnchorType)} instead. + */ + public void setAnchorType(int anchorType) { + _escherClientAnchor.setFlag((short) anchorType); + } private void checkRange(int value, int minRange, int maxRange, String varName) { if (value < minRange || value > maxRange) diff --git a/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java b/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java index 672c1e230..65e69d87d 100644 --- a/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java +++ b/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java @@ -288,11 +288,19 @@ public interface ClientAnchor { /** * Sets the anchor type * @param anchorType the anchor type to set + * @since POI 3.14 */ public void setAnchorType( AnchorType anchorType ); + /** + * Sets the anchor type + * @param anchorType the anchor type to set + * @deprecated POI 3.15. Use {@link #setAnchorType(AnchorType)} instead. + */ + public void setAnchorType( int anchorType ); /** * Gets the anchor type + * Changed from returning an int to an enum in POI 3.14 beta 1. * @return the anchor type */ public AnchorType getAnchorType(); diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java index 8045912ab..19d7d8109 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java @@ -218,15 +218,27 @@ public final class XSSFClientAnchor extends XSSFAnchor implements ClientAnchor { /** * Sets the anchor type * @param anchorType the anchor type to set + * @since POI 3.14 */ @Override public void setAnchorType( AnchorType anchorType ) { this.anchorType = anchorType; } + /** + * Sets the anchor type + * @param anchorType the anchor type to set + * @deprecated POI 3.15. Use {@link #setAnchorType(AnchorType)} instead + */ + @Override + public void setAnchorType( int anchorType ) + { + this.anchorType = AnchorType.byId(anchorType); + } /** * Gets the anchor type + * Changed from returning an int to an enum in POI 3.14 beta 1. * @return the anchor type */ @Override From 9ea59153136522e4af3faef3e48dcc053130b655 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 02:55:52 +0000 Subject: [PATCH 086/157] bug 59907: add @Removal annotations to deprecated ClientAnchor#setAnchorType(int) git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760619 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java | 3 +++ src/java/org/apache/poi/ss/usermodel/ClientAnchor.java | 2 ++ .../java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java | 2 ++ 3 files changed, 7 insertions(+) diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java b/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java index e71e362b8..d4c8c6d68 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java @@ -21,6 +21,7 @@ import org.apache.poi.ddf.EscherClientAnchorRecord; import org.apache.poi.ddf.EscherRecord; import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.usermodel.ClientAnchor; +import org.apache.poi.util.Removal; /** * A client anchor is attached to an excel worksheet. It anchors against a @@ -272,6 +273,8 @@ public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor { * @param anchorType the anchor type to set * @deprecated POI 3.15. Use {@link #setAnchorType(AnchorType)} instead. */ + @Removal(version="3.17") + @Override public void setAnchorType(int anchorType) { _escherClientAnchor.setFlag((short) anchorType); } diff --git a/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java b/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java index 65e69d87d..705c53bba 100644 --- a/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java +++ b/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java @@ -17,6 +17,7 @@ package org.apache.poi.ss.usermodel; import org.apache.poi.util.Internal; +import org.apache.poi.util.Removal; /** * A client anchor is attached to an excel worksheet. It anchors against a @@ -296,6 +297,7 @@ public interface ClientAnchor { * @param anchorType the anchor type to set * @deprecated POI 3.15. Use {@link #setAnchorType(AnchorType)} instead. */ + @Removal(version="3.17") public void setAnchorType( int anchorType ); /** diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java index 19d7d8109..df47fc227 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java @@ -19,6 +19,7 @@ package org.apache.poi.xssf.usermodel; import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.util.Internal; +import org.apache.poi.util.Removal; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker; /** @@ -230,6 +231,7 @@ public final class XSSFClientAnchor extends XSSFAnchor implements ClientAnchor { * @param anchorType the anchor type to set * @deprecated POI 3.15. Use {@link #setAnchorType(AnchorType)} instead */ + @Removal(version="3.17") @Override public void setAnchorType( int anchorType ) { From b91b5c57155f21e5b17c8ac4eb91bcd08ec13027 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 03:06:51 +0000 Subject: [PATCH 087/157] bug 59907: add @Removal annotations to AnchorType static aliases in ClientAnchor git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760620 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/ss/usermodel/ClientAnchor.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java b/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java index 705c53bba..702970c69 100644 --- a/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java +++ b/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java @@ -36,6 +36,7 @@ public interface ClientAnchor { *

* @deprecated since POI 3.14beta1 (circa 2015-11-24). Use {@link AnchorType#MOVE_AND_RESIZE} instead. */ + @Removal(version="3.17") public static final AnchorType MOVE_AND_RESIZE = AnchorType.MOVE_AND_RESIZE; /** @@ -51,6 +52,7 @@ public interface ClientAnchor { *

* @deprecated since POI 3.14beta1 (circa 2015-11-24). Use {@link AnchorType#MOVE_DONT_RESIZE} instead. */ + @Removal(version="3.17") public static final AnchorType MOVE_DONT_RESIZE = AnchorType.MOVE_DONT_RESIZE; /** @@ -67,6 +69,7 @@ public interface ClientAnchor { *

* @deprecated since POI 3.14beta1 (circa 2015-11-24). Use {@link AnchorType#DONT_MOVE_AND_RESIZE} instead. */ + @Removal(version="3.17") public static final AnchorType DONT_MOVE_AND_RESIZE = AnchorType.DONT_MOVE_AND_RESIZE; /** From 808996a68357c9905f22f4d2157c119db670b691 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 03:17:51 +0000 Subject: [PATCH 088/157] bug 59873: add @Removal annotations for deprecated CreationHelper#createHyperlink(int) and Hyperlink static aliases to HyperlinkType enum values git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760621 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/common/usermodel/Hyperlink.java | 7 +++++++ .../org/apache/poi/hssf/usermodel/HSSFCreationHelper.java | 2 ++ src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java | 2 ++ .../java/org/apache/poi/xslf/usermodel/XSLFHyperlink.java | 4 ++++ .../org/apache/poi/xssf/streaming/SXSSFCreationHelper.java | 2 ++ .../org/apache/poi/xssf/usermodel/XSSFCreationHelper.java | 2 ++ .../java/org/apache/poi/xssf/usermodel/XSSFHyperlink.java | 1 + 7 files changed, 20 insertions(+) diff --git a/src/java/org/apache/poi/common/usermodel/Hyperlink.java b/src/java/org/apache/poi/common/usermodel/Hyperlink.java index 132a3eb4c..abcdd112a 100644 --- a/src/java/org/apache/poi/common/usermodel/Hyperlink.java +++ b/src/java/org/apache/poi/common/usermodel/Hyperlink.java @@ -16,6 +16,8 @@ ==================================================================== */ package org.apache.poi.common.usermodel; +import org.apache.poi.util.Removal; + /** * Represents a hyperlink. */ @@ -25,6 +27,7 @@ public interface Hyperlink { * * @deprecated POI 3.15 beta 3. Use {@link HyperlinkType#URL} instead. */ + @Removal(version="3.17") public static final int LINK_URL = 1; // HyperlinkType.URL.getCode() /** @@ -32,6 +35,7 @@ public interface Hyperlink { * * @deprecated POI 3.15 beta 3. Use {@link HyperlinkType#DOCUMENT} instead. */ + @Removal(version="3.17") public static final int LINK_DOCUMENT = 2; // HyperlinkType.DOCUMENT.getCode() /** @@ -39,6 +43,7 @@ public interface Hyperlink { * * @deprecated POI 3.15 beta 3. Use {@link HyperlinkType#EMAIL} instead. */ + @Removal(version="3.17") public static final int LINK_EMAIL = 3; // HyperlinkType.EMAIL.getCode() /** @@ -46,6 +51,7 @@ public interface Hyperlink { * * @deprecated POI 3.15 beta 3. Use {@link HyperlinkType#FILE} instead. */ + @Removal(version="3.17") public static final int LINK_FILE = 4; // HyperlinkType.FILE.getCode() @@ -83,6 +89,7 @@ public interface Hyperlink { * @return the type of this hyperlink * @see HyperlinkType#forInt(int) * @deprecated POI 3.15 beta 3. Use {@link #getTypeEnum()} + * getType will return a HyperlinkType enum in the future. */ public int getType(); diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCreationHelper.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCreationHelper.java index 7ce7ef1be..863d1a004 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCreationHelper.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCreationHelper.java @@ -21,6 +21,7 @@ import org.apache.poi.common.usermodel.HyperlinkType; import org.apache.poi.hssf.record.common.ExtendedColor; import org.apache.poi.ss.usermodel.CreationHelper; import org.apache.poi.util.Internal; +import org.apache.poi.util.Removal; public class HSSFCreationHelper implements CreationHelper { private final HSSFWorkbook workbook; @@ -50,6 +51,7 @@ public class HSSFCreationHelper implements CreationHelper { * @deprecated POI 3.15 beta 3. Use {@link #createHyperlink(HyperlinkType)} instead. */ @Deprecated + @Removal(version="3.17") @Override public HSSFHyperlink createHyperlink(int type) { return new HSSFHyperlink(type); diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java b/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java index 1847bfc0f..084a6bfe0 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java @@ -273,6 +273,8 @@ public class HSSFHyperlink implements Hyperlink { * * @return the type of this hyperlink * @see HyperlinkType#forInt + * @deprecated POI 3.15. Use {@link #getTypeEnum()} instead. + * getType will return a HyperlinkType enum in the future. */ @Override public int getType() { diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFHyperlink.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFHyperlink.java index 09b883c00..2f300623f 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFHyperlink.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFHyperlink.java @@ -69,6 +69,10 @@ public class XSLFHyperlink implements Hyperlink { _link.setTooltip(label); } + /* (non-Javadoc) + * @deprecated POI 3.15. Use {@link #getTypeEnum()} instead. + * Will return a HyperlinkType enum in the future + */ @Override public int getType() { return getTypeEnum().getCode(); diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCreationHelper.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCreationHelper.java index 201879702..f2687ff1d 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCreationHelper.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCreationHelper.java @@ -26,6 +26,7 @@ import org.apache.poi.ss.usermodel.Hyperlink; import org.apache.poi.util.Internal; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; +import org.apache.poi.util.Removal; import org.apache.poi.xssf.usermodel.XSSFCreationHelper; import org.apache.poi.xssf.usermodel.XSSFRichTextString; @@ -72,6 +73,7 @@ public class SXSSFCreationHelper implements CreationHelper { * @deprecated POI 3.15 beta 3. Use {@link #createHyperlink(HyperlinkType)} instead. */ @Deprecated + @Removal(version="3.17") @Override public Hyperlink createHyperlink(int type) { return helper.createHyperlink(type); diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCreationHelper.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCreationHelper.java index 63dc78069..cb11a73b2 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCreationHelper.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCreationHelper.java @@ -20,6 +20,7 @@ import org.apache.poi.common.usermodel.HyperlinkType; import org.apache.poi.ss.usermodel.CreationHelper; import org.apache.poi.ss.usermodel.Hyperlink; import org.apache.poi.util.Internal; +import org.apache.poi.util.Removal; public class XSSFCreationHelper implements CreationHelper { private final XSSFWorkbook workbook; @@ -61,6 +62,7 @@ public class XSSFCreationHelper implements CreationHelper { * @deprecated POI 3.15 beta 3. Use {@link #createHyperlink(HyperlinkType)} instead. */ @Deprecated + @Removal(version="3.17") @Override public XSSFHyperlink createHyperlink(int type) { return new XSSFHyperlink(type); diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFHyperlink.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFHyperlink.java index 1f1c8421f..9d26a6658 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFHyperlink.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFHyperlink.java @@ -168,6 +168,7 @@ public class XSSFHyperlink implements Hyperlink { * @return the type of this hyperlink * @see HyperlinkType#forInt * @deprecated POI 3.15 beta 3. Use {@link #getTypeEnum()} instead. + * getType will return a HyperlinkType enum in the future. */ @Override public int getType() { From 6839a52aa382ff2f57cc6dc6e245fab14475f69f Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 03:24:15 +0000 Subject: [PATCH 089/157] bug 59837,59833,59264: add @Removal annotations to CellStyle constants for which enums now exist git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760622 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/ss/usermodel/CellStyle.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/java/org/apache/poi/ss/usermodel/CellStyle.java b/src/java/org/apache/poi/ss/usermodel/CellStyle.java index b6c971979..17a5d0e75 100644 --- a/src/java/org/apache/poi/ss/usermodel/CellStyle.java +++ b/src/java/org/apache/poi/ss/usermodel/CellStyle.java @@ -17,270 +17,316 @@ package org.apache.poi.ss.usermodel; +import org.apache.poi.util.Removal; + public interface CellStyle { /** * general (normal) horizontal alignment * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#GENERAL} instead. */ + @Removal(version="3.17") static final short ALIGN_GENERAL = 0x0; //HorizontalAlignment.GENERAL.getCode(); /** * left-justified horizontal alignment * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#LEFT} instead. */ + @Removal(version="3.17") static final short ALIGN_LEFT = 0x1; //HorizontalAlignment.LEFT.getCode(); /** * center horizontal alignment * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#CENTER} instead. */ + @Removal(version="3.17") static final short ALIGN_CENTER = 0x2; //HorizontalAlignment.CENTER.getCode(); /** * right-justified horizontal alignment * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#RIGHT} instead. */ + @Removal(version="3.17") static final short ALIGN_RIGHT = 0x3; //HorizontalAlignment.RIGHT.getCode(); /** * fill? horizontal alignment * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#FILL} instead. */ + @Removal(version="3.17") static final short ALIGN_FILL = 0x4; //HorizontalAlignment.FILL.getCode(); /** * justified horizontal alignment * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#JUSTIFY} instead. */ + @Removal(version="3.17") static final short ALIGN_JUSTIFY = 0x5; //HorizontalAlignment.JUSTIFY.getCode(); /** * center-selection? horizontal alignment * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#CENTER_SELECTION} instead. */ + @Removal(version="3.17") static final short ALIGN_CENTER_SELECTION = 0x6; //HorizontalAlignment.CENTER_SELECTION.getCode(); /** * top-aligned vertical alignment * @deprecated POI 3.15 beta 3. Use {@link VerticalAlignment#TOP} instead. */ + @Removal(version="3.17") static final short VERTICAL_TOP = 0x0; //VerticalAlignment.TOP.getCode(); /** * center-aligned vertical alignment * @deprecated POI 3.15 beta 3. Use {@link VerticalAlignment#CENTER} instead. */ + @Removal(version="3.17") static final short VERTICAL_CENTER = 0x1; //VerticalAlignment.CENTER.getCode(); /** * bottom-aligned vertical alignment * @deprecated POI 3.15 beta 3. Use {@link VerticalAlignment#BOTTOM} instead. */ + @Removal(version="3.17") static final short VERTICAL_BOTTOM = 0x2; //VerticalAlignment.BOTTOM.getCode(); /** * vertically justified vertical alignment * @deprecated POI 3.15 beta 3. Use {@link VerticalAlignment#JUSTIFY} instead. */ + @Removal(version="3.17") static final short VERTICAL_JUSTIFY = 0x3; //VerticalAlignment.JUSTIFY.getCode(); /** * No border * @deprecated 3.15 beta 2. Use {@link BorderStyle#NONE} instead. */ + @Removal(version="3.17") static final short BORDER_NONE = 0x0; //BorderStyle.NONE.getCode(); /** * Thin border * @deprecated 3.15 beta 2. Use {@link BorderStyle#THIN} instead. */ + @Removal(version="3.17") static final short BORDER_THIN = 0x1; //BorderStyle.THIN.getCode(); /** * Medium border * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM} instead. */ + @Removal(version="3.17") static final short BORDER_MEDIUM = 0x2; //BorderStyle.MEDIUM.getCode(); /** * dash border * @deprecated 3.15 beta 2. Use {@link BorderStyle#DASHED} instead. */ + @Removal(version="3.17") static final short BORDER_DASHED = 0x3; //BorderStyle.DASHED.getCode(); /** * dot border * @deprecated 3.15 beta 2. Use {@link BorderStyle#DOTTED} instead. */ + @Removal(version="3.17") static final short BORDER_DOTTED = 0x4; //BorderStyle.DOTTED.getCode(); /** * Thick border * @deprecated 3.15 beta 2. Use {@link BorderStyle#THICK} instead. */ + @Removal(version="3.17") static final short BORDER_THICK = 0x5; //BorderStyle.THICK.getCode(); /** * double-line border * @deprecated 3.15 beta 2. Use {@link BorderStyle#DOUBLE} instead. */ + @Removal(version="3.17") static final short BORDER_DOUBLE = 0x6; //BorderStyle.DOUBLE.getCode(); /** * hair-line border * @deprecated 3.15 beta 2. Use {@link BorderStyle#HAIR} instead. */ + @Removal(version="3.17") static final short BORDER_HAIR = 0x7; //BorderStyle.HAIR.getCode(); /** * Medium dashed border * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM_DASHED} instead. */ + @Removal(version="3.17") static final short BORDER_MEDIUM_DASHED = 0x8; //BorderStyle.MEDIUM_DASHED.getCode(); /** * dash-dot border * @deprecated 3.15 beta 2. Use {@link BorderStyle#DASH_DOT} instead. */ + @Removal(version="3.17") static final short BORDER_DASH_DOT = 0x9; //BorderStyle.DASH_DOT.getCode(); /** * medium dash-dot border * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM_DASH_DOT} instead. */ + @Removal(version="3.17") static final short BORDER_MEDIUM_DASH_DOT = 0xA; //BorderStyle.MEDIUM_DASH_DOT.getCode(); /** * dash-dot-dot border * @deprecated 3.15 beta 2. Use {@link BorderStyle#DASH_DOT_DOT} instead. */ + @Removal(version="3.17") static final short BORDER_DASH_DOT_DOT = 0xB; //BorderStyle.DASH_DOT_DOT.getCode(); /** * medium dash-dot-dot border * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM_DASH_DOT_DOT} instead. */ + @Removal(version="3.17") static final short BORDER_MEDIUM_DASH_DOT_DOT = 0xC; //BorderStyle.MEDIUM_DASH_DOT_DOT.getCode(); /** * slanted dash-dot border * @deprecated 3.15 beta 2. Use {@link BorderStyle#SLANTED_DASH_DOT} instead. */ + @Removal(version="3.17") static final short BORDER_SLANTED_DASH_DOT = 0xD; //BorderStyle.SLANTED_DASH_DOT.getCode(); /** * Fill Pattern: No background * @deprecated 3.15 beta 3. Use {@link FillPatternType#NO_FILL} instead. */ + @Removal(version="3.17") static final short NO_FILL = 0; //FillPatternType.NO_FILL.getCode(); /** * Fill Pattern: Solidly filled * @deprecated 3.15 beta 3. Use {@link FillPatternType#SOLID_FOREGROUND} instead. */ + @Removal(version="3.17") static final short SOLID_FOREGROUND = 1; //FillPatternType.SOLID_FOREGROUND.getCode(); /** * Fill Pattern: Small fine dots * @deprecated 3.15 beta 3. Use {@link FillPatternType#FINE_DOTS} instead. */ + @Removal(version="3.17") static final short FINE_DOTS = 2; //FillPatternType.FINE_DOTS.getCode(); /** * Fill Pattern: Wide dots * @deprecated 3.15 beta 3. Use {@link FillPatternType#ALT_BARS} instead. */ + @Removal(version="3.17") static final short ALT_BARS = 3; //FillPatternType.ALT_BARS.getCode(); /** * Fill Pattern: Sparse dots * @deprecated 3.15 beta 3. Use {@link FillPatternType#SPARSE_DOTS} instead. */ + @Removal(version="3.17") static final short SPARSE_DOTS = 4; //FillPatternType.SPARSE_DOTS.getCode(); /** * Fill Pattern: Thick horizontal bands * @deprecated 3.15 beta 3. Use {@link FillPatternType#THICK_HORZ_BANDS} instead. */ + @Removal(version="3.17") static final short THICK_HORZ_BANDS = 5; //FillPatternType.THICK_HORZ_BANDS.getCode(); /** * Fill Pattern: Thick vertical bands * @deprecated 3.15 beta 3. Use {@link FillPatternType#THICK_VERT_BANDS} instead. */ + @Removal(version="3.17") static final short THICK_VERT_BANDS = 6; //FillPatternType.THICK_VERT_BANDS.getCode(); /** * Fill Pattern: Thick backward facing diagonals * @deprecated 3.15 beta 3. Use {@link FillPatternType#THICK_BACKWARD_DIAG} instead. */ + @Removal(version="3.17") static final short THICK_BACKWARD_DIAG = 7; //FillPatternType.THICK_BACKWARD_DIAG.getCode(); /** * Fill Pattern: Thick forward facing diagonals * @deprecated 3.15 beta 3. Use {@link FillPatternType#THICK_FORWARD_DIAG} instead. */ + @Removal(version="3.17") static final short THICK_FORWARD_DIAG = 8; //FillPatternType.THICK_FORWARD_DIAG.getCode(); /** * Fill Pattern: Large spots * @deprecated 3.15 beta 3. Use {@link FillPatternType#BIG_SPOTS} instead. */ + @Removal(version="3.17") static final short BIG_SPOTS = 9; //FillPatternType.BIG_SPOTS.getCode(); /** * Fill Pattern: Brick-like layout * @deprecated 3.15 beta 3. Use {@link FillPatternType#BRICKS} instead. */ + @Removal(version="3.17") static final short BRICKS = 10; //FillPatternType.BRICKS.getCode(); /** * Fill Pattern: Thin horizontal bands * @deprecated 3.15 beta 3. Use {@link FillPatternType#THIN_HORZ_BANDS} instead. */ + @Removal(version="3.17") static final short THIN_HORZ_BANDS = 11; //FillPatternType.THIN_HORZ_BANDS.getCode(); /** * Fill Pattern: Thin vertical bands * @deprecated 3.15 beta 3. Use {@link FillPatternType#THIN_VERT_BANDS} instead. */ + @Removal(version="3.17") static final short THIN_VERT_BANDS = 12; //FillPatternType.THIN_VERT_BANDS.getCode(); /** * Fill Pattern: Thin backward diagonal * @deprecated 3.15 beta 3. Use {@link FillPatternType#THIN_BACKWARD_DIAG} instead. */ + @Removal(version="3.17") static final short THIN_BACKWARD_DIAG = 13; //FillPatternType.THIN_BACKWARD_DIAG.getCode(); /** * Fill Pattern: Thin forward diagonal * @deprecated 3.15 beta 3. Use {@link FillPatternType#THIN_FORWARD_DIAG} instead. */ + @Removal(version="3.17") static final short THIN_FORWARD_DIAG = 14; //FillPatternType.THIN_FORWARD_DIAG.getCode(); /** * Fill Pattern: Squares * @deprecated 3.15 beta 3. Use {@link FillPatternType#SQUARES} instead. */ + @Removal(version="3.17") static final short SQUARES = 15; //FillPatternType.SQUARES.getCode(); /** * Fill Pattern: Diamonds * @deprecated 3.15 beta 3. Use {@link FillPatternType#DIAMONDS} instead. */ + @Removal(version="3.17") static final short DIAMONDS = 16; //FillPatternType.DIAMONDS.getCode(); /** * Fill Pattern: Less Dots * @deprecated 3.15 beta 3. Use {@link FillPatternType#LESS_DOTS} instead. */ + @Removal(version="3.17") static final short LESS_DOTS = 17; //FillPatternType.LESS_DOTS.getCode(); /** * Fill Pattern: Least Dots * @deprecated 3.15 beta 3. Use {@link FillPatternType#LEAST_DOTS} instead. */ + @Removal(version="3.17") static final short LEAST_DOTS = 18; //FillPatternType.LEAST_DOTS.getCode(); /** From 5d1ae2cbae7b9445b8735e4871aee45a3c02e051 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 03:33:52 +0000 Subject: [PATCH 090/157] bug 59833: add @Removal annotation to deprecated methods git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760623 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java | 2 ++ .../java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java index 6e6c05504..4fbbdf62e 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java @@ -32,6 +32,7 @@ import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.VerticalAlignment; +import org.apache.poi.util.Removal; /** * High level representation of the style of a cell in a sheet of a workbook. @@ -254,6 +255,7 @@ public final class HSSFCellStyle implements CellStyle { * @see #ALIGN_CENTER_SELECTION * @deprecated POI 3.15 beta 3. Use {@link #setAlignment(HorizontalAlignment)} instead. */ + @Removal(version="3.17") @Override public void setAlignment(short align) { diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java index 760c21537..1e7dc5040 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java @@ -28,6 +28,7 @@ import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.VerticalAlignment; import org.apache.poi.util.Internal; +import org.apache.poi.util.Removal; import org.apache.poi.xssf.model.StylesTable; import org.apache.poi.xssf.model.ThemesTable; import org.apache.poi.xssf.usermodel.extensions.XSSFCellAlignment; @@ -1121,7 +1122,9 @@ public class XSSFCellStyle implements CellStyle { * @see #setFillBackgroundColor(short) * @see #setFillForegroundColor(short) * @param fp fill pattern (set to {@link org.apache.poi.ss.usermodel.CellStyle#SOLID_FOREGROUND} to fill w/foreground color) + * @deprecated POI 3.15. Use {@link #setFillPattern(FillPatternType)} instead. */ + @Removal(version="3.17") @Override public void setFillPattern(short fp) { setFillPattern(FillPatternType.forInt(fp)); From 2644cae41839fc4c9554e54a63a9e4588e645e3a Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 03:51:45 +0000 Subject: [PATCH 091/157] bug 59790: add @Removal annotations to deprecated methods git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760624 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/hssf/model/HSSFFormulaParser.java | 7 +++++-- .../apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java | 1 + .../org/apache/poi/ss/formula/OperandClassTransformer.java | 6 +++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/java/org/apache/poi/hssf/model/HSSFFormulaParser.java b/src/java/org/apache/poi/hssf/model/HSSFFormulaParser.java index b54b27ad4..774eb788f 100644 --- a/src/java/org/apache/poi/hssf/model/HSSFFormulaParser.java +++ b/src/java/org/apache/poi/hssf/model/HSSFFormulaParser.java @@ -17,8 +17,6 @@ package org.apache.poi.hssf.model; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.util.Internal; import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.formula.FormulaParseException; @@ -26,6 +24,9 @@ import org.apache.poi.ss.formula.FormulaParser; import org.apache.poi.ss.formula.FormulaParsingWorkbook; import org.apache.poi.ss.formula.FormulaRenderer; import org.apache.poi.ss.formula.FormulaType; +import org.apache.poi.ss.formula.ptg.Ptg; +import org.apache.poi.util.Internal; +import org.apache.poi.util.Removal; /** * HSSF wrapper for the {@link FormulaParser} and {@link FormulaRenderer} @@ -61,6 +62,7 @@ public final class HSSFFormulaParser { * * @deprecated POI 3.15 beta 3. Use {@link #parse(String, HSSFWorkbook, FormulaType)} instead. */ + @Removal(version="3.17") public static Ptg[] parse(String formula, HSSFWorkbook workbook, int formulaType) throws FormulaParseException { return parse(formula, workbook, FormulaType.forInt(formulaType)); } @@ -87,6 +89,7 @@ public final class HSSFFormulaParser { * @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid * @deprecated POI 3.15 beta 3. Use {@link #parse(String, HSSFWorkbook, FormulaType, int)} instead. */ + @Removal(version="3.17") public static Ptg[] parse(String formula, HSSFWorkbook workbook, int formulaType, int sheetIndex) throws FormulaParseException { return parse(formula, workbook, FormulaType.forInt(formulaType), sheetIndex); } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java index a0a932d07..b43228740 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java @@ -35,6 +35,7 @@ import org.apache.poi.ss.usermodel.CellValue; import org.apache.poi.ss.usermodel.FormulaEvaluator; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.util.Internal; +import org.apache.poi.util.Removal; /** * Evaluates formula cells.

diff --git a/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java b/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java index a45d5a2d1..8e438c966 100644 --- a/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java +++ b/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java @@ -28,6 +28,7 @@ import org.apache.poi.ss.formula.ptg.Ptg; import org.apache.poi.ss.formula.ptg.RangePtg; import org.apache.poi.ss.formula.ptg.UnionPtg; import org.apache.poi.ss.formula.ptg.ValueOperatorPtg; +import org.apache.poi.util.Removal; /** * This class performs 'operand class' transformation. Non-base tokens are classified into three @@ -59,7 +60,10 @@ final class OperandClassTransformer { private final FormulaType _formulaType; - /** @deprecated POI 3.15 beta 3. */ + /** + * @deprecated POI 3.15 beta 3. Use {@code OperandClassTransformer(FormulaType)} instead. + */ + @Removal(version="3.17") public OperandClassTransformer(int formulaType) { this(FormulaType.forInt(formulaType)); } From 292d7ec27c9a91c45aeec8387e7fd9f249d1b1e2 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 04:35:45 +0000 Subject: [PATCH 092/157] bug 59264: revert getBorder[Top|Bottom|Left|Right|Diagonal]() to return short and add getBorder[Top|Bottom|Left|Right|Diagonal]Enum() returns BorderStyle enum for backwards compatibility with POI 3.14 and earlier git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760627 13f79535-47bb-0310-9956-ffa450edef68 --- .../hssf/usermodel/HSSFBorderFormatting.java | 65 +++++++++++++++++-- .../poi/ss/usermodel/BorderFormatting.java | 58 +++++++++++++++-- .../xssf/usermodel/XSSFBorderFormatting.java | 65 +++++++++++++++++-- .../apache/poi/hssf/usermodel/TestBugs.java | 4 +- .../BaseTestConditionalFormatting.java | 58 ++++++++--------- 5 files changed, 203 insertions(+), 47 deletions(-) diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java b/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java index d06c9f179..c4113b615 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java @@ -42,28 +42,83 @@ public final class HSSFBorderFormatting implements org.apache.poi.ss.usermodel.B return borderFormatting; } + /** + * @deprecated POI 3.15. Use {@link #getBorderBottomEnum()}. + * This method will return an BorderStyle enum in the future. + */ @Override - public BorderStyle getBorderBottom() { + public short getBorderBottom() { + return (short)borderFormatting.getBorderBottom(); + } + /** + * @since POI 3.15 + */ + @Override + public BorderStyle getBorderBottomEnum() { return BorderStyle.valueOf((short)borderFormatting.getBorderBottom()); } + /** + * @deprecated POI 3.15. Use {@link #getBorderDiagonalEnum()}. + * This method will return an BorderStyle enum in the future. + */ @Override - public BorderStyle getBorderDiagonal() { + public short getBorderDiagonal() { + return (short)borderFormatting.getBorderDiagonal(); + } + /** + * @since POI 3.15 + */ + @Override + public BorderStyle getBorderDiagonalEnum() { return BorderStyle.valueOf((short)borderFormatting.getBorderDiagonal()); } + /** + * @deprecated POI 3.15. Use {@link #getBorderLeftEnum()}. + * This method will return an BorderStyle enum in the future. + */ @Override - public BorderStyle getBorderLeft() { + public short getBorderLeft() { + return (short)borderFormatting.getBorderLeft(); + } + /** + * @since POI 3.15 + */ + @Override + public BorderStyle getBorderLeftEnum() { return BorderStyle.valueOf((short)borderFormatting.getBorderLeft()); } + /** + * @deprecated POI 3.15. Use {@link #getBorderRightEnum()}. + * This method will return an BorderStyle enum in the future. + */ @Override - public BorderStyle getBorderRight() { + public short getBorderRight() { + return (short)borderFormatting.getBorderRight(); + } + /** + * @since POI 3.15 + */ + @Override + public BorderStyle getBorderRightEnum() { return BorderStyle.valueOf((short)borderFormatting.getBorderRight()); } + /** + * @deprecated POI 3.15. Use {@link #getBorderTopEnum()}. + * This method will return an BorderStyle enum in the future. + */ @Override - public BorderStyle getBorderTop() { + public short getBorderTop() { + return (short)borderFormatting.getBorderTop(); + } + /** + * @since POI 3.15 + */ + @Override + public BorderStyle getBorderTopEnum() { return BorderStyle.valueOf((short)borderFormatting.getBorderTop()); } diff --git a/src/java/org/apache/poi/ss/usermodel/BorderFormatting.java b/src/java/org/apache/poi/ss/usermodel/BorderFormatting.java index 059cdd065..949cc3d00 100644 --- a/src/java/org/apache/poi/ss/usermodel/BorderFormatting.java +++ b/src/java/org/apache/poi/ss/usermodel/BorderFormatting.java @@ -19,6 +19,8 @@ package org.apache.poi.ss.usermodel; +import org.apache.poi.util.Removal; + /** * High level representation for Border Formatting component * of Conditional Formatting settings @@ -27,84 +29,128 @@ public interface BorderFormatting { /** No border * @deprecated 3.15 beta 2. Use {@link BorderStyle#NONE} */ + @Removal(version="3.17") short BORDER_NONE = 0x0; /** Thin border * @deprecated 3.15 beta 2. Use {@link BorderStyle#THIN} */ + @Removal(version="3.17") short BORDER_THIN = 0x1; /** Medium border * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM} */ + @Removal(version="3.17") short BORDER_MEDIUM = 0x2; /** dash border * @deprecated 3.15 beta 2. Use {@link BorderStyle#DASHED} */ + @Removal(version="3.17") short BORDER_DASHED = 0x3; /** dot border * @deprecated 3.15 beta 2. Use {@link BorderStyle#DOTTED} */ + @Removal(version="3.17") short BORDER_DOTTED = 0x4; /** Thick border * @deprecated 3.15 beta 2. Use {@link BorderStyle#THICK} */ + @Removal(version="3.17") short BORDER_THICK = 0x5; /** double-line border * @deprecated 3.15 beta 2. Use {@link BorderStyle#DOUBLE} */ + @Removal(version="3.17") short BORDER_DOUBLE = 0x6; /** hair-line border * @deprecated 3.15 beta 2. Use {@link BorderStyle#HAIR} */ + @Removal(version="3.17") short BORDER_HAIR = 0x7; /** Medium dashed border * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM_DASHED} */ + @Removal(version="3.17") short BORDER_MEDIUM_DASHED = 0x8; - /** dash-dot border * @deprecated 3.15 beta 2. Use {@link BorderStyle#DASH_DOT} */ + @Removal(version="3.17") short BORDER_DASH_DOT = 0x9; /** medium dash-dot border * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM_DASH_DOT} */ + @Removal(version="3.17") short BORDER_MEDIUM_DASH_DOT = 0xA; /** dash-dot-dot border * @deprecated 3.15 beta 2. Use {@link BorderStyle#DASH_DOT_DOT} */ + @Removal(version="3.17") short BORDER_DASH_DOT_DOT = 0xB; /** medium dash-dot-dot border * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM_DASH_DOT_DOT} */ + @Removal(version="3.17") short BORDER_MEDIUM_DASH_DOT_DOT = 0xC; /** slanted dash-dot border * @deprecated 3.15 beta 2. Use {@link BorderStyle#SLANTED_DASH_DOT} */ + @Removal(version="3.17") short BORDER_SLANTED_DASH_DOT = 0xD; - BorderStyle getBorderBottom(); + /** + * @deprecated POI 3.15. Use {@link #getBorderBottomEnum()}. + * This method will return an BorderStyle enum in the future. + */ + short getBorderBottom(); + /** @since POI 3.15 */ + BorderStyle getBorderBottomEnum(); - BorderStyle getBorderDiagonal(); + /** + * @deprecated POI 3.15. Use {@link #getBorderDiagonalEnum()}. + * This method will return an BorderStyle enum in the future. + */ + short getBorderDiagonal(); + /** @since POI 3.15 */ + BorderStyle getBorderDiagonalEnum(); - BorderStyle getBorderLeft(); + /** + * @deprecated POI 3.15. Use {@link #getBorderLeftEnum()}. + * This method will return an BorderStyle enum in the future. + */ + short getBorderLeft(); + /** @since POI 3.15 */ + BorderStyle getBorderLeftEnum(); - BorderStyle getBorderRight(); + /** + * @deprecated POI 3.15. Use {@link #getBorderRightEnum()}. + * This method will return an BorderStyle enum in the future. + */ + short getBorderRight(); + /** @since POI 3.15 */ + BorderStyle getBorderRightEnum(); - BorderStyle getBorderTop(); + /** + * @deprecated POI 3.15. Use {@link #getBorderTopEnum()}. + * This method will return an BorderStyle enum in the future. + */ + short getBorderTop(); + /** @since POI 3.15 */ + BorderStyle getBorderTopEnum(); + short getBottomBorderColor(); Color getBottomBorderColorColor(); diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBorderFormatting.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBorderFormatting.java index e48fe948e..edea8cda9 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBorderFormatting.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBorderFormatting.java @@ -35,32 +35,87 @@ public class XSSFBorderFormatting implements BorderFormatting { _border = border; } + /** + * @deprecated POI 3.15. Use {@link #getBorderBottomEnum()}. + * This method will return an BorderStyle enum in the future. + */ @Override - public BorderStyle getBorderBottom() { + public short getBorderBottom() { + return getBorderBottomEnum().getCode(); + } + /** + * @since POI 3.15 + */ + @Override + public BorderStyle getBorderBottomEnum() { STBorderStyle.Enum ptrn = _border.isSetBottom() ? _border.getBottom().getStyle() : null; return ptrn == null ? BorderStyle.NONE : BorderStyle.valueOf((short)(ptrn.intValue() - 1)); } + /** + * @deprecated POI 3.15. Use {@link #getBorderDiagonalEnum()}. + * This method will return an BorderStyle enum in the future. + */ @Override - public BorderStyle getBorderDiagonal() { + public short getBorderDiagonal() { + return getBorderDiagonalEnum().getCode(); + } + /** + * @since POI 3.15 + */ + @Override + public BorderStyle getBorderDiagonalEnum() { STBorderStyle.Enum ptrn = _border.isSetDiagonal() ? _border.getDiagonal().getStyle() : null; return ptrn == null ? BorderStyle.NONE : BorderStyle.valueOf((short)(ptrn.intValue() - 1)); } + /** + * @deprecated POI 3.15. Use {@link #getBorderLeftEnum()}. + * This method will return an BorderStyle enum in the future. + */ @Override - public BorderStyle getBorderLeft() { + public short getBorderLeft() { + return getBorderLeftEnum().getCode(); + } + /** + * @since POI 3.15 + */ + @Override + public BorderStyle getBorderLeftEnum() { STBorderStyle.Enum ptrn = _border.isSetLeft() ? _border.getLeft().getStyle() : null; return ptrn == null ? BorderStyle.NONE : BorderStyle.valueOf((short)(ptrn.intValue() - 1)); } + /** + * @deprecated POI 3.15. Use {@link #getBorderRightEnum()}. + * This method will return an BorderStyle enum in the future. + */ @Override - public BorderStyle getBorderRight() { + public short getBorderRight() { + return getBorderRightEnum().getCode(); + } + /** + * @since POI 3.15 + */ + @Override + public BorderStyle getBorderRightEnum() { STBorderStyle.Enum ptrn = _border.isSetRight() ? _border.getRight().getStyle() : null; return ptrn == null ? BorderStyle.NONE : BorderStyle.valueOf((short)(ptrn.intValue() - 1)); } + /** + * @deprecated POI 3.15. Use {@link #getBorderTopEnum()}. + * This method will return an BorderStyle enum in the future. + */ @Override - public BorderStyle getBorderTop() { + public short getBorderTop() { + return getBorderTopEnum().getCode(); + } + /** + * @since POI 3.15 + */ + @Override + public BorderStyle getBorderTopEnum() { STBorderStyle.Enum ptrn = _border.isSetTop() ? _border.getTop().getStyle() : null; return ptrn == null ? BorderStyle.NONE : BorderStyle.valueOf((short)(ptrn.intValue() - 1)); } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java index 466964acf..dca98f620 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java @@ -3051,7 +3051,7 @@ public final class TestBugs extends BaseTestBugzillaIssues { HSSFBorderFormatting bord = rule.createBorderFormatting(); bord.setBorderDiagonal(BorderStyle.THICK); - assertEquals(BorderStyle.THICK, bord.getBorderDiagonal()); + assertEquals(BorderStyle.THICK, bord.getBorderDiagonalEnum()); bord.setBackwardDiagonalOn(true); assertTrue(bord.isBackwardDiagonalOn()); @@ -3064,7 +3064,7 @@ public final class TestBugs extends BaseTestBugzillaIssues { // Create the bottom border style so we know what a border is supposed to look like bord.setBorderBottom(BorderStyle.THICK); - assertEquals(BorderStyle.THICK, bord.getBorderBottom()); + assertEquals(BorderStyle.THICK, bord.getBorderBottomEnum()); bord.setBottomBorderColor(BLUE); assertEquals(BLUE, bord.getBottomBorderColor()); diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java index 5509cbf71..28cfb2cf7 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java @@ -363,10 +363,10 @@ public abstract class BaseTestConditionalFormatting { BorderFormatting r1bf = rule1.getBorderFormatting(); assertNotNull(r1bf); - assertEquals(BorderStyle.THIN, r1bf.getBorderBottom()); - assertEquals(BorderStyle.THICK,r1bf.getBorderTop()); - assertEquals(BorderStyle.DASHED,r1bf.getBorderLeft()); - assertEquals(BorderStyle.DOTTED,r1bf.getBorderRight()); + assertEquals(BorderStyle.THIN, r1bf.getBorderBottomEnum()); + assertEquals(BorderStyle.THICK,r1bf.getBorderTopEnum()); + assertEquals(BorderStyle.DASHED,r1bf.getBorderLeftEnum()); + assertEquals(BorderStyle.DOTTED,r1bf.getBorderRightEnum()); PatternFormatting r1pf = rule1.getPatternFormatting(); assertNotNull(r1pf); @@ -1021,19 +1021,19 @@ public abstract class BaseTestConditionalFormatting { for (BorderStyle border : BorderStyle.values()) { borderFmt.setBorderTop(border); - assertEquals(border, borderFmt.getBorderTop()); + assertEquals(border, borderFmt.getBorderTopEnum()); borderFmt.setBorderBottom(border); - assertEquals(border, borderFmt.getBorderBottom()); + assertEquals(border, borderFmt.getBorderBottomEnum()); borderFmt.setBorderLeft(border); - assertEquals(border, borderFmt.getBorderLeft()); + assertEquals(border, borderFmt.getBorderLeftEnum()); borderFmt.setBorderRight(border); - assertEquals(border, borderFmt.getBorderRight()); + assertEquals(border, borderFmt.getBorderRightEnum()); borderFmt.setBorderDiagonal(border); - assertEquals(border, borderFmt.getBorderDiagonal()); + assertEquals(border, borderFmt.getBorderDiagonalEnum()); } workbook.close(); @@ -1049,37 +1049,37 @@ public abstract class BaseTestConditionalFormatting { ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(ComparisonOperator.EQUAL, "7"); BorderFormatting borderFmt = rule1.createBorderFormatting(); - assertEquals(BorderStyle.NONE, borderFmt.getBorderBottom()); + assertEquals(BorderStyle.NONE, borderFmt.getBorderBottomEnum()); borderFmt.setBorderBottom(BorderStyle.DOTTED); - assertEquals(BorderStyle.DOTTED, borderFmt.getBorderBottom()); + assertEquals(BorderStyle.DOTTED, borderFmt.getBorderBottomEnum()); borderFmt.setBorderBottom(BorderStyle.NONE); - assertEquals(BorderStyle.NONE, borderFmt.getBorderBottom()); + assertEquals(BorderStyle.NONE, borderFmt.getBorderBottomEnum()); borderFmt.setBorderBottom(BorderStyle.THICK); - assertEquals(BorderStyle.THICK, borderFmt.getBorderBottom()); + assertEquals(BorderStyle.THICK, borderFmt.getBorderBottomEnum()); - assertEquals(BorderStyle.NONE, borderFmt.getBorderTop()); + assertEquals(BorderStyle.NONE, borderFmt.getBorderTopEnum()); borderFmt.setBorderTop(BorderStyle.DOTTED); - assertEquals(BorderStyle.DOTTED, borderFmt.getBorderTop()); + assertEquals(BorderStyle.DOTTED, borderFmt.getBorderTopEnum()); borderFmt.setBorderTop(BorderStyle.NONE); - assertEquals(BorderStyle.NONE, borderFmt.getBorderTop()); + assertEquals(BorderStyle.NONE, borderFmt.getBorderTopEnum()); borderFmt.setBorderTop(BorderStyle.THICK); - assertEquals(BorderStyle.THICK, borderFmt.getBorderTop()); + assertEquals(BorderStyle.THICK, borderFmt.getBorderTopEnum()); - assertEquals(BorderStyle.NONE, borderFmt.getBorderLeft()); + assertEquals(BorderStyle.NONE, borderFmt.getBorderLeftEnum()); borderFmt.setBorderLeft(BorderStyle.DOTTED); - assertEquals(BorderStyle.DOTTED, borderFmt.getBorderLeft()); + assertEquals(BorderStyle.DOTTED, borderFmt.getBorderLeftEnum()); borderFmt.setBorderLeft(BorderStyle.NONE); - assertEquals(BorderStyle.NONE, borderFmt.getBorderLeft()); + assertEquals(BorderStyle.NONE, borderFmt.getBorderLeftEnum()); borderFmt.setBorderLeft(BorderStyle.THIN); - assertEquals(BorderStyle.THIN, borderFmt.getBorderLeft()); + assertEquals(BorderStyle.THIN, borderFmt.getBorderLeftEnum()); - assertEquals(BorderStyle.NONE, borderFmt.getBorderRight()); + assertEquals(BorderStyle.NONE, borderFmt.getBorderRightEnum()); borderFmt.setBorderRight(BorderStyle.DOTTED); - assertEquals(BorderStyle.DOTTED, borderFmt.getBorderRight()); + assertEquals(BorderStyle.DOTTED, borderFmt.getBorderRightEnum()); borderFmt.setBorderRight(BorderStyle.NONE); - assertEquals(BorderStyle.NONE, borderFmt.getBorderRight()); + assertEquals(BorderStyle.NONE, borderFmt.getBorderRightEnum()); borderFmt.setBorderRight(BorderStyle.HAIR); - assertEquals(BorderStyle.HAIR, borderFmt.getBorderRight()); + assertEquals(BorderStyle.HAIR, borderFmt.getBorderRightEnum()); ConditionalFormattingRule [] cfRules = { rule1 }; @@ -1095,10 +1095,10 @@ public abstract class BaseTestConditionalFormatting { BorderFormatting r1fp = cf.getRule(0).getBorderFormatting(); assertNotNull(r1fp); - assertEquals(BorderStyle.THICK, r1fp.getBorderBottom()); - assertEquals(BorderStyle.THICK, r1fp.getBorderTop()); - assertEquals(BorderStyle.THIN, r1fp.getBorderLeft()); - assertEquals(BorderStyle.HAIR, r1fp.getBorderRight()); + assertEquals(BorderStyle.THICK, r1fp.getBorderBottomEnum()); + assertEquals(BorderStyle.THICK, r1fp.getBorderTopEnum()); + assertEquals(BorderStyle.THIN, r1fp.getBorderLeftEnum()); + assertEquals(BorderStyle.HAIR, r1fp.getBorderRightEnum()); workbook.close(); } From 38cd94d676d748560c931ee626e1a1088d579c1c Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 05:22:23 +0000 Subject: [PATCH 093/157] bug 59264: revert CellStyle#getBorder[Top|Bottom|Left|Right]() to return short and add getBorder[Top|Bottom|Left|Right]Enum() returns BorderStyle enum for backwards compatibility with POI 3.14 and earlier git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760630 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/hssf/view/SVTableCellRenderer.java | 4 +- .../poi/ss/examples/ExcelComparator.java | 16 ++--- .../apache/poi/ss/examples/html/ToHtml.java | 8 +-- .../poi/hssf/usermodel/HSSFCellStyle.java | 62 +++++++++++++++++-- .../apache/poi/ss/usermodel/CellStyle.java | 48 ++++++++++++-- src/java/org/apache/poi/ss/util/CellUtil.java | 8 +-- .../poi/xssf/usermodel/XSSFCellStyle.java | 61 +++++++++++------- .../poi/xssf/usermodel/TestXSSFCellStyle.java | 38 ++++++------ .../hssf/converter/ExcelToFoConverter.java | 16 ++--- .../hssf/converter/ExcelToHtmlConverter.java | 8 +-- .../apache/poi/hssf/usermodel/TestBugs.java | 2 +- .../poi/hssf/usermodel/TestCellStyle.java | 26 ++++---- .../poi/hssf/usermodel/TestHSSFOptimiser.java | 6 +- .../poi/hssf/usermodel/TestRowStyle.java | 8 +-- .../poi/ss/usermodel/BaseTestBorderStyle.java | 8 +-- .../apache/poi/ss/usermodel/BaseTestCell.java | 8 +-- .../apache/poi/ss/util/BaseTestCellUtil.java | 4 +- 17 files changed, 222 insertions(+), 109 deletions(-) diff --git a/src/examples/src/org/apache/poi/hssf/view/SVTableCellRenderer.java b/src/examples/src/org/apache/poi/hssf/view/SVTableCellRenderer.java index ac0075b16..8a59b8306 100644 --- a/src/examples/src/org/apache/poi/hssf/view/SVTableCellRenderer.java +++ b/src/examples/src/org/apache/poi/hssf/view/SVTableCellRenderer.java @@ -160,8 +160,8 @@ public class SVTableCellRenderer extends JLabel SVTableUtils.getAWTColor(s.getRightBorderColor(), SVTableUtils.black), SVTableUtils.getAWTColor(s.getBottomBorderColor(), SVTableUtils.black), SVTableUtils.getAWTColor(s.getLeftBorderColor(), SVTableUtils.black), - s.getBorderTop(), s.getBorderRight(), - s.getBorderBottom(), s.getBorderLeft(), + s.getBorderTopEnum(), s.getBorderRightEnum(), + s.getBorderBottomEnum(), s.getBorderLeftEnum(), hasFocus); setBorder(cellBorder); isBorderSet=true; diff --git a/src/examples/src/org/apache/poi/ss/examples/ExcelComparator.java b/src/examples/src/org/apache/poi/ss/examples/ExcelComparator.java index dce4b0196..d6f846a6b 100644 --- a/src/examples/src/org/apache/poi/ss/examples/ExcelComparator.java +++ b/src/examples/src/org/apache/poi/ss/examples/ExcelComparator.java @@ -367,23 +367,23 @@ public class ExcelComparator { String borderName; switch (borderSide) { case 't': default: - b1 = style1.getBorderTop() == BorderStyle.THIN; - b2 = style2.getBorderTop() == BorderStyle.THIN; + b1 = style1.getBorderTopEnum() == BorderStyle.THIN; + b2 = style2.getBorderTopEnum() == BorderStyle.THIN; borderName = "TOP"; break; case 'b': - b1 = style1.getBorderBottom() == BorderStyle.THIN; - b2 = style2.getBorderBottom() == BorderStyle.THIN; + b1 = style1.getBorderBottomEnum() == BorderStyle.THIN; + b2 = style2.getBorderBottomEnum() == BorderStyle.THIN; borderName = "BOTTOM"; break; case 'l': - b1 = style1.getBorderLeft() == BorderStyle.THIN; - b2 = style2.getBorderLeft() == BorderStyle.THIN; + b1 = style1.getBorderLeftEnum() == BorderStyle.THIN; + b2 = style2.getBorderLeftEnum() == BorderStyle.THIN; borderName = "LEFT"; break; case 'r': - b1 = style1.getBorderRight() == BorderStyle.THIN; - b2 = style2.getBorderRight() == BorderStyle.THIN; + b1 = style1.getBorderRightEnum() == BorderStyle.THIN; + b2 = style2.getBorderRightEnum() == BorderStyle.THIN; borderName = "RIGHT"; break; } diff --git a/src/examples/src/org/apache/poi/ss/examples/html/ToHtml.java b/src/examples/src/org/apache/poi/ss/examples/html/ToHtml.java index c5fdc1da9..f5d2ecba8 100644 --- a/src/examples/src/org/apache/poi/ss/examples/html/ToHtml.java +++ b/src/examples/src/org/apache/poi/ss/examples/html/ToHtml.java @@ -298,10 +298,10 @@ public class ToHtml { } private void borderStyles(CellStyle style) { - styleOut("border-left", style.getBorderLeft(), BORDER); - styleOut("border-right", style.getBorderRight(), BORDER); - styleOut("border-top", style.getBorderTop(), BORDER); - styleOut("border-bottom", style.getBorderBottom(), BORDER); + styleOut("border-left", style.getBorderLeftEnum(), BORDER); + styleOut("border-right", style.getBorderRightEnum(), BORDER); + styleOut("border-top", style.getBorderTopEnum(), BORDER); + styleOut("border-bottom", style.getBorderBottomEnum(), BORDER); } private void fontStyle(CellStyle style) { diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java index 4fbbdf62e..0fd7cf2ad 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java @@ -331,6 +331,7 @@ public final class HSSFCellStyle implements CellStyle { * @see VerticalAlignment * @deprecated POI 3.15 beta 3. Use {@link #setVerticalAlignment(VerticalAlignment)} instead. */ + @Removal(version="3.17") @Override public void setVerticalAlignment(short align) { @@ -461,6 +462,7 @@ public final class HSSFCellStyle implements CellStyle { * @see #BORDER_SLANTED_DASH_DOT * @deprecated 3.15 beta 2. Use {@link HSSFCellStyle#setBorderLeft(BorderStyle)} instead. */ + @Removal(version="3.17") @Override public void setBorderLeft(short border) { @@ -471,6 +473,7 @@ public final class HSSFCellStyle implements CellStyle { /** * set the type of border to use for the left border of the cell * @param border type + * @since POI 3.15 */ @Override public void setBorderLeft(BorderStyle border) @@ -481,9 +484,20 @@ public final class HSSFCellStyle implements CellStyle { /** * get the type of border to use for the left border of the cell * @return border type + * @deprecated POI 3.15. Will return a BorderStyle enum in the future. Use {@link #getBorderLeftEnum()}. */ @Override - public BorderStyle getBorderLeft() + public short getBorderLeft() + { + return _format.getBorderLeft(); + } + /** + * get the type of border to use for the left border of the cell + * @return border type + * @since POI 3.15 + */ + @Override + public BorderStyle getBorderLeftEnum() { return BorderStyle.valueOf(_format.getBorderLeft()); } @@ -507,6 +521,7 @@ public final class HSSFCellStyle implements CellStyle { * @see #BORDER_SLANTED_DASH_DOT * @deprecated 3.15 beta 2. Use {@link HSSFCellStyle#setBorderRight(BorderStyle)} instead. */ + @Removal(version="3.17") @Override public void setBorderRight(short border) { @@ -517,6 +532,7 @@ public final class HSSFCellStyle implements CellStyle { /** * set the type of border to use for the right border of the cell * @param border type + * @since POI 3.15 */ @Override public void setBorderRight(BorderStyle border) @@ -527,9 +543,20 @@ public final class HSSFCellStyle implements CellStyle { /** * get the type of border to use for the right border of the cell * @return border type + * @deprecated POI 3.15. Will return a BorderStyle enum in the future. Use {@link #getBorderRightEnum()}. */ @Override - public BorderStyle getBorderRight() + public short getBorderRight() + { + return _format.getBorderRight(); + } + /** + * get the type of border to use for the right border of the cell + * @return border type + * @since POI 3.15 + */ + @Override + public BorderStyle getBorderRightEnum() { return BorderStyle.valueOf(_format.getBorderRight()); } @@ -553,6 +580,7 @@ public final class HSSFCellStyle implements CellStyle { * @see #BORDER_SLANTED_DASH_DOT * @deprecated 3.15 beta 2. Use {@link HSSFCellStyle#setBorderTop(BorderStyle)} instead. */ + @Removal(version="3.17") @Override public void setBorderTop(short border) { @@ -563,6 +591,7 @@ public final class HSSFCellStyle implements CellStyle { /** * set the type of border to use for the top border of the cell * @param border type + * @since POI 3.15 */ @Override public void setBorderTop(BorderStyle border) @@ -573,9 +602,20 @@ public final class HSSFCellStyle implements CellStyle { /** * get the type of border to use for the top border of the cell * @return border type + * @deprecated POI 3.15. Will return a BorderStyle enum in the future. Use {@link #getBorderTopEnum()}. */ @Override - public BorderStyle getBorderTop() + public short getBorderTop() + { + return _format.getBorderTop(); + } + /** + * get the type of border to use for the top border of the cell + * @return border type + * @since 3.15 + */ + @Override + public BorderStyle getBorderTopEnum() { return BorderStyle.valueOf(_format.getBorderTop()); } @@ -599,6 +639,7 @@ public final class HSSFCellStyle implements CellStyle { * @see #BORDER_SLANTED_DASH_DOT * @deprecated 3.15 beta 2. Use {@link HSSFCellStyle#setBorderBottom(BorderStyle)} instead. */ + @Removal(version="3.17") @Override public void setBorderBottom(short border) { @@ -609,6 +650,7 @@ public final class HSSFCellStyle implements CellStyle { /** * set the type of border to use for the bottom border of the cell * @param border type + * @since 3.15 beta 2 */ @Override public void setBorderBottom(BorderStyle border) @@ -619,9 +661,20 @@ public final class HSSFCellStyle implements CellStyle { /** * get the type of border to use for the bottom border of the cell * @return border type + * @deprecated POI 3.15. Will return a BorderStyle enum in the future. Use {@link #getBorderBottomEnum()}. */ @Override - public BorderStyle getBorderBottom() + public short getBorderBottom() + { + return _format.getBorderBottom(); + } + /** + * get the type of border to use for the bottom border of the cell + * @return border type + * @since 3.15 + */ + @Override + public BorderStyle getBorderBottomEnum() { return BorderStyle.valueOf(_format.getBorderBottom()); } @@ -735,6 +788,7 @@ public final class HSSFCellStyle implements CellStyle { * @param fp fill pattern (set to 1 to fill w/foreground color) * @deprecated POI 3.15 beta 3. Use {@link #setFillPattern(FillPatternType)} instead. */ + @Removal(version="3.17") @Override public void setFillPattern(short fp) { diff --git a/src/java/org/apache/poi/ss/usermodel/CellStyle.java b/src/java/org/apache/poi/ss/usermodel/CellStyle.java index 17a5d0e75..df3d57259 100644 --- a/src/java/org/apache/poi/ss/usermodel/CellStyle.java +++ b/src/java/org/apache/poi/ss/usermodel/CellStyle.java @@ -541,19 +541,29 @@ public interface CellStyle { * @see #BORDER_SLANTED_DASH_DOT * @deprecated 3.15 beta 2. Use {@link #setBorderLeft(BorderStyle)} instead */ + @Removal(version="3.17") void setBorderLeft(short border); /** * set the type of border to use for the left border of the cell * @param border type + * @since POI 3.15 */ void setBorderLeft(BorderStyle border); /** * get the type of border to use for the left border of the cell * @return border type + * @deprecated POI 3.15. Use {@link #getBorderLeftEnum()} instead. + * This will return a BorderStyle enum in the future. */ - BorderStyle getBorderLeft(); + short getBorderLeft(); + /** + * get the type of border to use for the left border of the cell + * @return border type + * @since POI 3.15 + */ + BorderStyle getBorderLeftEnum(); /** * set the type of border to use for the right border of the cell @@ -574,19 +584,29 @@ public interface CellStyle { * @see #BORDER_SLANTED_DASH_DOT * @deprecated 3.15 beta 2. Use {@link #setBorderRight(BorderStyle)} instead */ + @Removal(version="3.17") void setBorderRight(short border); /** * set the type of border to use for the right border of the cell * @param border type + * @since POI 3.15 */ void setBorderRight(BorderStyle border); /** * get the type of border to use for the right border of the cell * @return border type + * @deprecated POI 3.15. Use {@link #getBorderRightEnum()} instead. + * This will return a BorderStyle enum in the future. */ - BorderStyle getBorderRight(); + short getBorderRight(); + /** + * get the type of border to use for the right border of the cell + * @return border type + * @since POI 3.15 + */ + BorderStyle getBorderRightEnum(); /** * set the type of border to use for the top border of the cell @@ -607,19 +627,29 @@ public interface CellStyle { * @see #BORDER_SLANTED_DASH_DOT * @deprecated 3.15 beta 2. Use {@link #setBorderTop(BorderStyle)} instead */ + @Removal(version="3.17") void setBorderTop(short border); /** * set the type of border to use for the top border of the cell * @param border type + * @since POI 3.15 */ void setBorderTop(BorderStyle border); /** * get the type of border to use for the top border of the cell * @return border type + * @deprecated POI 3.15. Use {@link #getBorderTopEnum()} instead. + * This will return a BorderStyle enum in the future. */ - BorderStyle getBorderTop(); + short getBorderTop(); + /** + * get the type of border to use for the top border of the cell + * @return border type + * @since POI 3.15 + */ + BorderStyle getBorderTopEnum(); /** * set the type of border to use for the bottom border of the cell @@ -640,19 +670,29 @@ public interface CellStyle { * @see #BORDER_SLANTED_DASH_DOT * @deprecated 3.15 beta 2. Use {@link #setBorderBottom(BorderStyle)} instead. */ + @Removal(version="3.17") void setBorderBottom(short border); /** * set the type of border to use for the bottom border of the cell * @param border type + * @since POI 3.15 */ void setBorderBottom(BorderStyle border); /** * get the type of border to use for the bottom border of the cell * @return border type + * @deprecated POI 3.15. Use {@link #getBorderBottomEnum()} instead. + * This will return a BorderStyle enum in the future. */ - BorderStyle getBorderBottom(); + short getBorderBottom(); + /** + * get the type of border to use for the bottom border of the cell + * @return border type + * @since POI 3.15 + */ + BorderStyle getBorderBottomEnum(); /** * set the color to use for the left border diff --git a/src/java/org/apache/poi/ss/util/CellUtil.java b/src/java/org/apache/poi/ss/util/CellUtil.java index 4f446c10d..3dad83aab 100644 --- a/src/java/org/apache/poi/ss/util/CellUtil.java +++ b/src/java/org/apache/poi/ss/util/CellUtil.java @@ -405,10 +405,10 @@ public final class CellUtil { Map properties = new HashMap(); put(properties, ALIGNMENT, style.getAlignmentEnum()); put(properties, VERTICAL_ALIGNMENT, style.getVerticalAlignmentEnum()); - put(properties, BORDER_BOTTOM, style.getBorderBottom()); - put(properties, BORDER_LEFT, style.getBorderLeft()); - put(properties, BORDER_RIGHT, style.getBorderRight()); - put(properties, BORDER_TOP, style.getBorderTop()); + put(properties, BORDER_BOTTOM, style.getBorderBottomEnum()); + put(properties, BORDER_LEFT, style.getBorderLeftEnum()); + put(properties, BORDER_RIGHT, style.getBorderRightEnum()); + put(properties, BORDER_TOP, style.getBorderTopEnum()); put(properties, BOTTOM_BORDER_COLOR, style.getBottomBorderColor()); put(properties, DATA_FORMAT, style.getDataFormat()); put(properties, FILL_PATTERN, style.getFillPatternEnum()); diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java index 1e7dc5040..9eec21ec6 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java @@ -252,11 +252,13 @@ public class XSSFCellStyle implements CellStyle { /** * Get the type of border to use for the bottom border of the cell + * Will be removed when {@link #getBorderBottom()} returns a BorderStyle enum * * @return border type, default value is {@link org.apache.poi.ss.usermodel.BorderStyle#NONE} + * @since POI 3.15 */ @Override - public BorderStyle getBorderBottom() { + public BorderStyle getBorderBottomEnum() { if(!_cellXf.getApplyBorder()) return BorderStyle.NONE; int idx = (int)_cellXf.getBorderId(); @@ -267,24 +269,26 @@ public class XSSFCellStyle implements CellStyle { } return BorderStyle.valueOf((short)(ptrn.intValue() - 1)); } - /** * Get the type of border to use for the bottom border of the cell + * This will return a BorderStyle enum in the future. * - * @return border type as Java enum - * @deprecated 3.15 beta 2. Use {@link #getBorderBottom} + * @return border type code + * @deprecated 3.15 beta 2. Use {@link #getBorderBottomEnum()} */ - public BorderStyle getBorderBottomEnum() { - return getBorderBottom(); + public short getBorderBottom() { + return getBorderBottomEnum().getCode(); } /** * Get the type of border to use for the left border of the cell + * Will be removed when {@link #getBorderLeft()} returns a BorderStyle enum * * @return border type, default value is {@link org.apache.poi.ss.usermodel.BorderStyle#NONE} + * @since POI 3.15 */ @Override - public BorderStyle getBorderLeft() { + public BorderStyle getBorderLeftEnum() { if(!_cellXf.getApplyBorder()) return BorderStyle.NONE; int idx = (int)_cellXf.getBorderId(); @@ -298,21 +302,24 @@ public class XSSFCellStyle implements CellStyle { /** * Get the type of border to use for the left border of the cell + * This will return a BorderStyle enum in the future. * - * @return border type, default value is {@link org.apache.poi.ss.usermodel.BorderStyle#NONE} - * @deprecated 3.15 beta 2. Use {@link #getBorderLeft} + * @return border type code + * @deprecated 3.15 beta 2. Use {@link #getBorderLeftEnum()} */ - public BorderStyle getBorderLeftEnum() { - return getBorderLeft(); + public short getBorderLeft() { + return getBorderLeftEnum().getCode(); } /** * Get the type of border to use for the right border of the cell + * Will be removed when {@link #getBorderRight()} returns a BorderStyle enum * * @return border type, default value is {@link org.apache.poi.ss.usermodel.BorderStyle#NONE} + * @since POI 3.15 */ @Override - public BorderStyle getBorderRight() { + public BorderStyle getBorderRightEnum() { if(!_cellXf.getApplyBorder()) return BorderStyle.NONE; int idx = (int)_cellXf.getBorderId(); @@ -323,24 +330,26 @@ public class XSSFCellStyle implements CellStyle { } return BorderStyle.valueOf((short)(ptrn.intValue() - 1)); } - /** * Get the type of border to use for the right border of the cell + * This will return a BorderStyle enum in the future. * * @return border type, default value is {@link org.apache.poi.ss.usermodel.BorderStyle#NONE} - * @deprecated 3.15 beta 2. Use {@link #getBorderRight} + * @deprecated 3.15 beta 2. Use {@link #getBorderRightEnum()} instead */ - public BorderStyle getBorderRightEnum() { - return getBorderRight(); + public short getBorderRight() { + return getBorderRightEnum().getCode(); } /** * Get the type of border to use for the top border of the cell + * Will be removed when {@link #getBorderTop()} returns a BorderStyle enum * * @return border type, default value is {@link org.apache.poi.ss.usermodel.BorderStyle#NONE} + * @since POI 3.15 */ @Override - public BorderStyle getBorderTop() { + public BorderStyle getBorderTopEnum() { if(!_cellXf.getApplyBorder()) return BorderStyle.NONE; int idx = (int)_cellXf.getBorderId(); @@ -351,15 +360,15 @@ public class XSSFCellStyle implements CellStyle { } return BorderStyle.valueOf((short) (ptrn.intValue() - 1)); } - /** * Get the type of border to use for the top border of the cell + * This will return a BorderStyle enum in the future. * * @return border type, default value is {@link org.apache.poi.ss.usermodel.BorderStyle#NONE} - * @deprecated 3.15 beta 2. Use {@link #getBorderTop} + * @deprecated 3.15 beta 2. Use {@link #getBorderTopEnum()} instead. */ - public BorderStyle getBorderTopEnum() { - return getBorderTop(); + public short getBorderTop() { + return getBorderTopEnum().getCode(); } /** @@ -776,6 +785,7 @@ public class XSSFCellStyle implements CellStyle { * @see org.apache.poi.ss.usermodel.CellStyle#ALIGN_CENTER_SELECTION * @deprecated POI 3.15 beta 3. Use {@link #setAlignment(HorizontalAlignment)} instead. */ + @Removal(version="3.17") @Override public void setAlignment(short align) { setAlignment(HorizontalAlignment.forInt(align)); @@ -797,6 +807,7 @@ public class XSSFCellStyle implements CellStyle { * @param border the type of border to use * @deprecated 3.15 beta 2. Use {@link #setBorderBottom(BorderStyle)} */ + @Removal(version="3.17") @Override public void setBorderBottom(short border) { setBorderBottom(BorderStyle.valueOf(border)); @@ -807,6 +818,7 @@ public class XSSFCellStyle implements CellStyle { * * @param border - type of border to use * @see org.apache.poi.ss.usermodel.BorderStyle + * @since POI 3.15 */ @Override public void setBorderBottom(BorderStyle border) { @@ -826,6 +838,7 @@ public class XSSFCellStyle implements CellStyle { * @param border the type of border to use * @deprecated 3.15 beta 2. Use {@link #setBorderLeft(BorderStyle)} */ + @Removal(version="3.17") @Override public void setBorderLeft(short border) { setBorderLeft(BorderStyle.valueOf(border)); @@ -835,6 +848,7 @@ public class XSSFCellStyle implements CellStyle { * Set the type of border to use for the left border of the cell * * @param border the type of border to use + * @since POI 3.15 */ @Override public void setBorderLeft(BorderStyle border) { @@ -855,6 +869,7 @@ public class XSSFCellStyle implements CellStyle { * @param border the type of border to use * @deprecated 3.15 beta 2. Use {@link #setBorderRight(BorderStyle)} */ + @Removal(version="3.17") @Override public void setBorderRight(short border) { setBorderRight(BorderStyle.valueOf(border)); @@ -864,6 +879,7 @@ public class XSSFCellStyle implements CellStyle { * Set the type of border to use for the right border of the cell * * @param border the type of border to use + * @since POI 3.15 */ @Override public void setBorderRight(BorderStyle border) { @@ -884,6 +900,7 @@ public class XSSFCellStyle implements CellStyle { * @param border the type of border to use * @deprecated 3.15 beta 2. Use {@link #setBorderTop(BorderStyle)} */ + @Removal(version="3.17") @Override public void setBorderTop(short border) { setBorderTop(BorderStyle.valueOf(border)); @@ -893,6 +910,7 @@ public class XSSFCellStyle implements CellStyle { * Set the type of border to use for the top border of the cell * * @param border the type of border to use + * @since POI 3.15 */ @Override public void setBorderTop(BorderStyle border) { @@ -1338,6 +1356,7 @@ public class XSSFCellStyle implements CellStyle { * @see org.apache.poi.ss.usermodel.VerticalAlignment * @deprecated POI 3.15 beta 3. Use {@link #setVerticalAlignment(VerticalAlignment)} instead. */ + @Removal(version="3.17") @Override public void setVerticalAlignment(short align) { setVerticalAlignment(VerticalAlignment.forInt(align)); diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCellStyle.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCellStyle.java index 94e40a3a7..c907d40db 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCellStyle.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCellStyle.java @@ -104,11 +104,11 @@ public class TestXSSFCellStyle { @Test public void testGetSetBorderBottom() { //default values - assertEquals(BorderStyle.NONE, cellStyle.getBorderBottom()); + assertEquals(BorderStyle.NONE, cellStyle.getBorderBottomEnum()); int num = stylesTable.getBorders().size(); cellStyle.setBorderBottom(BorderStyle.MEDIUM); - assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderBottom()); + assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderBottomEnum()); //a new border has been added assertEquals(num + 1, stylesTable.getBorders().size()); //id of the created border @@ -122,7 +122,7 @@ public class TestXSSFCellStyle { //setting the same border multiple times should not change borderId for (int i = 0; i < 3; i++) { cellStyle.setBorderBottom(BorderStyle.MEDIUM); - assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderBottom()); + assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderBottomEnum()); } assertEquals(borderId, cellStyle.getCoreXf().getBorderId()); assertEquals(num, stylesTable.getBorders().size()); @@ -139,11 +139,11 @@ public class TestXSSFCellStyle { @Test public void testGetSetBorderRight() { //default values - assertEquals(BorderStyle.NONE, cellStyle.getBorderRight()); + assertEquals(BorderStyle.NONE, cellStyle.getBorderRightEnum()); int num = stylesTable.getBorders().size(); cellStyle.setBorderRight(BorderStyle.MEDIUM); - assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderRight()); + assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderRightEnum()); //a new border has been added assertEquals(num + 1, stylesTable.getBorders().size()); //id of the created border @@ -157,7 +157,7 @@ public class TestXSSFCellStyle { //setting the same border multiple times should not change borderId for (int i = 0; i < 3; i++) { cellStyle.setBorderRight(BorderStyle.MEDIUM); - assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderRight()); + assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderRightEnum()); } assertEquals(borderId, cellStyle.getCoreXf().getBorderId()); assertEquals(num, stylesTable.getBorders().size()); @@ -174,11 +174,11 @@ public class TestXSSFCellStyle { @Test public void testGetSetBorderLeft() { //default values - assertEquals(BorderStyle.NONE, cellStyle.getBorderLeft()); + assertEquals(BorderStyle.NONE, cellStyle.getBorderLeftEnum()); int num = stylesTable.getBorders().size(); cellStyle.setBorderLeft(BorderStyle.MEDIUM); - assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderLeft()); + assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderLeftEnum()); //a new border has been added assertEquals(num + 1, stylesTable.getBorders().size()); //id of the created border @@ -192,7 +192,7 @@ public class TestXSSFCellStyle { //setting the same border multiple times should not change borderId for (int i = 0; i < 3; i++) { cellStyle.setBorderLeft(BorderStyle.MEDIUM); - assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderLeft()); + assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderLeftEnum()); } assertEquals(borderId, cellStyle.getCoreXf().getBorderId()); assertEquals(num, stylesTable.getBorders().size()); @@ -209,11 +209,11 @@ public class TestXSSFCellStyle { @Test public void testGetSetBorderTop() { //default values - assertEquals(BorderStyle.NONE, cellStyle.getBorderTop()); + assertEquals(BorderStyle.NONE, cellStyle.getBorderTopEnum()); int num = stylesTable.getBorders().size(); cellStyle.setBorderTop(BorderStyle.MEDIUM); - assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderTop()); + assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderTopEnum()); //a new border has been added assertEquals(num + 1, stylesTable.getBorders().size()); //id of the created border @@ -227,7 +227,7 @@ public class TestXSSFCellStyle { //setting the same border multiple times should not change borderId for (int i = 0; i < 3; i++) { cellStyle.setBorderTop(BorderStyle.MEDIUM); - assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderTop()); + assertEquals(BorderStyle.MEDIUM, cellStyle.getBorderTopEnum()); } assertEquals(borderId, cellStyle.getCoreXf().getBorderId()); assertEquals(num, stylesTable.getBorders().size()); @@ -243,7 +243,7 @@ public class TestXSSFCellStyle { private void testGetSetBorderXMLBean(BorderStyle border, STBorderStyle.Enum expected) { cellStyle.setBorderTop(border); - assertEquals(border, cellStyle.getBorderTop()); + assertEquals(border, cellStyle.getBorderTopEnum()); int borderId = (int)cellStyle.getCoreXf().getBorderId(); assertTrue(borderId > 0); //check changes in the underlying xml bean @@ -256,7 +256,7 @@ public class TestXSSFCellStyle { @Test public void testGetSetBorderNone() { cellStyle.setBorderTop(BorderStyle.NONE); - assertEquals(BorderStyle.NONE, cellStyle.getBorderTop()); + assertEquals(BorderStyle.NONE, cellStyle.getBorderTopEnum()); int borderId = (int)cellStyle.getCoreXf().getBorderId(); assertTrue(borderId > 0); //check changes in the underlying xml bean @@ -562,10 +562,10 @@ public class TestXSSFCellStyle { assertEquals(style2.getRightBorderColor(), style1.getRightBorderColor()); assertEquals(style2.getBottomBorderColor(), style1.getBottomBorderColor()); - assertEquals(style2.getBorderBottom(), style1.getBorderBottom()); - assertEquals(style2.getBorderLeft(), style1.getBorderLeft()); - assertEquals(style2.getBorderRight(), style1.getBorderRight()); - assertEquals(style2.getBorderTop(), style1.getBorderTop()); + assertEquals(style2.getBorderBottomEnum(), style1.getBorderBottomEnum()); + assertEquals(style2.getBorderLeftEnum(), style1.getBorderLeftEnum()); + assertEquals(style2.getBorderRightEnum(), style1.getBorderRightEnum()); + assertEquals(style2.getBorderTopEnum(), style1.getBorderTopEnum()); wb2.close(); } @@ -999,7 +999,7 @@ public class TestXSSFCellStyle { Workbook copy = XSSFTestDataSamples.writeOutAndReadBack(target); // previously this failed because the border-element was not copied over - copy.getCellStyleAt((short)1).getBorderBottom(); + copy.getCellStyleAt((short)1).getBorderBottomEnum(); copy.close(); diff --git a/src/scratchpad/src/org/apache/poi/hssf/converter/ExcelToFoConverter.java b/src/scratchpad/src/org/apache/poi/hssf/converter/ExcelToFoConverter.java index 1c32edabe..29d7ffce0 100644 --- a/src/scratchpad/src/org/apache/poi/hssf/converter/ExcelToFoConverter.java +++ b/src/scratchpad/src/org/apache/poi/hssf/converter/ExcelToFoConverter.java @@ -193,10 +193,10 @@ public class ExcelToFoConverter extends AbstractExcelConverter protected boolean isEmptyStyle( CellStyle cellStyle ) { return cellStyle == null || ( cellStyle.getFillPattern() == 0 - && cellStyle.getBorderTop() == BorderStyle.NONE - && cellStyle.getBorderRight() == BorderStyle.NONE - && cellStyle.getBorderBottom() == BorderStyle.NONE - && cellStyle.getBorderLeft() == BorderStyle.NONE + && cellStyle.getBorderTopEnum() == BorderStyle.NONE + && cellStyle.getBorderRightEnum() == BorderStyle.NONE + && cellStyle.getBorderBottomEnum() == BorderStyle.NONE + && cellStyle.getBorderLeftEnum() == BorderStyle.NONE ); } @@ -361,13 +361,13 @@ public class ExcelToFoConverter extends AbstractExcelConverter } processCellStyleBorder( workbook, cellTarget, "top", - cellStyle.getBorderTop(), cellStyle.getTopBorderColor() ); + cellStyle.getBorderTopEnum(), cellStyle.getTopBorderColor() ); processCellStyleBorder( workbook, cellTarget, "right", - cellStyle.getBorderRight(), cellStyle.getRightBorderColor() ); + cellStyle.getBorderRightEnum(), cellStyle.getRightBorderColor() ); processCellStyleBorder( workbook, cellTarget, "bottom", - cellStyle.getBorderBottom(), cellStyle.getBottomBorderColor() ); + cellStyle.getBorderBottomEnum(), cellStyle.getBottomBorderColor() ); processCellStyleBorder( workbook, cellTarget, "left", - cellStyle.getBorderLeft(), cellStyle.getLeftBorderColor() ); + cellStyle.getBorderLeftEnum(), cellStyle.getLeftBorderColor() ); HSSFFont font = cellStyle.getFont( workbook ); processCellStyleFont( workbook, blockTarget, font ); diff --git a/src/scratchpad/src/org/apache/poi/hssf/converter/ExcelToHtmlConverter.java b/src/scratchpad/src/org/apache/poi/hssf/converter/ExcelToHtmlConverter.java index 54dc4d319..5019339d3 100644 --- a/src/scratchpad/src/org/apache/poi/hssf/converter/ExcelToHtmlConverter.java +++ b/src/scratchpad/src/org/apache/poi/hssf/converter/ExcelToHtmlConverter.java @@ -175,13 +175,13 @@ public class ExcelToHtmlConverter extends AbstractExcelConverter break; } - buildStyle_border( workbook, style, "top", cellStyle.getBorderTop(), + buildStyle_border( workbook, style, "top", cellStyle.getBorderTopEnum(), cellStyle.getTopBorderColor() ); buildStyle_border( workbook, style, "right", - cellStyle.getBorderRight(), cellStyle.getRightBorderColor() ); + cellStyle.getBorderRightEnum(), cellStyle.getRightBorderColor() ); buildStyle_border( workbook, style, "bottom", - cellStyle.getBorderBottom(), cellStyle.getBottomBorderColor() ); - buildStyle_border( workbook, style, "left", cellStyle.getBorderLeft(), + cellStyle.getBorderBottomEnum(), cellStyle.getBottomBorderColor() ); + buildStyle_border( workbook, style, "left", cellStyle.getBorderLeftEnum(), cellStyle.getLeftBorderColor() ); HSSFFont font = cellStyle.getFont( workbook ); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java index dca98f620..2ce6e1de8 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java @@ -2567,7 +2567,7 @@ public final class TestBugs extends BaseTestBugzillaIssues { HSSFSheet sheet = wb.getSheetAt(0); HSSFRow row = sheet.getRow(0); HSSFCellStyle rstyle = row.getRowStyle(); - assertEquals(BorderStyle.DOUBLE, rstyle.getBorderBottom()); + assertEquals(BorderStyle.DOUBLE, rstyle.getBorderBottomEnum()); wb.close(); } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestCellStyle.java b/src/testcases/org/apache/poi/hssf/usermodel/TestCellStyle.java index 7e6d8a3bc..eec69b211 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestCellStyle.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestCellStyle.java @@ -348,40 +348,40 @@ public final class TestCellStyle extends TestCase { HSSFCellStyle cs; cs = s.getRow(0).getCell(0).getCellStyle(); - assertEquals(BorderStyle.HAIR, cs.getBorderRight()); + assertEquals(BorderStyle.HAIR, cs.getBorderRightEnum()); cs = s.getRow(1).getCell(1).getCellStyle(); - assertEquals(BorderStyle.DOTTED, cs.getBorderRight()); + assertEquals(BorderStyle.DOTTED, cs.getBorderRightEnum()); cs = s.getRow(2).getCell(2).getCellStyle(); - assertEquals(BorderStyle.DASH_DOT_DOT, cs.getBorderRight()); + assertEquals(BorderStyle.DASH_DOT_DOT, cs.getBorderRightEnum()); cs = s.getRow(3).getCell(3).getCellStyle(); - assertEquals(BorderStyle.DASHED, cs.getBorderRight()); + assertEquals(BorderStyle.DASHED, cs.getBorderRightEnum()); cs = s.getRow(4).getCell(4).getCellStyle(); - assertEquals(BorderStyle.THIN, cs.getBorderRight()); + assertEquals(BorderStyle.THIN, cs.getBorderRightEnum()); cs = s.getRow(5).getCell(5).getCellStyle(); - assertEquals(BorderStyle.MEDIUM_DASH_DOT_DOT, cs.getBorderRight()); + assertEquals(BorderStyle.MEDIUM_DASH_DOT_DOT, cs.getBorderRightEnum()); cs = s.getRow(6).getCell(6).getCellStyle(); - assertEquals(BorderStyle.SLANTED_DASH_DOT, cs.getBorderRight()); + assertEquals(BorderStyle.SLANTED_DASH_DOT, cs.getBorderRightEnum()); cs = s.getRow(7).getCell(7).getCellStyle(); - assertEquals(BorderStyle.MEDIUM_DASH_DOT, cs.getBorderRight()); + assertEquals(BorderStyle.MEDIUM_DASH_DOT, cs.getBorderRightEnum()); cs = s.getRow(8).getCell(8).getCellStyle(); - assertEquals(BorderStyle.MEDIUM_DASHED, cs.getBorderRight()); + assertEquals(BorderStyle.MEDIUM_DASHED, cs.getBorderRightEnum()); cs = s.getRow(9).getCell(9).getCellStyle(); - assertEquals(BorderStyle.MEDIUM, cs.getBorderRight()); + assertEquals(BorderStyle.MEDIUM, cs.getBorderRightEnum()); cs = s.getRow(10).getCell(10).getCellStyle(); - assertEquals(BorderStyle.THICK, cs.getBorderRight()); + assertEquals(BorderStyle.THICK, cs.getBorderRightEnum()); cs = s.getRow(11).getCell(11).getCellStyle(); - assertEquals(BorderStyle.DOUBLE, cs.getBorderRight()); + assertEquals(BorderStyle.DOUBLE, cs.getBorderRightEnum()); } public void testShrinkToFit() { @@ -500,7 +500,7 @@ public final class TestCellStyle extends TestCase { newCell.setCellValue("2testtext2"); CellStyle newStyle = newCell.getCellStyle(); - assertEquals(BorderStyle.DOTTED, newStyle.getBorderBottom()); + assertEquals(BorderStyle.DOTTED, newStyle.getBorderBottomEnum()); assertEquals(Font.COLOR_RED, ((HSSFCellStyle)newStyle).getFont(wb).getColor()); // OutputStream out = new FileOutputStream("/tmp/56959.xls"); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFOptimiser.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFOptimiser.java index 059ab3f38..acb4974c1 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFOptimiser.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFOptimiser.java @@ -308,8 +308,8 @@ public final class TestHSSFOptimiser extends TestCase { // Check assertEquals(23, wb.getNumCellStyles()); - assertEquals(BorderStyle.THICK, r.getCell(0).getCellStyle().getBorderBottom()); - assertEquals(BorderStyle.DASH_DOT, r.getCell(1).getCellStyle().getBorderBottom()); - assertEquals(BorderStyle.THICK, r.getCell(2).getCellStyle().getBorderBottom()); + assertEquals(BorderStyle.THICK, r.getCell(0).getCellStyle().getBorderBottomEnum()); + assertEquals(BorderStyle.DASH_DOT, r.getCell(1).getCellStyle().getBorderBottomEnum()); + assertEquals(BorderStyle.THICK, r.getCell(2).getCellStyle().getBorderBottomEnum()); } } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestRowStyle.java b/src/testcases/org/apache/poi/hssf/usermodel/TestRowStyle.java index ba65d063a..35519d36c 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestRowStyle.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestRowStyle.java @@ -151,10 +151,10 @@ public final class TestRowStyle extends TestCase { assertNotNull("Row is not null", r); cs = r.getRowStyle(); - assertEquals("Bottom Border Style for row:", BorderStyle.THIN, cs.getBorderBottom()); - assertEquals("Left Border Style for row:", BorderStyle.THIN, cs.getBorderLeft()); - assertEquals("Right Border Style for row:", BorderStyle.THIN, cs.getBorderRight()); - assertEquals("Top Border Style for row:", BorderStyle.THIN, cs.getBorderTop()); + assertEquals("Bottom Border Style for row:", BorderStyle.THIN, cs.getBorderBottomEnum()); + assertEquals("Left Border Style for row:", BorderStyle.THIN, cs.getBorderLeftEnum()); + assertEquals("Right Border Style for row:", BorderStyle.THIN, cs.getBorderRightEnum()); + assertEquals("Top Border Style for row:", BorderStyle.THIN, cs.getBorderTopEnum()); assertEquals("FillForegroundColor for row:", 0xA, cs.getFillForegroundColor()); assertEquals("FillPattern for row:", 0x1, cs.getFillPattern()); diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestBorderStyle.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestBorderStyle.java index 5ea2280b2..2fd2c37bf 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestBorderStyle.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestBorderStyle.java @@ -73,10 +73,10 @@ public class BaseTestBorderStyle { protected void assertBorderStyleEquals(BorderStyle expected, Cell cell) { CellStyle style = cell.getCellStyle(); - assertEquals(expected, style.getBorderTop()); - assertEquals(expected, style.getBorderBottom()); - assertEquals(expected, style.getBorderLeft()); - assertEquals(expected, style.getBorderRight()); + assertEquals(expected, style.getBorderTopEnum()); + assertEquals(expected, style.getBorderBottomEnum()); + assertEquals(expected, style.getBorderLeftEnum()); + assertEquals(expected, style.getBorderRightEnum()); } } diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java index 406816958..a19cf6684 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java @@ -278,10 +278,10 @@ public abstract class BaseTestCell { assertNotNull("Formula Cell Style", cs); assertEquals("Font Index Matches", f.getIndex(), cs.getFontIndex()); - assertEquals("Top Border", BorderStyle.THIN, cs.getBorderTop()); - assertEquals("Left Border", BorderStyle.THIN, cs.getBorderLeft()); - assertEquals("Right Border", BorderStyle.THIN, cs.getBorderRight()); - assertEquals("Bottom Border", BorderStyle.THIN, cs.getBorderBottom()); + assertEquals("Top Border", BorderStyle.THIN, cs.getBorderTopEnum()); + assertEquals("Left Border", BorderStyle.THIN, cs.getBorderLeftEnum()); + assertEquals("Right Border", BorderStyle.THIN, cs.getBorderRightEnum()); + assertEquals("Bottom Border", BorderStyle.THIN, cs.getBorderBottomEnum()); wb2.close(); } diff --git a/src/testcases/org/apache/poi/ss/util/BaseTestCellUtil.java b/src/testcases/org/apache/poi/ss/util/BaseTestCellUtil.java index a63ce5a60..91c204da3 100644 --- a/src/testcases/org/apache/poi/ss/util/BaseTestCellUtil.java +++ b/src/testcases/org/apache/poi/ss/util/BaseTestCellUtil.java @@ -99,11 +99,11 @@ public class BaseTestCellUtil { // A valid BorderStyle constant, as a Short CellUtil.setCellStyleProperty(c, CellUtil.BORDER_BOTTOM, BorderStyle.DASH_DOT.getCode()); - assertEquals(BorderStyle.DASH_DOT, c.getCellStyle().getBorderBottom()); + assertEquals(BorderStyle.DASH_DOT, c.getCellStyle().getBorderBottomEnum()); // A valid BorderStyle constant, as an Enum CellUtil.setCellStyleProperty(c, CellUtil.BORDER_TOP, BorderStyle.MEDIUM_DASH_DOT); - assertEquals(BorderStyle.MEDIUM_DASH_DOT, c.getCellStyle().getBorderTop()); + assertEquals(BorderStyle.MEDIUM_DASH_DOT, c.getCellStyle().getBorderTopEnum()); wb.close(); } From ca78ec28785cef64b1c651b519cf3324efca0117 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 05:31:48 +0000 Subject: [PATCH 094/157] bug 58671: add @Removal annotation to deprecated fields git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760632 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/ss/usermodel/Row.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/java/org/apache/poi/ss/usermodel/Row.java b/src/java/org/apache/poi/ss/usermodel/Row.java index b17edcd30..f58775704 100644 --- a/src/java/org/apache/poi/ss/usermodel/Row.java +++ b/src/java/org/apache/poi/ss/usermodel/Row.java @@ -19,6 +19,8 @@ package org.apache.poi.ss.usermodel; import java.util.Iterator; +import org.apache.poi.util.Removal; + /** * High level representation of a row of a spreadsheet. */ @@ -240,8 +242,10 @@ public interface Row extends Iterable { CREATE_NULL_AS_BLANK(3); /** - * @deprecated as of POI 3.15-beta2, scheduled for removal in 3.17 - the id has no function and will be removed + * @deprecated as of POI 3.15-beta2, scheduled for removal in 3.17 - the id has no function and will be removed. + * The {@code id} is only kept only for backwards compatibility with applications that hard-coded the number */ + @Removal(version="3.17") @Deprecated public final int id; private MissingCellPolicy(int id) { @@ -254,6 +258,7 @@ public interface Row extends Iterable { * * @deprecated as of POI 3.15-beta2, scheduled for removal in 3.17 - use the MissingCellPolicy enum **/ + @Removal(version="3.17") @Deprecated public static final MissingCellPolicy RETURN_NULL_AND_BLANK = MissingCellPolicy.RETURN_NULL_AND_BLANK; /** @@ -261,6 +266,7 @@ public interface Row extends Iterable { * * @deprecated as of POI 3.15-beta2, scheduled for removal in 3.17 - use the MissingCellPolicy enum **/ + @Removal(version="3.17") @Deprecated public static final MissingCellPolicy RETURN_BLANK_AS_NULL = MissingCellPolicy.RETURN_BLANK_AS_NULL; /** @@ -268,6 +274,7 @@ public interface Row extends Iterable { * * @deprecated as of POI 3.15-beta2, scheduled for removal in 3.17 - use the MissingCellPolicy enum **/ + @Removal(version="3.17") @Deprecated public static final MissingCellPolicy CREATE_NULL_AS_BLANK = MissingCellPolicy.CREATE_NULL_AS_BLANK; From 430ea9abfd90574b123e5381978dbd75395563ca Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 05:41:40 +0000 Subject: [PATCH 095/157] bug 58190: add @since annotations to SlideShow.addPicture and findPicture git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760633 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/sl/usermodel/SlideShow.java | 3 +++ src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java | 3 +++ .../src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java | 3 +++ 3 files changed, 9 insertions(+) diff --git a/src/java/org/apache/poi/sl/usermodel/SlideShow.java b/src/java/org/apache/poi/sl/usermodel/SlideShow.java index e46ce243f..228925d1c 100644 --- a/src/java/org/apache/poi/sl/usermodel/SlideShow.java +++ b/src/java/org/apache/poi/sl/usermodel/SlideShow.java @@ -83,6 +83,7 @@ public interface SlideShow< * @param format The format of the picture. * * @return the picture data reference. + * @since 3.15 beta 1 */ PictureData addPicture(InputStream is, PictureType format) throws IOException; @@ -93,6 +94,7 @@ public interface SlideShow< * @param format The format of the picture. * * @return the picture data reference + * @since 3.15 beta 1 */ PictureData addPicture(File pict, PictureType format) throws IOException; @@ -101,6 +103,7 @@ public interface SlideShow< * * @param pictureData The picture data to find in the SlideShow * @return {@code null} if picture data is not found in this slideshow + * @since 3.15 beta 3 */ PictureData findPictureData(byte[] pictureData); diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java index fe969d36b..14b656b53 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java @@ -471,6 +471,7 @@ implements SlideShow { * @param format The format of the picture * * @return the picture data + * @since 3.15 beta 2 */ @Override public XSLFPictureData addPicture(InputStream is, PictureType format) throws IOException @@ -486,6 +487,7 @@ implements SlideShow { * @param format The format of the picture. * * @return the picture data + * @since 3.15 beta 2 */ @Override public XSLFPictureData addPicture(File pict, PictureType format) throws IOException @@ -507,6 +509,7 @@ implements SlideShow { * * @param pictureData The picture data to find in the SlideShow * @return {@code null} if picture data is not found in this slideshow + * @since 3.15 beta 2 */ @Override public XSLFPictureData findPictureData(byte[] pictureData) { diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java index ad0e5aa9a..a17c61143 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java @@ -804,6 +804,7 @@ public final class HSLFSlideShow implements SlideShow Date: Wed, 14 Sep 2016 05:51:52 +0000 Subject: [PATCH 096/157] bug 59791: add deprecation and removal annotations git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760634 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/ss/format/CellFormat.java | 32 +++++++++++-------- .../apache/poi/xssf/streaming/SXSSFCell.java | 3 ++ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/java/org/apache/poi/ss/format/CellFormat.java b/src/java/org/apache/poi/ss/format/CellFormat.java index e47d40c4f..bad849712 100644 --- a/src/java/org/apache/poi/ss/format/CellFormat.java +++ b/src/java/org/apache/poi/ss/format/CellFormat.java @@ -35,7 +35,6 @@ import org.apache.poi.ss.usermodel.ConditionalFormattingRule; import org.apache.poi.ss.usermodel.DataFormatter; import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.util.DateFormatConverter; -import org.apache.poi.util.Internal; /** * Format a value according to the standard Excel behavior. This "standard" is @@ -44,28 +43,35 @@ import org.apache.poi.util.Internal; *

* An Excel format has up to four parts, separated by semicolons. Each part * specifies what to do with particular kinds of values, depending on the number - * of parts given:

One part (example: [Green]#.##)
If the - * value is a number, display according to this one part (example: green text, - * with up to two decimal points). If the value is text, display it as is. - *
Two parts (example: [Green]#.##;[Red]#.##)
If the value is a - * positive number or zero, display according to the first part (example: green + * of parts given: + *
+ *
One part (example: [Green]#.##)
+ *
If the value is a number, display according to this one part (example: green text, + * with up to two decimal points). If the value is text, display it as is.
+ * + *
Two parts (example: [Green]#.##;[Red]#.##)
+ *
If the value is a positive number or zero, display according to the first part (example: green * text, with up to two decimal points); if it is a negative number, display * according to the second part (example: red text, with up to two decimal - * points). If the value is text, display it as is.
Three parts (example: - * [Green]#.##;[Black]#.##;[Red]#.##)
If the value is a positive + * points). If the value is text, display it as is.
+ * + *
Three parts (example: [Green]#.##;[Black]#.##;[Red]#.##)
+ *
If the value is a positive * number, display according to the first part (example: green text, with up to * two decimal points); if it is zero, display according to the second part * (example: black text, with up to two decimal points); if it is a negative * number, display according to the third part (example: red text, with up to - * two decimal points). If the value is text, display it as is.
Four parts - * (example: [Green]#.##;[Black]#.##;[Red]#.##;[@])
If the value is - * a positive number, display according to the first part (example: green text, + * two decimal points). If the value is text, display it as is.
+ * + *
Four parts (example: [Green]#.##;[Black]#.##;[Red]#.##;[@])
+ *
If the value is a positive number, display according to the first part (example: green text, * with up to two decimal points); if it is zero, display according to the * second part (example: black text, with up to two decimal points); if it is a * negative number, display according to the third part (example: red text, with * up to two decimal points). If the value is text, display according to the * fourth part (example: text in the cell's usual color, with the text value - * surround by brackets).
+ * surround by brackets).
+ *
*

* A given format part may specify a given Locale, by including something * like [$$-409] or [$£-809] or [$-40C]. These @@ -421,6 +427,7 @@ public class CellFormat { * @param cell The cell. * * @return The ultimate type of this cell. + * @deprecated POI 3.15. This will return a CellType enum in the future */ public static int ultimateType(Cell cell) { return ultimateTypeEnum(cell).getCode(); @@ -439,7 +446,6 @@ public class CellFormat { * @deprecated POI 3.15 beta 3 * Will be deleted when we make the CellType enum transition. See bug 59791. */ - @Internal(since="POI 3.15 beta 3") public static CellType ultimateTypeEnum(Cell cell) { CellType type = cell.getCellTypeEnum(); if (type == CellType.FORMULA) 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 6174af54b..99a4648a7 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java @@ -43,6 +43,7 @@ import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.NotImplemented; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; +import org.apache.poi.util.Removal; import org.apache.poi.xssf.usermodel.XSSFHyperlink; import org.apache.poi.xssf.usermodel.XSSFRichTextString; @@ -61,6 +62,8 @@ public class SXSSFCell implements Cell { * @deprecated POI 3.15 beta 3. * Will be deleted when we make the CellType enum transition. See bug 59791. */ + @Removal(version="3.17") + @Deprecated public SXSSFCell(SXSSFRow row, int cellType) { this(row, CellType.forInt((cellType))); From b0f814f83f6936846fab22a956202581fb8268ba Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 06:22:38 +0000 Subject: [PATCH 097/157] bug 59791: add deprecation warnings git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760639 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java | 1 - .../org/apache/poi/ss/formula/BaseFormulaEvaluator.java | 1 + src/java/org/apache/poi/ss/formula/EvaluationCell.java | 2 ++ .../poi/ss/formula/eval/forked/ForkedEvaluationCell.java | 4 ++-- src/java/org/apache/poi/ss/usermodel/Cell.java | 4 ++-- src/java/org/apache/poi/ss/usermodel/CreationHelper.java | 9 +++++---- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java index b43228740..7154d7450 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java @@ -155,7 +155,6 @@ public class HSSFFormulaEvaluator extends BaseFormulaEvaluator { * @since POI 3.15 beta 3 * @deprecated POI 3.15 beta 3. Will be deleted when we make the CellType enum transition. See bug 59791. */ - @Internal @Override public CellType evaluateFormulaCellEnum(Cell cell) { if (cell == null || cell.getCellTypeEnum() != CellType.FORMULA) { diff --git a/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java b/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java index fb0c4d68d..7c459abb4 100644 --- a/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java +++ b/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java @@ -125,6 +125,7 @@ public abstract class BaseFormulaEvaluator implements FormulaEvaluator, Workbook * replaced with the result of the formula, use {@link #evaluateInCell(org.apache.poi.ss.usermodel.Cell)} * @param cell The cell to evaluate * @return -1 for non-formula cells, or the type of the formula result + * @deprecated 3.15. Will return a {@link CellType} enum in the future. */ @Override public int evaluateFormulaCell(Cell cell) { diff --git a/src/java/org/apache/poi/ss/formula/EvaluationCell.java b/src/java/org/apache/poi/ss/formula/EvaluationCell.java index 3695fe280..a7e855c44 100644 --- a/src/java/org/apache/poi/ss/formula/EvaluationCell.java +++ b/src/java/org/apache/poi/ss/formula/EvaluationCell.java @@ -42,6 +42,7 @@ public interface EvaluationCell { * For forwards compatibility, do not hard-code cell type literals in your code. * * @return cell type + * @deprecated 3.15. Will return a {@link CellType} enum in the future. */ int getCellType(); /** @@ -61,6 +62,7 @@ public interface EvaluationCell { * For forwards compatibility, do not hard-code cell type literals in your code. * * @return cell type of cached formula result + * @deprecated 3.15. Will return a {@link CellType} enum in the future. */ int getCachedFormulaResultType(); /** diff --git a/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationCell.java b/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationCell.java index 0521e0889..db01b0640 100644 --- a/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationCell.java +++ b/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationCell.java @@ -108,6 +108,7 @@ final class ForkedEvaluationCell implements EvaluationCell { * For forwards compatibility, do not hard-code cell type literals in your code. * * @return cell type + * @deprecated 3.15. Will return a {@link CellType} enum in the future. */ @Override public int getCellType() { @@ -118,7 +119,6 @@ final class ForkedEvaluationCell implements EvaluationCell { * @deprecated POI 3.15 beta 3. * Will be deleted when we make the CellType enum transition. See bug 59791. */ - @Internal(since="POI 3.15 beta 3") @Override public CellType getCellTypeEnum() { return _cellType; @@ -160,6 +160,7 @@ final class ForkedEvaluationCell implements EvaluationCell { * For forwards compatibility, do not hard-code cell type literals in your code. * * @return cell type of cached formula result + * @deprecated 3.15. Will return a {@link CellType} enum in the future. */ @Override public int getCachedFormulaResultType() { @@ -170,7 +171,6 @@ final class ForkedEvaluationCell implements EvaluationCell { * @deprecated POI 3.15 beta 3. * Will be deleted when we make the CellType enum transition. See bug 59791. */ - @Internal(since="POI 3.15 beta 3") @Override public CellType getCachedFormulaResultTypeEnum() { return _masterCell.getCachedFormulaResultTypeEnum(); diff --git a/src/java/org/apache/poi/ss/usermodel/Cell.java b/src/java/org/apache/poi/ss/usermodel/Cell.java index 48b74789a..13d860823 100644 --- a/src/java/org/apache/poi/ss/usermodel/Cell.java +++ b/src/java/org/apache/poi/ss/usermodel/Cell.java @@ -167,6 +167,7 @@ public interface Cell { * For forwards compatibility, do not hard-code cell type literals in your code. * * @return the cell type + * @deprecated POI 3.15. Will return a {@link CellType} enum in the future. */ int getCellType(); @@ -178,7 +179,6 @@ public interface Cell { * @deprecated POI 3.15 beta 3 * Will be renamed to getCellType() when we make the CellType enum transition in POI 4.0. See bug 59791. */ - @Internal(since="POI 3.15 beta 3") @Removal(version="4.2") CellType getCellTypeEnum(); @@ -191,6 +191,7 @@ public interface Cell { * @return one of ({@link CellType#NUMERIC}, {@link CellType#STRING}, * {@link CellType#BOOLEAN}, {@link CellType#ERROR}) depending * on the cached value of the formula + * @deprecated 3.15. Will return a {@link CellType} enum in the future. */ int getCachedFormulaResultType(); @@ -203,7 +204,6 @@ public interface Cell { * @deprecated POI 3.15 beta 3 * Will be renamed to getCachedFormulaResultType() when we make the CellType enum transition in POI 4.0. See bug 59791. */ - @Internal(since="POI 3.15 beta 3") CellType getCachedFormulaResultTypeEnum(); /** diff --git a/src/java/org/apache/poi/ss/usermodel/CreationHelper.java b/src/java/org/apache/poi/ss/usermodel/CreationHelper.java index 25e1cdaae..53462c1d4 100644 --- a/src/java/org/apache/poi/ss/usermodel/CreationHelper.java +++ b/src/java/org/apache/poi/ss/usermodel/CreationHelper.java @@ -17,18 +17,18 @@ package org.apache.poi.ss.usermodel; import org.apache.poi.common.usermodel.HyperlinkType; +import org.apache.poi.util.Removal; /** * An object that handles instantiating concrete * classes of the various instances one needs for * HSSF and XSSF. - * Works around a major shortcoming in Java, where we - * can't have static methods on interfaces or abstract + * Works around a limitation in Java where we + * cannot have static methods on interfaces or abstract * classes. * This allows you to get the appropriate class for * a given interface, without you having to worry - * about if you're dealing with HSSF or XSSF, despite - * Java being quite rubbish. + * about if you're dealing with HSSF or XSSF. */ public interface CreationHelper { /** @@ -46,6 +46,7 @@ public interface CreationHelper { * Creates a new Hyperlink, of the given type * @deprecated POI 3.15 beta 3. Use {@link #createHyperlink(HyperlinkType)} instead. */ + @Removal(version="3.17") @Deprecated Hyperlink createHyperlink(int type); From f71ae8036d555757eb397de5452f86c79a1e6501 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 06:42:20 +0000 Subject: [PATCH 098/157] bug 59791: add deprecation and removal annotations git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760641 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/hssf/usermodel/HSSFCell.java | 4 ++-- .../org/apache/poi/hssf/usermodel/HSSFEvaluationCell.java | 4 ++-- .../apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java | 2 -- src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java | 3 ++- .../org/apache/poi/xssf/usermodel/XSSFEvaluationCell.java | 2 +- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java index 44427fce7..cfe998e05 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java @@ -446,6 +446,7 @@ public class HSSFCell implements Cell { * * Will return {@link CellType} in a future version of POI. * For forwards compatibility, do not hard-code cell type literals in your code. + * @deprecated 3.15. Will be return a {@link CellType} enum in the future. */ @Override public int getCellType() @@ -459,7 +460,6 @@ public class HSSFCell implements Cell { * @deprecated POI 3.15 beta 3 * Will be deleted when we make the CellType enum transition. See bug 59791. */ - @Internal(since="POI 3.15 beta 3") @Override public CellType getCellTypeEnum() { @@ -1154,6 +1154,7 @@ public class HSSFCell implements Cell { * @return one of ({@link CellType#NUMERIC}, {@link CellType#STRING}, * {@link CellType#BOOLEAN}, {@link CellType#ERROR}) depending * on the cached value of the formula + * @deprecated 3.15. Will return a {@link CellType} enum in the future. */ @Override public int getCachedFormulaResultType() { @@ -1169,7 +1170,6 @@ public class HSSFCell implements Cell { * @deprecated POI 3.15 beta 3 * Will be deleted when we make the CellType enum transition. See bug 59791. */ - @Internal(since="POI 3.15 beta 3") @Override public CellType getCachedFormulaResultTypeEnum() { if (_cellType != CellType.FORMULA) { diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationCell.java index b524cc149..1771b2e35 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationCell.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationCell.java @@ -55,6 +55,7 @@ final class HSSFEvaluationCell implements EvaluationCell { * For forwards compatibility, do not hard-code cell type literals in your code. * * @return cell type + * @deprecated 3.15. Will return a {@link CellType} enum in the future. */ @Override public int getCellType() { @@ -65,7 +66,6 @@ final class HSSFEvaluationCell implements EvaluationCell { * @deprecated POI 3.15 beta 3. * Will be deleted when we make the CellType enum transition. See bug 59791. */ - @Internal(since="POI 3.15 beta 3") @Override public CellType getCellTypeEnum() { return _cell.getCellTypeEnum(); @@ -99,6 +99,7 @@ final class HSSFEvaluationCell implements EvaluationCell { * For forwards compatibility, do not hard-code cell type literals in your code. * * @return cell type of cached formula result + * @deprecated 3.15. Will return a {@link CellType} enum in the future. */ @Override public int getCachedFormulaResultType() { @@ -109,7 +110,6 @@ final class HSSFEvaluationCell implements EvaluationCell { * @deprecated POI 3.15 beta 3. * Will be deleted when we make the CellType enum transition. See bug 59791. */ - @Internal(since="POI 3.15 beta 3") @Override public CellType getCachedFormulaResultTypeEnum() { return _cell.getCachedFormulaResultTypeEnum(); diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java index 726ae87e4..e5bd1a27c 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java @@ -28,7 +28,6 @@ import org.apache.poi.ss.formula.eval.ValueEval; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.CellValue; -import org.apache.poi.util.Internal; /** * Internal POI use only - parent of XSSF and SXSSF formula evaluators @@ -69,7 +68,6 @@ public abstract class BaseXSSFFormulaEvaluator extends BaseFormulaEvaluator { * @since POI 3.15 beta 3 * @deprecated POI 3.15 beta 3. Will be deleted when we make the CellType enum transition. See bug 59791. */ - @Internal(since="POI 3.15 beta 3") public CellType evaluateFormulaCellEnum(Cell cell) { if (cell == null || cell.getCellTypeEnum() != CellType.FORMULA) { return CellType._NONE; 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 4aa2f037e..7d2d6d25b 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java @@ -668,6 +668,7 @@ public final class XSSFCell implements Cell { * For forwards compatibility, do not hard-code cell type literals in your code. * * @return the cell type + * @deprecated 3.15. Will return a {@link CellType} enum in the future. */ @Override public int getCellType() { @@ -699,6 +700,7 @@ public final class XSSFCell implements Cell { * @return one of ({@link CellType#NUMERIC}, {@link CellType#STRING}, * {@link CellType#BOOLEAN}, {@link CellType#ERROR}) depending * on the cached value of the formula + * @deprecated 3.15. Will return a {@link CellType} enum in the future. */ @Override public int getCachedFormulaResultType() { @@ -714,7 +716,6 @@ public final class XSSFCell implements Cell { * @deprecated POI 3.15 beta 3 * Will be deleted when we make the CellType enum transition. See bug 59791. */ - @Internal(since="POI 3.15 beta 3") @Override public CellType getCachedFormulaResultTypeEnum() { if (! isFormulaCell()) { diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationCell.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationCell.java index e85b58017..129052e79 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationCell.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationCell.java @@ -58,6 +58,7 @@ final class XSSFEvaluationCell implements EvaluationCell { * For forwards compatibility, do not hard-code cell type literals in your code. * * @return cell type + * @deprecated 3.15. Will return a {@link CellType} enum in the future. */ @Override public int getCellType() { @@ -68,7 +69,6 @@ final class XSSFEvaluationCell implements EvaluationCell { * @deprecated POI 3.15 beta 3. * Will be deleted when we make the CellType enum transition. See bug 59791. */ - @Internal(since="POI 3.15 beta 3") @Override public CellType getCellTypeEnum() { return _cell.getCellTypeEnum(); From 8842d7bffdb76d9d774b91fbfd3b1e336a0b2a55 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 07:33:20 +0000 Subject: [PATCH 099/157] move BaseXSSFFormulaEvaluator#evaluateFormulaCellEnum(Cell) and HSSFFormulaEvaluator#evaluateFormulaCellEnum(Cell) up to BaseFormulaEvaluator class to reduce duplicated code git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760647 13f79535-47bb-0310-9956-ffa450edef68 --- .../hssf/usermodel/HSSFFormulaEvaluator.java | 60 ++---------------- .../poi/ss/formula/BaseFormulaEvaluator.java | 62 +++++++++++++++++++ .../poi/ss/usermodel/FormulaEvaluator.java | 1 + .../usermodel/BaseXSSFFormulaEvaluator.java | 60 ++---------------- 4 files changed, 74 insertions(+), 109 deletions(-) diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java index 7154d7450..7eb1cfc5f 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java @@ -33,9 +33,8 @@ import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.CellValue; import org.apache.poi.ss.usermodel.FormulaEvaluator; +import org.apache.poi.ss.usermodel.RichTextString; import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.util.Internal; -import org.apache.poi.util.Removal; /** * Evaluates formula cells.

@@ -82,6 +81,11 @@ public class HSSFFormulaEvaluator extends BaseFormulaEvaluator { public static HSSFFormulaEvaluator create(HSSFWorkbook workbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) { return new HSSFFormulaEvaluator(workbook, stabilityClassifier, udfFinder); } + + @Override + protected RichTextString createRichTextString(String str) { + return new HSSFRichTextString(str); + } /** @@ -138,34 +142,6 @@ public class HSSFFormulaEvaluator extends BaseFormulaEvaluator { _bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell((HSSFCell)cell)); } - /** - * If cell contains formula, it evaluates the formula, and saves the result of the formula. The - * cell remains as a formula cell. If the cell does not contain formula, rather than throwing an - * exception, this method returns {@link CellType#_NONE} and leaves the cell unchanged. - * - * Note that the type of the formula result is returned, so you know what kind of - * cached formula result is also stored with the formula. - *

-     * CellType evaluatedCellType = evaluator.evaluateFormulaCell(cell);
-     * 
- * Be aware that your cell will hold both the formula, and the result. If you want the cell - * replaced with the result of the formula, use {@link #evaluateInCell(org.apache.poi.ss.usermodel.Cell)} - * @param cell The cell to evaluate - * @return {@link CellType#_NONE} for non-formula cells, or the type of the formula result - * @since POI 3.15 beta 3 - * @deprecated POI 3.15 beta 3. Will be deleted when we make the CellType enum transition. See bug 59791. - */ - @Override - public CellType evaluateFormulaCellEnum(Cell cell) { - if (cell == null || cell.getCellTypeEnum() != CellType.FORMULA) { - return CellType._NONE; - } - CellValue cv = evaluateFormulaCellValue(cell); - // cell remains a formula cell, but the cached value is changed - setCellValue(cell, cv); - return cv.getCellTypeEnum(); - } - /** * If cell contains formula, it evaluates the formula, and * puts the formula result back into the cell, in place @@ -195,30 +171,6 @@ public class HSSFFormulaEvaluator extends BaseFormulaEvaluator { return result; } - private static void setCellValue(Cell cell, CellValue cv) { - CellType cellType = cv.getCellTypeEnum(); - switch (cellType) { - case BOOLEAN: - cell.setCellValue(cv.getBooleanValue()); - break; - case ERROR: - cell.setCellErrorValue(cv.getErrorValue()); - break; - case NUMERIC: - cell.setCellValue(cv.getNumberValue()); - break; - case STRING: - cell.setCellValue(new HSSFRichTextString(cv.getStringValue())); - break; - case BLANK: - // never happens - blanks eventually get translated to zero - case FORMULA: - // this will never happen, we have already evaluated the formula - default: - throw new IllegalStateException("Unexpected cell value type (" + cellType + ")"); - } - } - /** * Loops over all cells in all sheets of the supplied * workbook. diff --git a/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java b/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java index 7c459abb4..c52c41f9b 100644 --- a/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java +++ b/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java @@ -19,10 +19,13 @@ package org.apache.poi.ss.formula; import java.util.Map; +import org.apache.poi.hssf.usermodel.HSSFRichTextString; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.CellValue; +import org.apache.poi.ss.usermodel.CreationHelper; import org.apache.poi.ss.usermodel.FormulaEvaluator; +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; @@ -131,6 +134,38 @@ public abstract class BaseFormulaEvaluator implements FormulaEvaluator, Workbook public int evaluateFormulaCell(Cell cell) { return evaluateFormulaCellEnum(cell).getCode(); } + + /** + * If cell contains formula, it evaluates the formula, + * and saves the result of the formula. The cell + * remains as a formula cell. + * Else if cell does not contain formula, this method leaves + * the cell unchanged. + * Note that the type of the formula result is returned, + * so you know what kind of value is also stored with + * the formula. + *
+     * CellType evaluatedCellType = evaluator.evaluateFormulaCellEnum(cell);
+     * 
+ * Be aware that your cell will hold both the formula, + * and the result. If you want the cell replaced with + * the result of the formula, use {@link #evaluate(org.apache.poi.ss.usermodel.Cell)} } + * @param cell The cell to evaluate + * @return The type of the formula result (the cell's type remains as CellType.FORMULA however) + * If cell is not a formula cell, returns {@link CellType#_NONE} rather than throwing an exception. + * @since POI 3.15 beta 3 + * @deprecated POI 3.15 beta 3. Will be deleted when we make the CellType enum transition. See bug 59791. + */ + @Override + public CellType evaluateFormulaCellEnum(Cell cell) { + if (cell == null || cell.getCellTypeEnum() != CellType.FORMULA) { + return CellType._NONE; + } + CellValue cv = evaluateFormulaCellValue(cell); + // cell remains a formula cell, but the cached value is changed + setCellValue(cell, cv); + return cv.getCellTypeEnum(); + } protected static void setCellType(Cell cell, CellValue cv) { CellType cellType = cv.getCellTypeEnum(); @@ -151,6 +186,33 @@ public abstract class BaseFormulaEvaluator implements FormulaEvaluator, Workbook throw new IllegalStateException("Unexpected cell value type (" + cellType + ")"); } } + + protected abstract RichTextString createRichTextString(String str); + + protected void setCellValue(Cell cell, CellValue cv) { + CellType cellType = cv.getCellTypeEnum(); + switch (cellType) { + case BOOLEAN: + cell.setCellValue(cv.getBooleanValue()); + break; + case ERROR: + cell.setCellErrorValue(cv.getErrorValue()); + break; + case NUMERIC: + cell.setCellValue(cv.getNumberValue()); + break; + case STRING: + cell.setCellValue(createRichTextString(cv.getStringValue())); + break; + case BLANK: + // never happens - blanks eventually get translated to zero + case FORMULA: + // this will never happen, we have already evaluated the formula + default: + throw new IllegalStateException("Unexpected cell value type (" + cellType + ")"); + } + } + /** * Loops over all cells in all sheets of the supplied diff --git a/src/java/org/apache/poi/ss/usermodel/FormulaEvaluator.java b/src/java/org/apache/poi/ss/usermodel/FormulaEvaluator.java index be75ff9d5..357bd073a 100644 --- a/src/java/org/apache/poi/ss/usermodel/FormulaEvaluator.java +++ b/src/java/org/apache/poi/ss/usermodel/FormulaEvaluator.java @@ -101,6 +101,7 @@ public interface FormulaEvaluator { * or one of {@link CellType#NUMERIC}, {@link CellType#STRING}, * {@link CellType#BOOLEAN}, {@link CellType#ERROR} * Note: the cell's type remains as CellType.FORMULA however. + * @deprecated 3.15. Will return a {@link CellType} enum in the future */ int evaluateFormulaCell(Cell cell); diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java index e5bd1a27c..3c72dfe79 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java @@ -28,6 +28,7 @@ import org.apache.poi.ss.formula.eval.ValueEval; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.CellValue; +import org.apache.poi.ss.usermodel.RichTextString; /** * Internal POI use only - parent of XSSF and SXSSF formula evaluators @@ -36,6 +37,10 @@ public abstract class BaseXSSFFormulaEvaluator extends BaseFormulaEvaluator { protected BaseXSSFFormulaEvaluator(WorkbookEvaluator bookEvaluator) { super(bookEvaluator); } + @Override + protected RichTextString createRichTextString(String str) { + return new XSSFRichTextString(str); + } public void notifySetFormula(Cell cell) { _bookEvaluator.notifyUpdateCell(new XSSFEvaluationCell((XSSFCell)cell)); @@ -47,37 +52,6 @@ public abstract class BaseXSSFFormulaEvaluator extends BaseFormulaEvaluator { _bookEvaluator.notifyUpdateCell(new XSSFEvaluationCell((XSSFCell)cell)); } - /** - * If cell contains formula, it evaluates the formula, - * and saves the result of the formula. The cell - * remains as a formula cell. - * Else if cell does not contain formula, this method leaves - * the cell unchanged. - * Note that the type of the formula result is returned, - * so you know what kind of value is also stored with - * the formula. - *
-     * CellType evaluatedCellType = evaluator.evaluateFormulaCellEnum(cell);
-     * 
- * Be aware that your cell will hold both the formula, - * and the result. If you want the cell replaced with - * the result of the formula, use {@link #evaluate(org.apache.poi.ss.usermodel.Cell)} } - * @param cell The cell to evaluate - * @return The type of the formula result (the cell's type remains as CellType.FORMULA however) - * If cell is not a formula cell, returns {@link CellType#_NONE} rather than throwing an exception. - * @since POI 3.15 beta 3 - * @deprecated POI 3.15 beta 3. Will be deleted when we make the CellType enum transition. See bug 59791. - */ - public CellType evaluateFormulaCellEnum(Cell cell) { - if (cell == null || cell.getCellTypeEnum() != CellType.FORMULA) { - return CellType._NONE; - } - CellValue cv = evaluateFormulaCellValue(cell); - // cell remains a formula cell, but the cached value is changed - setCellValue(cell, cv); - return cv.getCellTypeEnum(); - } - /** * If cell contains formula, it evaluates the formula, and * puts the formula result back into the cell, in place @@ -94,30 +68,6 @@ public abstract class BaseXSSFFormulaEvaluator extends BaseFormulaEvaluator { } } - private static void setCellValue(Cell cell, CellValue cv) { - CellType cellType = cv.getCellTypeEnum(); - switch (cellType) { - case BOOLEAN: - cell.setCellValue(cv.getBooleanValue()); - break; - case ERROR: - cell.setCellErrorValue(cv.getErrorValue()); - break; - case NUMERIC: - cell.setCellValue(cv.getNumberValue()); - break; - case STRING: - cell.setCellValue(new XSSFRichTextString(cv.getStringValue())); - break; - case BLANK: - // never happens - blanks eventually get translated to zero - case FORMULA: - // this will never happen, we have already evaluated the formula - default: - throw new IllegalStateException("Unexpected cell value type (" + cellType + ")"); - } - } - /** * Turns a XSSFCell / SXSSFCell into a XSSFEvaluationCell */ From ed7258906f625a311b51c3e2e93f896af8a4ed88 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 07:53:58 +0000 Subject: [PATCH 100/157] move HSSFFormulaEvaluator#evaluateInCell and BaseXSSFFormulaEvaluator#evaluateInCell(Cell) up to BaseFormulaEvaluator to reduce duplicated code git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760651 13f79535-47bb-0310-9956-ffa450edef68 --- .../hssf/usermodel/HSSFFormulaEvaluator.java | 29 ++-------------- .../poi/ss/formula/BaseFormulaEvaluator.java | 33 +++++++++++++++++-- .../xssf/streaming/SXSSFFormulaEvaluator.java | 19 ++--------- .../usermodel/BaseXSSFFormulaEvaluator.java | 16 --------- .../xssf/usermodel/XSSFFormulaEvaluator.java | 29 +++++----------- .../usermodel/TestXSSFFormulaEvaluation.java | 11 +++++++ .../usermodel/BaseTestFormulaEvaluator.java | 12 +++++++ 7 files changed, 66 insertions(+), 83 deletions(-) diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java index 7eb1cfc5f..20c7ffa1e 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java @@ -30,7 +30,6 @@ import org.apache.poi.ss.formula.eval.StringValueEval; import org.apache.poi.ss.formula.eval.ValueEval; import org.apache.poi.ss.formula.udf.UDFFinder; import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.CellValue; import org.apache.poi.ss.usermodel.FormulaEvaluator; import org.apache.poi.ss.usermodel.RichTextString; @@ -141,34 +140,10 @@ public class HSSFFormulaEvaluator extends BaseFormulaEvaluator { public void notifySetFormula(Cell cell) { _bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell((HSSFCell)cell)); } - - /** - * If cell contains formula, it evaluates the formula, and - * puts the formula result back into the cell, in place - * of the old formula. - * Else if cell does not contain formula, this method leaves - * the cell unchanged. - * Note that the same instance of HSSFCell is returned to - * allow chained calls like: - *
-     * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
-     * 
- * Be aware that your cell value will be changed to hold the - * result of the formula. If you simply want the formula - * value computed for you, use {@link #evaluateFormulaCellEnum(Cell)}} - */ + @Override public HSSFCell evaluateInCell(Cell cell) { - if (cell == null) { - return null; - } - HSSFCell result = (HSSFCell) cell; - if (cell.getCellTypeEnum() == CellType.FORMULA) { - CellValue cv = evaluateFormulaCellValue(cell); - setCellValue(cell, cv); - setCellType(cell, cv); // cell will no longer be a formula cell - } - return result; + return (HSSFCell) super.evaluateInCell(cell); } /** diff --git a/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java b/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java index c52c41f9b..6cd19f5bf 100644 --- a/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java +++ b/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java @@ -19,11 +19,9 @@ package org.apache.poi.ss.formula; import java.util.Map; -import org.apache.poi.hssf.usermodel.HSSFRichTextString; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.CellValue; -import org.apache.poi.ss.usermodel.CreationHelper; import org.apache.poi.ss.usermodel.FormulaEvaluator; import org.apache.poi.ss.usermodel.RichTextString; import org.apache.poi.ss.usermodel.Row; @@ -111,6 +109,37 @@ public abstract class BaseFormulaEvaluator implements FormulaEvaluator, Workbook throw new IllegalStateException("Bad cell type (" + cell.getCellTypeEnum() + ")"); } } + + /** + * If cell contains formula, it evaluates the formula, and + * puts the formula result back into the cell, in place + * of the old formula. + * Else if cell does not contain formula, this method leaves + * the cell unchanged. + * Note that the same instance of HSSFCell is returned to + * allow chained calls like: + *
+     * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
+     * 
+ * Be aware that your cell value will be changed to hold the + * result of the formula. If you simply want the formula + * value computed for you, use {@link #evaluateFormulaCellEnum(Cell)}} + * @param cell + * @return the {@code cell} that was passed in, allowing for chained calls + */ + @Override + public Cell evaluateInCell(Cell cell) { + if (cell == null) { + return null; + } + Cell result = cell; + if (cell.getCellTypeEnum() == CellType.FORMULA) { + CellValue cv = evaluateFormulaCellValue(cell); + setCellValue(cell, cv); + setCellType(cell, cv); // cell will no longer be a formula cell + } + return result; + } protected abstract CellValue evaluateFormulaCellValue(Cell cell); diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFFormulaEvaluator.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFFormulaEvaluator.java index ac72bc7f3..0ac776ffc 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFFormulaEvaluator.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFFormulaEvaluator.java @@ -72,24 +72,9 @@ public final class SXSSFFormulaEvaluator extends BaseXSSFFormulaEvaluator { return new SXSSFEvaluationCell((SXSSFCell)cell); } - /** - * If cell contains formula, it evaluates the formula, and - * puts the formula result back into the cell, in place - * of the old formula. - * Else if cell does not contain formula, this method leaves - * the cell unchanged. - * Note that the same instance of SXSSFCell is returned to - * allow chained calls like: - *
-     * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
-     * 
- * Be aware that your cell value will be changed to hold the - * result of the formula. If you simply want the formula - * value computed for you, use {@link #evaluateFormulaCellEnum(org.apache.poi.ss.usermodel.Cell)} } - */ + @Override public SXSSFCell evaluateInCell(Cell cell) { - doEvaluateInCell(cell); - return (SXSSFCell)cell; + return (SXSSFCell) super.evaluateInCell(cell); } /** diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java index 3c72dfe79..780126c3d 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java @@ -52,22 +52,6 @@ public abstract class BaseXSSFFormulaEvaluator extends BaseFormulaEvaluator { _bookEvaluator.notifyUpdateCell(new XSSFEvaluationCell((XSSFCell)cell)); } - /** - * If cell contains formula, it evaluates the formula, and - * puts the formula result back into the cell, in place - * of the old formula. - * Else if cell does not contain formula, this method leaves - * the cell unchanged. - */ - protected void doEvaluateInCell(Cell cell) { - if (cell == null) return; - if (cell.getCellTypeEnum() == CellType.FORMULA) { - CellValue cv = evaluateFormulaCellValue(cell); - setCellType(cell, cv); // cell will no longer be a formula cell - setCellValue(cell, cv); - } - } - /** * Turns a XSSFCell / SXSSFCell into a XSSFEvaluationCell */ diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFormulaEvaluator.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFormulaEvaluator.java index fc456b7e5..e63f47b46 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFormulaEvaluator.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFormulaEvaluator.java @@ -23,6 +23,8 @@ import org.apache.poi.ss.formula.IStabilityClassifier; import org.apache.poi.ss.formula.WorkbookEvaluator; import org.apache.poi.ss.formula.udf.UDFFinder; import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.CellValue; /** * Evaluates formula cells.

@@ -55,27 +57,6 @@ public final class XSSFFormulaEvaluator extends BaseXSSFFormulaEvaluator { return new XSSFFormulaEvaluator(workbook, stabilityClassifier, udfFinder); } - /** - * If cell contains formula, it evaluates the formula, and - * puts the formula result back into the cell, in place - * of the old formula. - * Else if cell does not contain formula, this method leaves - * the cell unchanged. - * Note that the same instance of XSSFCell is returned to - * allow chained calls like: - *

-     * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
-     * 
- * Be aware that your cell value will be changed to hold the - * result of the formula. If you simply want the formula - * value computed for you, use {@link #evaluateFormulaCellEnum(org.apache.poi.ss.usermodel.Cell)} } - * @param cell - */ - public XSSFCell evaluateInCell(Cell cell) { - doEvaluateInCell(cell); - return (XSSFCell)cell; - } - /** * Loops over all cells in all sheets of the supplied * workbook. @@ -90,6 +71,12 @@ public final class XSSFFormulaEvaluator extends BaseXSSFFormulaEvaluator { public static void evaluateAllFormulaCells(XSSFWorkbook wb) { BaseFormulaEvaluator.evaluateAllFormulaCells(wb); } + + @Override + public XSSFCell evaluateInCell(Cell cell) { + return (XSSFCell) super.evaluateInCell(cell); + } + /** * Loops over all cells in all sheets of the supplied * workbook. diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java index 6dcaef960..84a4aa680 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java @@ -682,4 +682,15 @@ public final class TestXSSFFormulaEvaluation extends BaseTestFormulaEvaluator { value = evaluator.evaluate(cell); assertEquals(1, value.getNumberValue(), 0.001); } + + @Test + public void evaluateInCellReturnsSameDataType() throws IOException { + XSSFWorkbook wb = new XSSFWorkbook(); + wb.createSheet().createRow(0).createCell(0); + XSSFFormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); + XSSFCell cell = wb.getSheetAt(0).getRow(0).getCell(0); + XSSFCell same = evaluator.evaluateInCell(cell); + assertSame(cell, same); + wb.close(); + } } diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestFormulaEvaluator.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestFormulaEvaluator.java index 8a16d3a64..c4922a7c8 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestFormulaEvaluator.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestFormulaEvaluator.java @@ -19,6 +19,7 @@ package org.apache.poi.ss.usermodel; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.fail; import java.io.IOException; @@ -326,4 +327,15 @@ public abstract class BaseTestFormulaEvaluator { wb.close(); } + + @Test + public void evaluateInCellReturnsSameCell() throws IOException { + Workbook wb = _testDataProvider.createWorkbook(); + wb.createSheet().createRow(0).createCell(0); + FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); + Cell cell = wb.getSheetAt(0).getRow(0).getCell(0); + Cell same = evaluator.evaluateInCell(cell); + assertSame(cell, same); + wb.close(); + } } \ No newline at end of file From 6219cc6664d2e2c2488c8ea2f28b58b19831aeec Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Wed, 14 Sep 2016 12:35:34 +0000 Subject: [PATCH 101/157] Unit test for bug #60128, showing that calling close on a broken package cleans up file or stream git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760693 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/openxml4j/util/ZipEntrySource.java | 5 ++ .../openxml4j/util/ZipFileZipEntrySource.java | 3 ++ .../util/ZipInputStreamZipEntrySource.java | 3 ++ .../poi/openxml4j/opc/TestZipPackage.java | 50 +++++++++++++++++++ .../poi/poifs/crypt/TestSecureTempZip.java | 8 +++ 5 files changed, 69 insertions(+) diff --git a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipEntrySource.java b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipEntrySource.java index 1d64ffe4e..51ad32ce6 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipEntrySource.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipEntrySource.java @@ -45,4 +45,9 @@ public interface ZipEntrySource { * resources may be freed */ public void close() throws IOException; + + /** + * Has close been called already? + */ + public boolean isClosed(); } diff --git a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipFileZipEntrySource.java b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipFileZipEntrySource.java index f4117f44b..09317d361 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipFileZipEntrySource.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipFileZipEntrySource.java @@ -39,6 +39,9 @@ public class ZipFileZipEntrySource implements ZipEntrySource { } zipArchive = null; } + public boolean isClosed() { + return (zipArchive == null); + } public Enumeration getEntries() { if (zipArchive == null) diff --git a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java index 36b69ac25..4c2b9df3e 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java @@ -76,6 +76,9 @@ public class ZipInputStreamZipEntrySource implements ZipEntrySource { // Free the memory zipEntries = null; } + public boolean isClosed() { + return (zipEntries == null); + } /** * Why oh why oh why are Iterator and Enumeration diff --git a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestZipPackage.java b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestZipPackage.java index 7f174e07a..698f194c4 100644 --- a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestZipPackage.java +++ b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestZipPackage.java @@ -33,11 +33,14 @@ import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; +import org.apache.poi.POIDataSamples; import org.apache.poi.POITextExtractor; import org.apache.poi.POIXMLException; import org.apache.poi.extractor.ExtractorFactory; import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.openxml4j.OpenXML4JTestDataSamples; +import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException; +import org.apache.poi.openxml4j.exceptions.ODFNotOfficeXmlFileException; import org.apache.poi.sl.usermodel.SlideShow; import org.apache.poi.sl.usermodel.SlideShowFactory; import org.apache.poi.ss.usermodel.Workbook; @@ -194,6 +197,53 @@ public class TestZipPackage { } catch (Exception e) { } assertTrue("Can't delete tmp file", tmp.delete()); + } + + /** + * If ZipPackage is passed an invalid file, a call to close + * (eg from the OPCPackage open method) should tidy up the + * stream / file the broken file is being read from. + * See bug #60128 for more + */ + @Test + public void testTidyStreamOnInvalidFile() throws Exception { + // Spreadsheet has a good mix of alternate file types + POIDataSamples files = POIDataSamples.getSpreadSheetInstance(); + + File[] notValidF = new File[] { + files.getFile("SampleSS.ods"), files.getFile("SampleSS.txt") + }; + InputStream[] notValidS = new InputStream[] { + files.openResourceAsStream("SampleSS.ods"), files.openResourceAsStream("SampleSS.txt") + }; + for (File notValid : notValidF) { + ZipPackage pkg = new ZipPackage(notValid, PackageAccess.READ); + assertNotNull(pkg.getZipArchive()); + assertFalse(pkg.getZipArchive().isClosed()); + try { + pkg.getParts(); + fail("Shouldn't work"); + } catch (ODFNotOfficeXmlFileException e) { + } catch (NotOfficeXmlFileException ne) {} + pkg.close(); + + assertNotNull(pkg.getZipArchive()); + assertTrue(pkg.getZipArchive().isClosed()); + } + for (InputStream notValid : notValidS) { + ZipPackage pkg = new ZipPackage(notValid, PackageAccess.READ); + assertNotNull(pkg.getZipArchive()); + assertFalse(pkg.getZipArchive().isClosed()); + try { + pkg.getParts(); + fail("Shouldn't work"); + } catch (ODFNotOfficeXmlFileException e) { + } catch (NotOfficeXmlFileException ne) {} + pkg.close(); + + assertNotNull(pkg.getZipArchive()); + assertTrue(pkg.getZipArchive().isClosed()); + } } } diff --git a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSecureTempZip.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSecureTempZip.java index 4d4c5df34..868a38227 100644 --- a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSecureTempZip.java +++ b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSecureTempZip.java @@ -149,10 +149,12 @@ public class TestSecureTempZip { static class AesZipFileZipEntrySource implements ZipEntrySource { final ZipFile zipFile; final Cipher ci; + boolean closed; AesZipFileZipEntrySource(ZipFile zipFile, Cipher ci) { this.zipFile = zipFile; this.ci = ci; + this.closed = false; } /** @@ -172,6 +174,12 @@ public class TestSecureTempZip { @Override public void close() throws IOException { zipFile.close(); + closed = true; + } + + @Override + public boolean isClosed() { + return closed; } } } From ed5cd06fb740b26eb91d5cde0f95adc1c6478ef0 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 12:57:39 +0000 Subject: [PATCH 102/157] bug 60128: close open file descriptors when exceptions are thrown from OPCPackage.open git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760702 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/openxml4j/opc/OPCPackage.java | 17 ++- .../apache/poi/openxml4j/opc/ZipPackage.java | 118 ++++++++++++------ .../poi/openxml4j/util/ZipSecureFile.java | 6 +- .../poi/extractor/TestExtractorFactory.java | 6 +- .../apache/poi/openxml4j/opc/TestPackage.java | 18 +++ .../poi/openxml4j/opc/TestZipPackage.java | 6 + test-data/openxml4j/invalid.xlsx | Bin 0 -> 22 bytes 7 files changed, 130 insertions(+), 41 deletions(-) create mode 100644 test-data/openxml4j/invalid.xlsx diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java index e029d7dec..b7720ee42 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java @@ -248,9 +248,10 @@ public abstract class OPCPackage implements RelationshipSource, Closeable { * @throws InvalidFormatException * If the specified file doesn't exist, and a parsing error * occur. + * @throws InvalidOperationException */ public static OPCPackage open(String path, PackageAccess access) - throws InvalidFormatException { + throws InvalidFormatException, InvalidOperationException { if (path == null || "".equals(path.trim())) { throw new IllegalArgumentException("'path' must be given"); } @@ -261,8 +262,20 @@ public abstract class OPCPackage implements RelationshipSource, Closeable { } OPCPackage pack = new ZipPackage(path, access); + boolean success = false; if (pack.partList == null && access != PackageAccess.WRITE) { - pack.getParts(); + try { + pack.getParts(); + success = true; + } finally { + if (! success) { + try { + pack.close(); + } catch (final IOException e) { + throw new InvalidOperationException("Could not close OPCPackage while cleaning up", e); + } + } + } } pack.originalPackagePath = new File(path).getAbsolutePath(); return pack; diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java index fe4d6f1ed..8f7efa02c 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java @@ -19,6 +19,7 @@ package org.apache.poi.openxml4j.opc; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -88,9 +89,18 @@ public final class ZipPackage extends OPCPackage { */ ZipPackage(InputStream in, PackageAccess access) throws IOException { super(access); - @SuppressWarnings("resource") ThresholdInputStream zis = ZipHelper.openZipStream(in); - this.zipArchive = new ZipInputStreamZipEntrySource(zis); + try { + this.zipArchive = new ZipInputStreamZipEntrySource(zis); + } catch (final IOException e) { + try { + zis.close(); + } catch (final IOException e2) { + e2.addSuppressed(e); + throw new IOException("Failed to close zip input stream while cleaning up", e2); + } + throw new IOException("Failed to read zip entry source", e); + } } /** @@ -100,8 +110,9 @@ public final class ZipPackage extends OPCPackage { * The path of the file to open or create. * @param access * The package access mode. + * @throws InvalidOperationException */ - ZipPackage(String path, PackageAccess access) { + ZipPackage(String path, PackageAccess access) throws InvalidOperationException { this(new File(path), access); } @@ -112,9 +123,9 @@ public final class ZipPackage extends OPCPackage { * The file to open or create. * @param access * The package access mode. + * @throws InvalidOperationException */ - @SuppressWarnings("resource") - ZipPackage(File file, PackageAccess access) { + ZipPackage(File file, PackageAccess access) throws InvalidOperationException { super(access); ZipEntrySource ze; @@ -127,36 +138,72 @@ public final class ZipPackage extends OPCPackage { throw new InvalidOperationException("Can't open the specified file: '" + file + "'", e); } logger.log(POILogger.ERROR, "Error in zip file "+file+" - falling back to stream processing (i.e. ignoring zip central directory)"); - // some zips can't be opened via ZipFile in JDK6, as the central directory - // contains either non-latin entries or the compression type can't be handled - // the workaround is to iterate over the stream and not the directory - FileInputStream fis = null; - ThresholdInputStream zis = null; - try { - fis = new FileInputStream(file); - zis = ZipHelper.openZipStream(fis); - ze = new ZipInputStreamZipEntrySource(zis); - } catch (IOException e2) { - if (zis != null) { - try { - zis.close(); - } catch (IOException e3) { - throw new InvalidOperationException("Can't open the specified file: '" + file + "'"+ - " and couldn't close the file input stream", e); - } - } else if (fis != null) { - try { - fis.close(); - } catch (IOException e3) { - throw new InvalidOperationException("Can't open the specified file: '" + file + "'"+ - " and couldn't close the file input stream", e); - } - } - throw new InvalidOperationException("Can't open the specified file: '" + file + "'", e); - } + ze = openZipEntrySourceStream(file); } this.zipArchive = ze; } + + private static ZipEntrySource openZipEntrySourceStream(File file) throws InvalidOperationException { + final FileInputStream fis; + // Acquire a resource that is needed to read the next level of openZipEntrySourceStream + try { + // open the file input stream + fis = new FileInputStream(file); + } catch (final FileNotFoundException e) { + // If the source cannot be acquired, abort (no resources to free at this level) + throw new InvalidOperationException("Can't open the specified file input stream from file: '" + file + "'", e); + } + + // If an error occurs while reading the next level of openZipEntrySourceStream, free the acquired resource + try { + // read from the file input stream + return openZipEntrySourceStream(fis); + } catch (final Exception e) { + try { + // abort: close the file input stream + fis.close(); + } catch (final IOException e2) { + throw new InvalidOperationException("Could not close the specified file input stream from file: '" + file + "'", e2); + } + throw new InvalidOperationException("Failed to read the file input stream from file: '" + file + "'", e); + } + } + + private static ZipEntrySource openZipEntrySourceStream(FileInputStream fis) throws InvalidOperationException { + final ThresholdInputStream zis; + // Acquire a resource that is needed to read the next level of openZipEntrySourceStream + try { + // open the zip input stream + zis = ZipHelper.openZipStream(fis); + } catch (final IOException e) { + // If the source cannot be acquired, abort (no resources to free at this level) + throw new InvalidOperationException("Could not open the file input stream", e); + } + + // If an error occurs while reading the next level of openZipEntrySourceStream, free the acquired resource + try { + // read from the zip input stream + return openZipEntrySourceStream(zis); + } catch (final Exception e) { + try { + // abort: close the zip input stream + zis.close(); + } catch (final IOException e2) { + throw new InvalidOperationException("Failed to read the zip entry source stream and could not close the zip input stream", e2); + } + throw new InvalidOperationException("Failed to read the zip entry source stream"); + } + } + + private static ZipEntrySource openZipEntrySourceStream(ThresholdInputStream zis) throws InvalidOperationException { + // Acquire the final level resource. If this is acquired successfully, the zip package was read successfully from the input stream + try { + // open the zip entry source stream + return new ZipInputStreamZipEntrySource(zis); + } catch (IOException e) { + throw new InvalidOperationException("Could not open the specified zip entry source stream", e); + } + } /** * Constructor. Opens a Zip based Open XML document from @@ -220,11 +267,12 @@ public final class ZipPackage extends OPCPackage { boolean hasSettingsXML = false; entries = this.zipArchive.getEntries(); while (entries.hasMoreElements()) { - ZipEntry entry = entries.nextElement(); - if (entry.getName().equals("mimetype")) { + final ZipEntry entry = entries.nextElement(); + final String name = entry.getName(); + if ("mimetype".equals(name)) { hasMimetype = true; } - if (entry.getName().equals("settings.xml")) { + if ("settings.xml".equals(name)) { hasSettingsXML = true; } numEntries++; diff --git a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java index 13369a5ed..9000656e5 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java @@ -134,15 +134,15 @@ public class ZipSecureFile extends ZipFile { return MAX_TEXT_SIZE; } - public ZipSecureFile(File file, int mode) throws IOException { + public ZipSecureFile(File file, int mode) throws ZipException, IOException { super(file, mode); } - public ZipSecureFile(File file) throws IOException { + public ZipSecureFile(File file) throws ZipException, IOException { super(file); } - public ZipSecureFile(String name) throws IOException { + public ZipSecureFile(String name) throws ZipException, IOException { super(name); } diff --git a/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java b/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java index 0aa022332..9d206f719 100644 --- a/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java +++ b/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java @@ -682,9 +682,12 @@ public class TestExtractorFactory { // Text try { ExtractorFactory.createExtractor(OPCPackage.open(txt.toString())); - fail(); + fail("TestExtractorFactory.testPackage() failed on " + txt.toString()); } catch(UnsupportedFileFormatException e) { // Good + } catch (Exception e) { + System.out.println("TestExtractorFactory.testPackage() failed on " + txt.toString()); + throw e; } } @@ -942,6 +945,7 @@ public class TestExtractorFactory { "openxml4j/OPCCompliance_CoreProperties_OnlyOneCorePropertiesPartFAIL.docx", "openxml4j/OPCCompliance_CoreProperties_UnauthorizedXMLLangAttributeFAIL.docx", "openxml4j/OPCCompliance_DerivedPartNameFAIL.docx", + "openxml4j/invalid.xlsx", "spreadsheet/54764-2.xlsx", // see TestXSSFBugs.bug54764() "spreadsheet/54764.xlsx", // see TestXSSFBugs.bug54764() "spreadsheet/Simple.xlsb", diff --git a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java index d84ecab81..5f83bc52d 100644 --- a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java +++ b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java @@ -943,4 +943,22 @@ public final class TestPackage { ZipSecureFile.setMaxTextSize(before); } } + + // bug 60128 + @Test + public void testCorruptFile() throws IOException { + OPCPackage pkg = null; + File file = OpenXML4JTestDataSamples.getSampleFile("invalid.xlsx"); + try { + pkg = OPCPackage.open(file, PackageAccess.READ); + } catch (Exception e) { + System.out.println(e.getClass().getName()); + System.out.println(e.getMessage()); + e.printStackTrace(); + } finally { + if (pkg != null) { + pkg.close(); + } + } + } } diff --git a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestZipPackage.java b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestZipPackage.java index 698f194c4..0989d10cb 100644 --- a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestZipPackage.java +++ b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestZipPackage.java @@ -184,6 +184,7 @@ public class TestZipPackage { public void testClosingStreamOnException() throws IOException { InputStream is = OpenXML4JTestDataSamples.openSampleStream("dcterms_bug_56479.zip"); File tmp = File.createTempFile("poi-test-truncated-zip", ""); + // create a corrupted zip file by truncating a valid zip file to the first 100 bytes OutputStream os = new FileOutputStream(tmp); for (int i = 0; i < 100; i++) { os.write(is.read()); @@ -192,10 +193,15 @@ public class TestZipPackage { os.close(); is.close(); + // feed the corrupted zip file to OPCPackage try { OPCPackage.open(tmp, PackageAccess.READ); } catch (Exception e) { + // expected: the zip file is invalid + // this test does not care if open() throws an exception or not. } + // If the stream is not closed on exception, it will keep a file descriptor to tmp, + // and requests to the OS to delete the file will fail. assertTrue("Can't delete tmp file", tmp.delete()); } diff --git a/test-data/openxml4j/invalid.xlsx b/test-data/openxml4j/invalid.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..15cb0ecb3e219d1701294bfdf0fe3f5cb5d208e7 GIT binary patch literal 22 NcmWIWW@Tf*000g10H*)| literal 0 HcmV?d00001 From d34b6a995b8ef138212746f2459135e6854b8f68 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 13:28:27 +0000 Subject: [PATCH 103/157] give more helpful exceptions rather than returning null when zip file cannot be opened git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760708 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/openxml4j/opc/internal/ZipHelper.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java index 632d2af26..b674b3ad2 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java @@ -19,6 +19,7 @@ package org.apache.poi.openxml4j.opc.internal; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.PushbackInputStream; @@ -239,10 +240,15 @@ public final class ZipHelper { * @param file * The file to open. * @return The zip archive freshly open. + * @throws IOException if the zip file cannot be opened or closed to read the header signature + * @throws NotOfficeXmlFileException if stream does not start with zip header signature */ - public static ZipFile openZipFile(File file) throws IOException { + public static ZipFile openZipFile(File file) throws IOException, NotOfficeXmlFileException { if (!file.exists()) { - return null; + throw new FileNotFoundException("File does not exist"); + } + if (file.isDirectory()) { + throw new IOException("File is a directory"); } // Peek at the first few bytes to sanity check From 2104b1d585d6b14c206ddcbd06bb7ac5d0825f36 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 13:55:39 +0000 Subject: [PATCH 104/157] bug 60128: close opened resources to avoid leaks; add exception as cause where available for more context for raised exceptions. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760710 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/openxml4j/opc/ZipPackage.java | 54 ++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java index 8f7efa02c..e2f4c8e70 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java @@ -53,6 +53,9 @@ import org.apache.poi.util.TempFile; * Physical zip package. */ public final class ZipPackage extends OPCPackage { + private static final String MIMETYPE = "mimetype"; + private static final String SETTINGS_XML = "settings.xml"; + private static POILogger logger = POILogFactory.getLogger(ZipPackage.class); /** @@ -191,7 +194,7 @@ public final class ZipPackage extends OPCPackage { } catch (final IOException e2) { throw new InvalidOperationException("Failed to read the zip entry source stream and could not close the zip input stream", e2); } - throw new InvalidOperationException("Failed to read the zip entry source stream"); + throw new InvalidOperationException("Failed to read the zip entry source stream", e); } } @@ -253,7 +256,7 @@ public final class ZipPackage extends OPCPackage { this.contentTypeManager = new ZipContentTypeManager( getZipArchive().getInputStream(entry), this); } catch (IOException e) { - throw new InvalidFormatException(e.getMessage()); + throw new InvalidFormatException(e.getMessage(), e); } break; } @@ -269,10 +272,10 @@ public final class ZipPackage extends OPCPackage { while (entries.hasMoreElements()) { final ZipEntry entry = entries.nextElement(); final String name = entry.getName(); - if ("mimetype".equals(name)) { + if (MIMETYPE.equals(name)) { hasMimetype = true; } - if ("settings.xml".equals(name)) { + if (SETTINGS_XML.equals(name)) { hasSettingsXML = true; } numEntries++; @@ -307,10 +310,10 @@ public final class ZipPackage extends OPCPackage { String contentType = contentTypeManager.getContentType(partName); if (contentType != null && contentType.equals(ContentTypes.RELATIONSHIPS_PART)) { try { - partList.put(partName, new ZipPackagePart(this, entry, - partName, contentType)); + PackagePart part = new ZipPackagePart(this, entry, partName, contentType); + partList.put(partName, part); } catch (InvalidOperationException e) { - throw new InvalidFormatException(e.getMessage()); + throw new InvalidFormatException(e.getMessage(), e); } } } @@ -322,17 +325,16 @@ public final class ZipPackage extends OPCPackage { PackagePartName partName = buildPartName(entry); if(partName == null) continue; - String contentType = contentTypeManager - .getContentType(partName); + String contentType = contentTypeManager.getContentType(partName); if (contentType != null && contentType.equals(ContentTypes.RELATIONSHIPS_PART)) { // Already handled } else if (contentType != null) { try { - partList.put(partName, new ZipPackagePart(this, entry, - partName, contentType)); + PackagePart part = new ZipPackagePart(this, entry, partName, contentType); + partList.put(partName, part); } catch (InvalidOperationException e) { - throw new InvalidFormatException(e.getMessage()); + throw new InvalidFormatException(e.getMessage(), e); } } else { throw new InvalidFormatException( @@ -440,20 +442,22 @@ public final class ZipPackage extends OPCPackage { // Save the final package to a temporary file try { save(tempFile); - - // Close the current zip file, so we can - // overwrite it on all platforms - this.zipArchive.close(); - // Copy the new file over the old one - FileHelper.copyFile(tempFile, targetFile); } finally { - // Either the save operation succeed or not, we delete the - // temporary file - if (!tempFile.delete()) { - logger - .log(POILogger.WARN,"The temporary file: '" - + targetFile.getAbsolutePath() - + "' cannot be deleted ! Make sure that no other application use it."); + try { + // Close the current zip file, so we can + // overwrite it on all platforms + this.zipArchive.close(); + // Copy the new file over the old one + FileHelper.copyFile(tempFile, targetFile); + } finally { + // Either the save operation succeed or not, we delete the + // temporary file + if (!tempFile.delete()) { + logger + .log(POILogger.WARN,"The temporary file: '" + + targetFile.getAbsolutePath() + + "' cannot be deleted ! Make sure that no other application use it."); + } } } } else { From 6ed8aaada619d8c5a880449481ea894986af9af9 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 13:56:03 +0000 Subject: [PATCH 105/157] make logger final git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760711 13f79535-47bb-0310-9956-ffa450edef68 --- src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java index e2f4c8e70..3872e7381 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java @@ -56,7 +56,7 @@ public final class ZipPackage extends OPCPackage { private static final String MIMETYPE = "mimetype"; private static final String SETTINGS_XML = "settings.xml"; - private static POILogger logger = POILogFactory.getLogger(ZipPackage.class); + private static final POILogger logger = POILogFactory.getLogger(ZipPackage.class); /** * Zip archive, as either a file on disk, From 5fc5680d157600ea499990cf4f90270a99964c03 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Wed, 14 Sep 2016 14:59:00 +0000 Subject: [PATCH 106/157] Patches from Patrick Zimmermann from bugs #60130 and #60131 - DGET fix for empty cells and D* coding improvements git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760717 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/ss/formula/functions/DGet.java | 19 ++- .../poi/ss/formula/functions/DStarRunner.java | 142 +++++++----------- test-data/spreadsheet/DGet.xls | Bin 51712 -> 53760 bytes 3 files changed, 67 insertions(+), 94 deletions(-) diff --git a/src/java/org/apache/poi/ss/formula/functions/DGet.java b/src/java/org/apache/poi/ss/formula/functions/DGet.java index 91a9934b5..0bf9cc262 100644 --- a/src/java/org/apache/poi/ss/formula/functions/DGet.java +++ b/src/java/org/apache/poi/ss/formula/functions/DGet.java @@ -17,7 +17,10 @@ package org.apache.poi.ss.formula.functions; +import org.apache.poi.ss.formula.eval.BlankEval; import org.apache.poi.ss.formula.eval.ErrorEval; +import org.apache.poi.ss.formula.eval.EvaluationException; +import org.apache.poi.ss.formula.eval.OperandResolver; import org.apache.poi.ss.formula.eval.ValueEval; /** @@ -46,8 +49,18 @@ public final class DGet implements IDStarAlgorithm { public ValueEval getResult() { if(result == null) { return ErrorEval.VALUE_INVALID; - } else { - return result; - } + } else if(result instanceof BlankEval) { + return ErrorEval.VALUE_INVALID; + } else + try { + if(OperandResolver.coerceValueToString(OperandResolver.getSingleValue(result, 0, 0)).equals("")) { + return ErrorEval.VALUE_INVALID; + } + else { + return result; + } + } catch (EvaluationException e) { + return e.getErrorEval(); + } } } diff --git a/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java b/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java index 6a87a67a6..2901abc95 100644 --- a/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java +++ b/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java @@ -17,13 +17,13 @@ package org.apache.poi.ss.formula.functions; -import org.apache.poi.ss.formula.TwoDEval; +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.EvaluationException; import org.apache.poi.ss.formula.eval.NotImplementedException; import org.apache.poi.ss.formula.eval.NumericValueEval; -import org.apache.poi.ss.formula.eval.RefEval; +import org.apache.poi.ss.formula.eval.OperandResolver; import org.apache.poi.ss.formula.eval.StringEval; import org.apache.poi.ss.formula.eval.StringValueEval; import org.apache.poi.ss.formula.eval.ValueEval; @@ -62,11 +62,17 @@ public final class DStarRunner implements Function3Arg { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval database, ValueEval filterColumn, ValueEval conditionDatabase) { // Input processing and error checks. - if(!(database instanceof TwoDEval) || !(conditionDatabase instanceof TwoDEval)) { + if(!(database instanceof AreaEval) || !(conditionDatabase instanceof AreaEval)) { return ErrorEval.VALUE_INVALID; } - TwoDEval db = (TwoDEval)database; - TwoDEval cdb = (TwoDEval)conditionDatabase; + AreaEval db = (AreaEval)database; + AreaEval cdb = (AreaEval)conditionDatabase; + + try { + filterColumn = OperandResolver.getSingleValue(filterColumn, srcRowIndex, srcColumnIndex); + } catch (EvaluationException e) { + return e.getErrorEval(); + } int fc; try { @@ -100,15 +106,11 @@ public final class DStarRunner implements Function3Arg { } // Filter each entry. if(matches) { - try { - ValueEval currentValueEval = solveReference(db.getValue(row, fc)); - // Pass the match to the algorithm and conditionally abort the search. - boolean shouldContinue = algorithm.processMatch(currentValueEval); - if(! shouldContinue) { - break; - } - } catch (EvaluationException e) { - return e.getErrorEval(); + ValueEval currentValueEval = resolveReference(db, row, fc); + // Pass the match to the algorithm and conditionally abort the search. + boolean shouldContinue = algorithm.processMatch(currentValueEval); + if(! shouldContinue) { + break; } } } @@ -126,56 +128,16 @@ public final class DStarRunner implements Function3Arg { } /** - * Resolve reference(-chains) until we have a normal value. + * * - * @param field a ValueEval which can be a RefEval. - * @return a ValueEval which is guaranteed not to be a RefEval - * @throws EvaluationException If a multi-sheet reference was found along the way. - */ - private static ValueEval solveReference(ValueEval field) throws EvaluationException { - if (field instanceof RefEval) { - RefEval refEval = (RefEval)field; - if (refEval.getNumberOfSheets() > 1) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - return solveReference(refEval.getInnerValueEval(refEval.getFirstSheetIndex())); - } - else { - return field; - } - } - - /** - * Returns the first column index that matches the given name. The name can either be - * a string or an integer, when it's an integer, then the respective column - * (1 based index) is returned. - * @param nameValueEval + * @param nameValueEval Must not be a RefEval or AreaEval. Thus make sure resolveReference() is called on the value first! * @param db - * @return the first column index that matches the given name (or int) + * @return * @throws EvaluationException */ - @SuppressWarnings("unused") - private static int getColumnForTag(ValueEval nameValueEval, TwoDEval db) + private static int getColumnForName(ValueEval nameValueEval, AreaEval db) throws EvaluationException { - int resultColumn = -1; - - // Numbers as column indicator are allowed, check that. - if(nameValueEval instanceof NumericValueEval) { - double doubleResultColumn = ((NumericValueEval)nameValueEval).getNumberValue(); - resultColumn = (int)doubleResultColumn; - // Floating comparisions are usually not possible, but should work for 0.0. - if(doubleResultColumn - resultColumn != 0.0) - throw new EvaluationException(ErrorEval.VALUE_INVALID); - resultColumn -= 1; // Numbers are 1-based not 0-based. - } else { - resultColumn = getColumnForName(nameValueEval, db); - } - return resultColumn; - } - - private static int getColumnForName(ValueEval nameValueEval, TwoDEval db) - throws EvaluationException { - String name = getStringFromValueEval(nameValueEval); + String name = OperandResolver.coerceValueToString(nameValueEval); return getColumnForString(db, name); } @@ -187,16 +149,19 @@ public final class DStarRunner implements Function3Arg { * @return Corresponding column number. * @throws EvaluationException If it's not possible to turn all headings into strings. */ - private static int getColumnForString(TwoDEval db,String name) + private static int getColumnForString(AreaEval db,String name) throws EvaluationException { int resultColumn = -1; final int width = db.getWidth(); for(int column = 0; column < width; ++column) { - ValueEval columnNameValueEval = db.getValue(0, column); - if(solveReference(columnNameValueEval) instanceof BlankEval) { + ValueEval columnNameValueEval = resolveReference(db, 0, column); + if(columnNameValueEval instanceof BlankEval) { continue; } - String columnName = getStringFromValueEval(columnNameValueEval); + if(columnNameValueEval instanceof ErrorEval) { + continue; + } + String columnName = OperandResolver.coerceValueToString(columnNameValueEval); if(name.equals(columnName)) { resultColumn = column; break; @@ -215,7 +180,7 @@ public final class DStarRunner implements Function3Arg { * @throws EvaluationException If references could not be resolved or comparison * operators and operands didn't match. */ - private static boolean fullfillsConditions(TwoDEval db, int row, TwoDEval cdb) + private static boolean fullfillsConditions(AreaEval db, int row, AreaEval cdb) throws EvaluationException { // Only one row must match to accept the input, so rows are ORed. // Each row is made up of cells where each cell is a condition, @@ -229,20 +194,15 @@ public final class DStarRunner implements Function3Arg { // special column that accepts formulas. boolean columnCondition = true; ValueEval condition = null; - try { - // The condition to apply. - condition = solveReference(cdb.getValue(conditionRow, column)); - } catch (java.lang.RuntimeException e) { - // It might be a special formula, then it is ok if it fails. - columnCondition = false; - } + + // The condition to apply. + condition = resolveReference(cdb, conditionRow, column); + // If the condition is empty it matches. if(condition instanceof BlankEval) continue; // The column in the DB to apply the condition to. - ValueEval targetHeader = solveReference(cdb.getValue(0, column)); - targetHeader = solveReference(targetHeader); - + ValueEval targetHeader = resolveReference(cdb, 0, column); if(!(targetHeader instanceof StringValueEval)) { throw new EvaluationException(ErrorEval.VALUE_INVALID); @@ -254,14 +214,14 @@ public final class DStarRunner implements Function3Arg { if(columnCondition == true) { // normal column condition // Should not throw, checked above. - ValueEval value = db.getValue( - row, getColumnForName(targetHeader, db)); + ValueEval value = resolveReference(db, row, getColumnForName(targetHeader, db)); if(!testNormalCondition(value, condition)) { matches = false; break; } } else { // It's a special formula condition. - if(getStringFromValueEval(condition).isEmpty()) { + // TODO: Check whether the condition cell contains a formula and return #VALUE! if it doesn't. + if(OperandResolver.coerceValueToString(condition).isEmpty()) { throw new EvaluationException(ErrorEval.VALUE_INVALID); } throw new NotImplementedException( @@ -328,7 +288,7 @@ public final class DStarRunner implements Function3Arg { if(itsANumber) { return testNumericCondition(value, operator.equal, stringOrNumber); } else { // It's a string. - String valueString = value instanceof BlankEval ? "" : getStringFromValueEval(value); + String valueString = value instanceof BlankEval ? "" : OperandResolver.coerceValueToString(value); return stringOrNumber.equals(valueString); } } else { // It's a text starts-with condition. @@ -336,7 +296,7 @@ public final class DStarRunner implements Function3Arg { return value instanceof StringEval; } else { - String valueString = value instanceof BlankEval ? "" : getStringFromValueEval(value); + String valueString = value instanceof BlankEval ? "" : OperandResolver.coerceValueToString(value); return valueString.startsWith(conditionString); } } @@ -424,20 +384,20 @@ public final class DStarRunner implements Function3Arg { return null; } } - + /** - * Takes a ValueEval and tries to retrieve a String value from it. - * It tries to resolve references if there are any. + * Resolve a ValueEval that's in an AreaEval. * - * @param value ValueEval to retrieve the string from. - * @return String corresponding to the given ValueEval. - * @throws EvaluationException If it's not possible to retrieve a String value. + * @param db AreaEval from which the cell to resolve is retrieved. + * @param dbRow Relative row in the AreaEval. + * @param dbCol Relative column in the AreaEval. + * @return A ValueEval that is a NumberEval, StringEval, BoolEval, BlankEval or ErrorEval. */ - private static String getStringFromValueEval(ValueEval value) - throws EvaluationException { - value = solveReference(value); - if(!(value instanceof StringValueEval)) - throw new EvaluationException(ErrorEval.VALUE_INVALID); - return ((StringValueEval)value).getStringValue(); + private static ValueEval resolveReference(AreaEval db, int dbRow, int dbCol) { + try { + return OperandResolver.getSingleValue(db.getValue(dbRow, dbCol), db.getFirstRow()+dbRow, db.getFirstColumn()+dbCol); + } catch (EvaluationException e) { + return e.getErrorEval(); + } } } diff --git a/test-data/spreadsheet/DGet.xls b/test-data/spreadsheet/DGet.xls index 5d254febeb15659303de31134301f5446aaa2924..729e974e4dfd4bf2e06b10c620cbb17b4b6bf719 100644 GIT binary patch delta 4726 zcmZ`+YitzP75--ZUTp8Oez1Nr2GdfY0z?{;7KjZt)CHRYHjl+%)_AaYz1}r`qyn`} z67rB*wFNF!E5(3$l(d2H$TmqIX|w5{kbhAc5z!Y_f3%gVs>+|Xs!F!!+_^LMtjA-m z@0|19d%kndJ@?+Z&z#SD=33sFHQM0WwRQQ&0NmYmTT5p(UDFl_J+En=|6!5ID8p^zG43+oYBaH4}Jogq_SEJ<$vCS#jX4j_4a{$`>pKrKZRF{O$B9ylS%*M zc-yB8vE9dJ?4BuLyWFS5>68Ab;EsRupHN9d01Y~DL_-S;zKrhH2f?t1J_uc$3Wf`N zFlC&4H$4^nVx>5;Fr@7k3m2}@_Q?O;^uIBEzqvnD_5MCKUxeL8bU^PkUO*{+6A_*3 zZxmgtC?(&2na-~N&O$NO(I`Ibc*!gPjFHia6V#56MvoeKz{Vv@$l)<#d@?biA2kvQ zJvOe(PStbNQC*G-%>l?r4Y0JUwX^*xJ(kobh75foIyPunCc}j7ZQaphwm0b=NqxW= z(<3n>agx}Kd>*&Dl{{M7)zjHjq`I~@RapR=a}8i)+>d-M+Y+@ zz3kbs!vjpP;oa?9n>+#_qm#+WabrL?#>P@(`Vgg?f_OTbm^8*IPfAXvCZxO3iD-Xx z+{ohBD8?Ti2h9qwd_7F?bnRacyhQDAQQDFpUy0$!wi zeD*0|Z!xf|1$d?e*xE|o_<_33z*iOkr>T9N+7GDBQv1g(Kv@}ZzYQoT2R>=1VhaFk zwmt^*(M!)Z;CZUR-&4C_A<+9};9Jz*q4puQLmj~PX_Eg*ZDU2cZ2O(k!iW2TgAwr{ zGL`PzKj5pLAjd!H1KybgE_@rhII*3DaltCQ! z&`~w~pT1Xw~fC#7m}>wJxP`usW#=~vGOiW)|tW$Uo)AbL@VGAzo& z&ZHs50D|KF%NrUZ^Y#d#Lad%TWo|)(_6U9)Bm-?Y&CW?FfX#T8q*Fe|f`rl2VqqbL zSyBaIFFWI^6jtCXrg7DT1(f};3#lPwh4!dhlGVAOdV-qOphg$6m=N3DCWTl|EFpxQ zFT`5(irW|KSGw|1MV_?&9qd#u9WDXoR4?+-il2xJ7y8Vtm{vjbQYyM}*^vTh$McR9 z#5TO(NFf(iLD-aoRk^Tg!Y(*i*oD<#n~6&fSmy%kY2ZZ%Yjk0Y37dAXCKtAZFb;xK za){2ffDHT~vRT?T=G4UkyL7^+5x=`wtGzD%b+I|<%3>Yr#fnR{HEG3om~2{A!jo{A zYVOdb*&C7w&HPCiks7`W@_Uwcm{*wZ_~>ca3%0;1h80?U7l4yQS{4B zt(R+ey-gjgj&=d@HWO9bOmPdBY`R=XuV)(RS*7jL|?x8Wm+CZB!OER=!6#4RL5Qf;2L3?{UCJp{r zj9+cv!OjfIVZ61r$>fq5KAU0~C#yw#Hg$h3MPeNOjGt4>d-33`En!d^d`-M@wZmkC zLpgpB!8`^_Go`cUO6QagNyA)+mc+r|k^!zo%<XY}&4tXUc6?W3yb1Nmp+x z>oE#&W*3Z6ux)tG!Tjiy=P3ITqmRkiQn^bCI+Dpyqk~#2Jm} z1Wt*_30%c(BA5x4d4P`=h3WjA0=xc@Ma9F0`4P||ptnPNg8I~!qtBy`9V!5H1 z6N>K|Q?ZUH)&|mXyyV3^ ztks!nn{>pKtk#Fth-AH^SVtr)f5!0g9g(a7jWe6Hn6x6rM9lLrg)?EBDJhAHWMY$& z=%-9%Ql68NiD#dgl9FkKWJ)QfMT&`-=V7YN)Y?ob$+So^r6kkORY)mG#2;8plwu;2 zK0i4o`o5;w@@Y^^#5@mEeWu=K8kJ0tOrw(NXNqZ5GEFO{Q5lkzWIlWYXjc7>o7AyG z)-$_woI37-m83C=aBVX(CQVpD@iyBo>zt8sLgAR`I!O_2vB(3E89J^p+>~Tzlf&^#_F; zp8LW5vJcY_uN!(N-vjyH$M-zG*L|AJX8GF2*EGJC@imOEUA^?FFD}Ud delta 2383 zcmZ`)ZA_C_6n<{MpcQCg1xjnNL`ckFnGQeL1_%ncITb|tuzb|kR+~66VPR&3SzL4` zYNm35WSIj|KHMA?eX}J?_GA9ruZfA#jkpiDW&5!#+kPxF+oU`9?b}z1FSmJn?tPwf z&$;K^d+zNY*Y^+V&#h+r&aZJ90syY>yvC#$^Dt)P9(}-?wic3x>rC!S1N*5fmsVo2Cs``GR| zqp&M<%&Lxb$2eng^rhO-mrAqL)`;SsPd7+E*eqEU7!b6?r1jAzqk6O zZ3Xp{kV?Ic@BzDe>V$sbAnMzUc8;3W^8Wk8rhyI&6cOosX@fVWeC zZIwVXE&lb5K))F{SOxT0fU0U>>oVX9$r~j9A{is8-wdRu1OKk0jxhtssRcY%poyf9 zWN#gC+y<~Mz_Lu>7|GKlza;rprc|+gCe3uM87OY$=8g-}S#MC66Q+gU>;TTb1{^vK z+9)pdoD6)2%#s4**2bvEpz?qaM_1KXv6?bg7=J}tIK zi%nn=)v?I+V#QVsY>x)!)xg>`u=XdgXKkP~J>j@h1M>+?@(%20%)@VTuik^r{LcXw ze}1r(`ZaR@)Zi;74=Lgi_n)!z-v_HndCgFR(SvfN^9MtDd~~RSuy2OEGWL{=H4T@_ zqa6P2a2}r=E@d8RZrGaQZUKwAP}GKYnCMvM>QUbnl7|^onx>I*cl(kWnaJY4k)x3s zxY;9E(1r|b!ZBLhQJolBQ6pAb73VS)E1#JHIWYbZuWi_+0aY(p$YWwvB!c4YJWqfR!#{~q;4w&0?& z)OHH77RS|*6`y11ga>1*>XWRw zk&o(MA$H6su5o3@e9)sBR}?$Gq;&a6E1s@SlR+6fATaJ3FL|7)PKs1iMf>E#(=7^u$> zrk}yUznCtQ{)qOlf#}z!>W|;J`~7X{yJ*N$F&~S?#1kZ*9Pz}6Cq=v<;>8dzgy6*s vAZ~nd!HWysN8euh{QUf_!{_(f24)}Xx-ap6W_wv9@3|dG6VC{paJl^t&%dF} From 41b0462f502772cb15911c764c5421b714c13844 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Wed, 14 Sep 2016 15:01:57 +0000 Subject: [PATCH 107/157] Javadoc fix git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760719 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/ss/formula/functions/DStarRunner.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java b/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java index 2901abc95..8418c4f74 100644 --- a/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java +++ b/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java @@ -131,8 +131,8 @@ public final class DStarRunner implements Function3Arg { * * * @param nameValueEval Must not be a RefEval or AreaEval. Thus make sure resolveReference() is called on the value first! - * @param db - * @return + * @param db Database + * @return Corresponding column number. * @throws EvaluationException */ private static int getColumnForName(ValueEval nameValueEval, AreaEval db) From 753ca9b8119b4bdd4c65e297b23e877f013c1ab0 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 17:21:31 +0000 Subject: [PATCH 108/157] bug 60128: make code Java 6 compatible. Throwable#addSuppressed not available until Java 7 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760732 13f79535-47bb-0310-9956-ffa450edef68 --- src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java index 3872e7381..ca54fa9f4 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java @@ -99,8 +99,8 @@ public final class ZipPackage extends OPCPackage { try { zis.close(); } catch (final IOException e2) { - e2.addSuppressed(e); - throw new IOException("Failed to close zip input stream while cleaning up", e2); + e.printStackTrace(); + throw new IOException("Failed to close zip input stream while cleaning up. " + e.getMessage(), e2); } throw new IOException("Failed to read zip entry source", e); } From 97b94f5dcd7beb2d89b1983fbba3c7e40f4923d0 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 17:25:03 +0000 Subject: [PATCH 109/157] javadocs git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760733 13f79535-47bb-0310-9956-ffa450edef68 --- src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java index ca54fa9f4..da053e6d1 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java @@ -89,6 +89,8 @@ public final class ZipPackage extends OPCPackage { * @throws IllegalArgumentException * If the specified input stream not an instance of * ZipInputStream. + * @throws IOException + * if input stream cannot be opened, read, or closed */ ZipPackage(InputStream in, PackageAccess access) throws IOException { super(access); From 9ac461596f5d7cd0e5abe9da99dd64c39721c750 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 17:48:00 +0000 Subject: [PATCH 110/157] bug 60128: add test-data/openxml4j/invalid.xlsx to expected failures for integration test git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760735 13f79535-47bb-0310-9956-ffa450edef68 --- src/integrationtest/org/apache/poi/TestAllFiles.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/integrationtest/org/apache/poi/TestAllFiles.java b/src/integrationtest/org/apache/poi/TestAllFiles.java index 6183c185c..be3fb6636 100644 --- a/src/integrationtest/org/apache/poi/TestAllFiles.java +++ b/src/integrationtest/org/apache/poi/TestAllFiles.java @@ -240,6 +240,7 @@ public class TestAllFiles { EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_OnlyOneCorePropertiesPartFAIL.docx"); EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_UnauthorizedXMLLangAttributeFAIL.docx"); EXPECTED_FAILURES.add("openxml4j/OPCCompliance_DerivedPartNameFAIL.docx"); + EXPECTED_FAILURES.add("openxml4j/invalid.xlsx"); EXPECTED_FAILURES.add("spreadsheet/54764-2.xlsx"); // see TestXSSFBugs.bug54764() EXPECTED_FAILURES.add("spreadsheet/54764.xlsx"); // see TestXSSFBugs.bug54764() EXPECTED_FAILURES.add("spreadsheet/Simple.xlsb"); From 3445bcbc8fb06d94c1164d848e26624cadc456aa Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 17:55:51 +0000 Subject: [PATCH 111/157] add compile-examples dependency to compile-integration. o.a.p.xssf.eventusermodel.XLSX2CSV and o.a.p.xssf.eventusermodel.examples.FromHowTo are needed for o.a.p.stress.XSSFFileHandler. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760736 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index 633607618..d3623395d 100644 --- a/build.xml +++ b/build.xml @@ -1092,7 +1092,7 @@ under the License. - + Date: Wed, 14 Sep 2016 18:41:21 +0000 Subject: [PATCH 112/157] bug 60128: exclude openxml4j/invalid.xlsx from additional integration (stress) tests git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760743 13f79535-47bb-0310-9956-ffa450edef68 --- src/integrationtest/org/apache/poi/TestAllFiles.java | 5 ++++- .../org/apache/poi/stress/XSSFFileHandler.java | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/integrationtest/org/apache/poi/TestAllFiles.java b/src/integrationtest/org/apache/poi/TestAllFiles.java index be3fb6636..e364c9f28 100644 --- a/src/integrationtest/org/apache/poi/TestAllFiles.java +++ b/src/integrationtest/org/apache/poi/TestAllFiles.java @@ -298,7 +298,10 @@ public class TestAllFiles { List files = new ArrayList(); for(String file : scanner.getIncludedFiles()) { file = file.replace('\\', '/'); // ... failures/handlers lookup doesn't work on windows otherwise - if (IGNORED.contains(file)) continue; + if (IGNORED.contains(file)) { + System.out.println("Ignoring " + file); + continue; + } FileHandler handler = HANDLERS.get(getExtension(file)); files.add(new Object[] { file, handler }); diff --git a/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java b/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java index be6039707..0e24f0486 100644 --- a/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java +++ b/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java @@ -30,6 +30,7 @@ import javax.xml.transform.TransformerException; import org.apache.poi.POIXMLException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException; import org.apache.poi.openxml4j.exceptions.OLE2NotOfficeXmlFileException; import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.opc.OPCPackage; @@ -134,6 +135,9 @@ public class XSSFFileHandler extends SpreadsheetHandler { EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/Simple.xlsb"); // TODO: good to ignore? EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/sample-beta.xlsx"); + + // corrupt/invalid + EXPECTED_ADDITIONAL_FAILURES.add("openxml4j/invalid.xlsx"); } @SuppressWarnings("resource") From 03b5dc68ebc6e23402d0163b5de42c04d774f3a6 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 19:24:49 +0000 Subject: [PATCH 113/157] bug 60128: remove forbidden-api Exception.printStackTrace() git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760744 13f79535-47bb-0310-9956-ffa450edef68 --- src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java index da053e6d1..33333c3c5 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java @@ -101,7 +101,6 @@ public final class ZipPackage extends OPCPackage { try { zis.close(); } catch (final IOException e2) { - e.printStackTrace(); throw new IOException("Failed to close zip input stream while cleaning up. " + e.getMessage(), e2); } throw new IOException("Failed to read zip entry source", e); From 91f2d5680e81b8c5ecff441d83c2581ae5c4db41 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 21:32:34 +0000 Subject: [PATCH 114/157] declare methods throw runtime exceptions for IDE hints git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760784 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/ss/usermodel/FormulaError.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java/org/apache/poi/ss/usermodel/FormulaError.java b/src/java/org/apache/poi/ss/usermodel/FormulaError.java index 583ca06d9..fa102299e 100644 --- a/src/java/org/apache/poi/ss/usermodel/FormulaError.java +++ b/src/java/org/apache/poi/ss/usermodel/FormulaError.java @@ -166,19 +166,19 @@ public enum FormulaError { return false; } - public static FormulaError forInt(byte type){ + public static FormulaError forInt(byte type) throws IllegalArgumentException { FormulaError err = bmap.get(type); if(err == null) throw new IllegalArgumentException("Unknown error type: " + type); return err; } - public static FormulaError forInt(int type){ + public static FormulaError forInt(int type) throws IllegalArgumentException { FormulaError err = imap.get(type); if(err == null) err = bmap.get((byte)type); if(err == null) throw new IllegalArgumentException("Unknown error type: " + type); return err; } - public static FormulaError forString(String code){ + public static FormulaError forString(String code) throws IllegalArgumentException { FormulaError err = smap.get(code); if(err == null) throw new IllegalArgumentException("Unknown error code: " + code); return err; From 1de973e2a7c641b3ce4c46c4f691148233992709 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 21:44:06 +0000 Subject: [PATCH 115/157] declare methods throw runtime exceptions for IDE hints git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760798 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/poi/xssf/usermodel/XSSFCell.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) 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 7d2d6d25b..c7932d167 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java @@ -827,7 +827,7 @@ public final class XSSFCell implements Cell { * @throws IllegalStateException if the cell type returned by {@link #getCellTypeEnum()} isn't {@link CellType#ERROR} * @see FormulaError */ - public String getErrorCellString() { + public String getErrorCellString() throws IllegalStateException { CellType cellType = getBaseCellType(true); if(cellType != CellType.ERROR) throw typeMismatch(CellType.ERROR, cellType, false); @@ -845,13 +845,16 @@ public final class XSSFCell implements Cell { * @see FormulaError */ @Override - public byte getErrorCellValue() { + public byte getErrorCellValue() throws IllegalStateException { String code = getErrorCellString(); if (code == null) { return 0; } - - return FormulaError.forString(code).getCode(); + try { + return FormulaError.forString(code).getCode(); + } catch (final IllegalArgumentException e) { + throw new IllegalStateException("Unexpected error code", e); + } } /** From 16acf81b9e9dd6ae74473be2ce636e592d0d203a Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 22:01:11 +0000 Subject: [PATCH 116/157] convert TestXSSFPivotTable to junit4 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760806 13f79535-47bb-0310-9956-ffa450edef68 --- .../xssf/usermodel/AllXSSFUsermodelTests.java | 2 +- .../xssf/usermodel/TestXSSFPivotTable.java | 24 +++++++++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/AllXSSFUsermodelTests.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/AllXSSFUsermodelTests.java index 96b363283..6ecad0a74 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/AllXSSFUsermodelTests.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/AllXSSFUsermodelTests.java @@ -59,7 +59,7 @@ import org.junit.runners.Suite; TestXSSFSheetComments.class, TestColumnHelper.class, TestHeaderFooterHelper.class, - TestXSSFPivotTable.class, + //TestXSSFPivotTable.class, //converted to junit4 TestForkedEvaluator.class }) public final class AllXSSFUsermodelTests { diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTable.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTable.java index 55fe4a4fa..320ae68c9 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTable.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTable.java @@ -16,6 +16,9 @@ ==================================================================== */ package org.apache.poi.xssf.usermodel; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.DataConsolidateFunction; @@ -23,20 +26,20 @@ import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.AreaReference; import org.apache.poi.ss.util.CellReference; +import org.junit.Before; +import org.junit.Test; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageField; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageFields; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotFields; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotTableDefinition; import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataConsolidateFunction; -import junit.framework.TestCase; - -public class TestXSSFPivotTable extends TestCase { +public class TestXSSFPivotTable { private XSSFPivotTable pivotTable; private XSSFPivotTable offsetPivotTable; private Cell offsetOuterCell; - @Override + @Before public void setUp(){ Workbook wb = new XSSFWorkbook(); XSSFSheet sheet = (XSSFSheet) wb.createSheet(); @@ -119,6 +122,7 @@ public class TestXSSFPivotTable extends TestCase { * Verify that when creating a row label it's created on the correct row * and the count is increased by one. */ + @Test public void testAddRowLabelToPivotTable() { int columnIndex = 0; @@ -141,6 +145,7 @@ public class TestXSSFPivotTable extends TestCase { /** * Verify that it's not possible to create a row label outside of the referenced area. */ + @Test public void testAddRowLabelOutOfRangeThrowsException() { int columnIndex = 5; @@ -155,6 +160,7 @@ public class TestXSSFPivotTable extends TestCase { /** * Verify that when creating one column label, no col fields are being created. */ + @Test public void testAddOneColumnLabelToPivotTableDoesNotCreateColField() { int columnIndex = 0; @@ -167,6 +173,7 @@ public class TestXSSFPivotTable extends TestCase { /** * Verify that it's possible to create three column labels with different DataConsolidateFunction */ + @Test public void testAddThreeDifferentColumnLabelsToPivotTable() { int columnOne = 0; int columnTwo = 1; @@ -184,6 +191,7 @@ public class TestXSSFPivotTable extends TestCase { /** * Verify that it's possible to create three column labels with the same DataConsolidateFunction */ + @Test public void testAddThreeSametColumnLabelsToPivotTable() { int columnOne = 0; int columnTwo = 1; @@ -200,6 +208,7 @@ public class TestXSSFPivotTable extends TestCase { /** * Verify that when creating two column labels, a col field is being created and X is set to -2. */ + @Test public void testAddTwoColumnLabelsToPivotTable() { int columnOne = 0; int columnTwo = 1; @@ -214,6 +223,7 @@ public class TestXSSFPivotTable extends TestCase { /** * Verify that a data field is created when creating a data column */ + @Test public void testColumnLabelCreatesDataField() { int columnIndex = 0; @@ -229,6 +239,7 @@ public class TestXSSFPivotTable extends TestCase { /** * Verify that it's possible to set a custom name when creating a data column */ + @Test public void testColumnLabelSetCustomName() { int columnIndex = 0; @@ -245,6 +256,7 @@ public class TestXSSFPivotTable extends TestCase { /** * Verify that it's not possible to create a column label outside of the referenced area. */ + @Test public void testAddColumnLabelOutOfRangeThrowsException() { int columnIndex = 5; @@ -260,6 +272,7 @@ public class TestXSSFPivotTable extends TestCase { * Verify when creating a data column set to a data field, the data field with the corresponding * column index will be set to true. */ + @Test public void testAddDataColumn() { int columnIndex = 0; boolean isDataField = true; @@ -272,6 +285,7 @@ public class TestXSSFPivotTable extends TestCase { /** * Verify that it's not possible to create a data column outside of the referenced area. */ + @Test public void testAddDataColumnOutOfRangeThrowsException() { int columnIndex = 5; boolean isDataField = true; @@ -301,6 +315,7 @@ public class TestXSSFPivotTable extends TestCase { /** * Verify that it's not possible to create a new filter outside of the referenced area. */ + @Test public void testAddReportFilterOutOfRangeThrowsException() { int columnIndex = 5; try { @@ -315,6 +330,7 @@ public class TestXSSFPivotTable extends TestCase { * Verify that the Pivot Table operates only within the referenced area, even when the * first column of the referenced area is not index 0. */ + @Test public void testAddDataColumnWithOffsetData() { offsetPivotTable.addColumnLabel(DataConsolidateFunction.SUM, 1); assertEquals(CellType.NUMERIC, offsetOuterCell.getCellTypeEnum()); From 39752a5643c6fb9ed97de02764b17ae24ce70a1c Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 22:11:14 +0000 Subject: [PATCH 117/157] make sure workbook can be written out and read back for all TestXSSFPivotTable tests git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760811 13f79535-47bb-0310-9956-ffa450edef68 --- .../xssf/usermodel/TestXSSFPivotTable.java | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTable.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTable.java index 320ae68c9..3248f2e1e 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTable.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTable.java @@ -19,13 +19,17 @@ package org.apache.poi.xssf.usermodel; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; +import java.io.IOException; + +import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.DataConsolidateFunction; import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.AreaReference; import org.apache.poi.ss.util.CellReference; +import org.apache.poi.xssf.XSSFITestDataProvider; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageField; @@ -35,14 +39,16 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotTableDefinitio import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataConsolidateFunction; public class TestXSSFPivotTable { + private static final XSSFITestDataProvider _testDataProvider = XSSFITestDataProvider.instance; + private XSSFWorkbook wb; private XSSFPivotTable pivotTable; private XSSFPivotTable offsetPivotTable; private Cell offsetOuterCell; @Before public void setUp(){ - Workbook wb = new XSSFWorkbook(); - XSSFSheet sheet = (XSSFSheet) wb.createSheet(); + wb = new XSSFWorkbook(); + XSSFSheet sheet = wb.createSheet(); Row row1 = sheet.createRow(0); // Create a cell and put a value in it. @@ -75,10 +81,10 @@ public class TestXSSFPivotTable { Cell cell12 = row1.createCell(3); cell12.setCellValue(12.12); - AreaReference source = new AreaReference("A1:C2"); + AreaReference source = new AreaReference("A1:C2", _testDataProvider.getSpreadsheetVersion()); pivotTable = sheet.createPivotTable(source, new CellReference("H5")); - XSSFSheet offsetSheet = (XSSFSheet) wb.createSheet(); + XSSFSheet offsetSheet = wb.createSheet(); Row tableRow_1 = offsetSheet.createRow(1); offsetOuterCell = tableRow_1.createCell(1); @@ -117,6 +123,13 @@ public class TestXSSFPivotTable { AreaReference offsetSource = new AreaReference(new CellReference("C2"), new CellReference("E4")); offsetPivotTable = offsetSheet.createPivotTable(offsetSource, new CellReference("C6")); } + + @After + public void tearDown() throws IOException { + XSSFWorkbook wb2 = _testDataProvider.writeOutAndReadBack(wb); + wb.close(); + wb2.close(); + } /** * Verify that when creating a row label it's created on the correct row From 5b79b4da902c7c8414de5d0715618cac270582f3 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 14 Sep 2016 22:43:08 +0000 Subject: [PATCH 118/157] sheet names are case insensitive git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760814 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/xssf/usermodel/XSSFSheet.java | 12 +++++++----- .../xssf/usermodel/TestXSSFPivotTable.java | 19 ++++++++++++++++++- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java index 98711c9dd..d72dca445 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java @@ -4165,9 +4165,9 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { * @return The pivot table */ @Beta - public XSSFPivotTable createPivotTable(AreaReference source, CellReference position, Sheet sourceSheet){ - - if(source.getFirstCell().getSheetName() != null && !source.getFirstCell().getSheetName().equals(sourceSheet.getSheetName())) { + public XSSFPivotTable createPivotTable(AreaReference source, CellReference position, Sheet sourceSheet) { + final String sourceSheetName = source.getFirstCell().getSheetName(); + if(sourceSheetName != null && !sourceSheetName.equalsIgnoreCase(sourceSheet.getSheetName())) { throw new IllegalArgumentException("The area is referenced in another sheet than the " + "defined source sheet " + sourceSheet.getSheetName() + "."); } @@ -4193,8 +4193,10 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { */ @Beta public XSSFPivotTable createPivotTable(AreaReference source, CellReference position){ - if(source.getFirstCell().getSheetName() != null && !source.getFirstCell().getSheetName().equals(this.getSheetName())) { - return createPivotTable(source, position, getWorkbook().getSheet(source.getFirstCell().getSheetName())); + final String sourceSheetName = source.getFirstCell().getSheetName(); + if(sourceSheetName != null && !sourceSheetName.equalsIgnoreCase(this.getSheetName())) { + final XSSFSheet sourceSheet = getWorkbook().getSheet(sourceSheetName); + return createPivotTable(source, position, sourceSheet); } return createPivotTable(source, position, this); } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTable.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTable.java index 3248f2e1e..851ca33d6 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTable.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTable.java @@ -17,11 +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.fail; import java.io.IOException; -import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.DataConsolidateFunction; @@ -350,4 +350,21 @@ public class TestXSSFPivotTable { offsetPivotTable.addColumnLabel(DataConsolidateFunction.SUM, 0); } + + @Test + public void testPivotTableSheetNamesAreCaseInsensitive() { + wb.setSheetName(0, "original"); + wb.setSheetName(1, "offset"); + XSSFSheet original = wb.getSheet("OriginaL"); + XSSFSheet offset = wb.getSheet("OffseT"); + // assume sheets are accessible via case-insensitive name + assertNotNull(original); + assertNotNull(offset); + + AreaReference source = new AreaReference("ORIGinal!A1:C2", _testDataProvider.getSpreadsheetVersion()); + // create a pivot table on the same sheet, case insensitive + original.createPivotTable(source, new CellReference("W1")); + // create a pivot table on a different sheet, case insensitive + offset.createPivotTable(source, new CellReference("W1")); + } } From 0784ab530aa06b4510d2c040886a0b622154b4de Mon Sep 17 00:00:00 2001 From: Tim Allison Date: Thu, 15 Sep 2016 00:19:52 +0000 Subject: [PATCH 119/157] POI 60140 Prevent unnecessary memory usage -- no need to cache HeapByteBuffer in FileBackedDataSource, thanks to Luis Filipe Nassif for diagnosing this git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760816 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java b/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java index 1b8660644..47637daa3 100644 --- a/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java +++ b/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java @@ -94,6 +94,8 @@ public class FileBackedDataSource extends DataSource { if (writable) { dst = channel.map(FileChannel.MapMode.READ_WRITE, position, length); worked = 0; + // remember the buffer for cleanup if necessary + buffersToClean.add(dst); } else { // Read channel.position(position); @@ -109,9 +111,6 @@ public class FileBackedDataSource extends DataSource { // Ready it for reading dst.position(0); - // remember the buffer for cleanup if necessary - buffersToClean.add(dst); - // All done return dst; } From 008a26d1bfb79a7ff5d74cb4b96e5fc013cda325 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Fri, 16 Sep 2016 00:32:40 +0000 Subject: [PATCH 120/157] bug 59705: consolidate bounds checking of column index into a helper method git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760986 13f79535-47bb-0310-9956-ffa450edef68 --- .../ss/usermodel/DataConsolidateFunction.java | 4 +- .../poi/xssf/usermodel/XSSFPivotTable.java | 74 +++++++++++-------- 2 files changed, 44 insertions(+), 34 deletions(-) diff --git a/src/java/org/apache/poi/ss/usermodel/DataConsolidateFunction.java b/src/java/org/apache/poi/ss/usermodel/DataConsolidateFunction.java index f54fb4f7b..d40a8d11c 100644 --- a/src/java/org/apache/poi/ss/usermodel/DataConsolidateFunction.java +++ b/src/java/org/apache/poi/ss/usermodel/DataConsolidateFunction.java @@ -38,8 +38,8 @@ public enum DataConsolidateFunction { VAR(10, "Var"), VARP(11, "Varp"); - private int value; - private String name; + private final int value; + private final String name; DataConsolidateFunction(int value, String name) { this.value = value; diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java index 9f6864919..bf85f65de 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java @@ -30,6 +30,7 @@ import javax.xml.namespace.QName; import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackageRelationship; +import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.DataConsolidateFunction; @@ -213,24 +214,43 @@ public class XSSFPivotTable extends POIXMLDocumentPart { } protected AreaReference getPivotArea() { - AreaReference pivotArea = new AreaReference(getPivotCacheDefinition(). - getCTPivotCacheDefinition().getCacheSource().getWorksheetSource().getRef()); + AreaReference pivotArea = new AreaReference( + getPivotCacheDefinition() + .getCTPivotCacheDefinition() + .getCacheSource() + .getWorksheetSource() + .getRef(), + SpreadsheetVersion.EXCEL2007); return pivotArea; } + + /** + * Verify column index (relative to first column in pivot area) is within the + * pivot area + * + * @param columnIndex + * @throws IndexOutOfBoundsException + */ + private void checkColumnIndex(int columnIndex) throws IndexOutOfBoundsException { + AreaReference pivotArea = getPivotArea(); + int size = pivotArea.getLastCell().getCol() - pivotArea.getFirstCell().getCol() + 1; + + if (columnIndex < 0 || columnIndex >= size) { + throw new IndexOutOfBoundsException("Column Index: " + columnIndex + ", Size: " + size); + } + } /** * Add a row label using data from the given column. - * @param columnIndex the index of the column to be used as row label. + * @param columnIndex the index of the source column to be used as row label. + * {@code columnIndex} is 0-based indexed and relative to the first column in the source. */ @Beta public void addRowLabel(int columnIndex) { + checkColumnIndex(columnIndex); + AreaReference pivotArea = getPivotArea(); - int lastRowIndex = pivotArea.getLastCell().getRow() - pivotArea.getFirstCell().getRow(); - int lastColIndex = pivotArea.getLastCell().getCol() - pivotArea.getFirstCell().getCol(); - - if(columnIndex > lastColIndex) { - throw new IndexOutOfBoundsException(); - } + final int lastRowIndex = pivotArea.getLastCell().getRow() - pivotArea.getFirstCell().getRow(); CTPivotFields pivotFields = pivotTableDefinition.getPivotFields(); CTPivotField pivotField = CTPivotField.Factory.newInstance(); @@ -238,7 +258,7 @@ public class XSSFPivotTable extends POIXMLDocumentPart { pivotField.setAxis(STAxis.AXIS_ROW); pivotField.setShowAll(false); - for(int i = 0; i <= lastRowIndex; i++) { + for (int i = 0; i <= lastRowIndex; i++) { items.addNewItem().setT(STItemType.DEFAULT); } items.setCount(items.sizeOfItemArray()); @@ -270,7 +290,8 @@ public class XSSFPivotTable extends POIXMLDocumentPart { /** * Add a column label using data from the given column and specified function - * @param columnIndex the index of the column to be used as column label. + * @param columnIndex the index of the source column to be used as column label. + * {@code columnIndex} is 0-based indexed and relative to the first column in the source. * @param function the function to be used on the data * The following functions exists: * Sum, Count, Average, Max, Min, Product, Count numbers, StdDev, StdDevp, Var, Varp @@ -278,12 +299,7 @@ public class XSSFPivotTable extends POIXMLDocumentPart { */ @Beta public void addColumnLabel(DataConsolidateFunction function, int columnIndex, String valueFieldName) { - AreaReference pivotArea = getPivotArea(); - int lastColIndex = pivotArea.getLastCell().getCol() - pivotArea.getFirstCell().getCol(); - - if(columnIndex > lastColIndex && columnIndex < 0) { - throw new IndexOutOfBoundsException(); - } + checkColumnIndex(columnIndex); addDataColumn(columnIndex, true); addDataField(function, columnIndex, valueFieldName); @@ -303,7 +319,8 @@ public class XSSFPivotTable extends POIXMLDocumentPart { /** * Add a column label using data from the given column and specified function - * @param columnIndex the index of the column to be used as column label. + * @param columnIndex the index of the source column to be used as column label + * {@code columnIndex} is 0-based indexed and relative to the first column in the source.. * @param function the function to be used on the data * The following functions exists: * Sum, Count, Average, Max, Min, Product, Count numbers, StdDev, StdDevp, Var, Varp @@ -323,12 +340,10 @@ public class XSSFPivotTable extends POIXMLDocumentPart { */ @Beta private void addDataField(DataConsolidateFunction function, int columnIndex, String valueFieldName) { + checkColumnIndex(columnIndex); + AreaReference pivotArea = getPivotArea(); - int lastColIndex = pivotArea.getLastCell().getCol() - pivotArea.getFirstCell().getCol(); - - if(columnIndex > lastColIndex && columnIndex < 0) { - throw new IndexOutOfBoundsException(); - } + CTDataFields dataFields; if(pivotTableDefinition.getDataFields() != null) { dataFields = pivotTableDefinition.getDataFields(); @@ -352,11 +367,8 @@ public class XSSFPivotTable extends POIXMLDocumentPart { */ @Beta public void addDataColumn(int columnIndex, boolean isDataField) { - AreaReference pivotArea = getPivotArea(); - int lastColIndex = pivotArea.getLastCell().getCol() - pivotArea.getFirstCell().getCol(); - if(columnIndex > lastColIndex && columnIndex < 0) { - throw new IndexOutOfBoundsException(); - } + checkColumnIndex(columnIndex); + CTPivotFields pivotFields = pivotTableDefinition.getPivotFields(); CTPivotField pivotField = CTPivotField.Factory.newInstance(); @@ -371,13 +383,11 @@ public class XSSFPivotTable extends POIXMLDocumentPart { */ @Beta public void addReportFilter(int columnIndex) { + checkColumnIndex(columnIndex); + AreaReference pivotArea = getPivotArea(); - int lastColIndex = pivotArea.getLastCell().getCol() - pivotArea.getFirstCell().getCol(); int lastRowIndex = pivotArea.getLastCell().getRow() - pivotArea.getFirstCell().getRow(); - if(columnIndex > lastColIndex && columnIndex < 0) { - throw new IndexOutOfBoundsException(); - } CTPivotFields pivotFields = pivotTableDefinition.getPivotFields(); CTPivotField pivotField = CTPivotField.Factory.newInstance(); From d6a7b7d49dbbef6ec58604ab2c5e3e4f55b3cf0e Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Fri, 16 Sep 2016 00:41:25 +0000 Subject: [PATCH 121/157] +svnprops eol-style=native git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760987 13f79535-47bb-0310-9956-ffa450edef68 From 75e2fc77df086dfd062e143f174b68a53393aeee Mon Sep 17 00:00:00 2001 From: David North Date: Sat, 17 Sep 2016 07:49:02 +0000 Subject: [PATCH 122/157] release prepare for 3.15 - updating build.xml and status.xml git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761142 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index d3623395d..4392d39e1 100644 --- a/build.xml +++ b/build.xml @@ -40,7 +40,7 @@ under the License. The Apache POI project Ant build. - + From 4a3571bf566f4e2dbeeed4daa09828470cb37775 Mon Sep 17 00:00:00 2001 From: David North Date: Sat, 17 Sep 2016 07:49:52 +0000 Subject: [PATCH 123/157] prepare for 3.16-beta1 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761144 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index 4392d39e1..d3623395d 100644 --- a/build.xml +++ b/build.xml @@ -40,7 +40,7 @@ under the License. The Apache POI project Ant build. - + From 3b5bd602bdafc77a57affdf03cf4d76fce244d73 Mon Sep 17 00:00:00 2001 From: David North Date: Sat, 17 Sep 2016 08:50:18 +0000 Subject: [PATCH 124/157] release prepare for 3.15 - updating build.xml and status.xml git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761161 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index d3623395d..4392d39e1 100644 --- a/build.xml +++ b/build.xml @@ -40,7 +40,7 @@ under the License. The Apache POI project Ant build. - + From be5158c813580a9df11a4bef646e986bcc640f26 Mon Sep 17 00:00:00 2001 From: David North Date: Sat, 17 Sep 2016 09:33:43 +0000 Subject: [PATCH 125/157] prepare for 3.16-beta1 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761167 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index 4392d39e1..d3623395d 100644 --- a/build.xml +++ b/build.xml @@ -40,7 +40,7 @@ under the License. The Apache POI project Ant build. - + From 676ca76fd90a279c0dcce24fae810d85c00e7919 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Tue, 20 Sep 2016 07:55:13 +0000 Subject: [PATCH 126/157] bug 59853: support PivotTables with named structured references; patch from Greg Woolsey git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761537 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 +- .../usermodel/XSSFPivotCacheDefinition.java | 40 ++++++- .../poi/xssf/usermodel/XSSFPivotTable.java | 33 +++--- .../apache/poi/xssf/usermodel/XSSFSheet.java | 104 ++++++++++++++-- ...Table.java => BaseTestXSSFPivotTable.java} | 107 +++-------------- .../usermodel/TestXSSFPivotTableName.java | 112 ++++++++++++++++++ .../xssf/usermodel/TestXSSFPivotTableRef.java | 111 +++++++++++++++++ 7 files changed, 394 insertions(+), 115 deletions(-) rename src/ooxml/testcases/org/apache/poi/xssf/usermodel/{TestXSSFPivotTable.java => BaseTestXSSFPivotTable.java} (74%) create mode 100644 src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTableName.java create mode 100644 src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTableRef.java diff --git a/build.xml b/build.xml index d3623395d..bdf0033f3 100644 --- a/build.xml +++ b/build.xml @@ -78,7 +78,7 @@ under the License. JVM system properties for running tests, user.language and user.country are required as we have locale-sensitive formatters --> - + diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheDefinition.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheDefinition.java index 8ab465aff..26735c782 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheDefinition.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheDefinition.java @@ -28,10 +28,13 @@ import javax.xml.namespace.QName; import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackageRelationship; +import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; +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.AreaReference; import org.apache.poi.ss.util.CellReference; import org.apache.poi.util.Beta; @@ -41,6 +44,7 @@ import org.apache.xmlbeans.XmlOptions; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCacheField; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCacheFields; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotCacheDefinition; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheetSource; public class XSSFPivotCacheDefinition extends POIXMLDocumentPart{ @@ -116,6 +120,40 @@ public class XSSFPivotCacheDefinition extends POIXMLDocumentPart{ out.close(); } + /** + * Find the 2D base data area for the pivot table, either from its direct reference or named table/range. + * @return AreaReference representing the current area defined by the pivot table + * @throws IllegalArgumentException if the ref attribute is not contiguous or the name attribute is not found. + */ + @Beta + public AreaReference getPivotArea(Workbook wb) throws IllegalArgumentException { + final CTWorksheetSource wsSource = ctPivotCacheDefinition.getCacheSource().getWorksheetSource(); + + final String ref = wsSource.getRef(); + final String name = wsSource.getName(); + + if (ref == null && name == null) throw new IllegalArgumentException("Pivot cache must reference an area, named range, or table."); + + // this is the XML format, so tell the reference that. + if (ref != null) return new AreaReference(ref, SpreadsheetVersion.EXCEL2007); + + if (name != null) { + // named range or table? + final Name range = wb.getName(name); + if (range != null) return new AreaReference(range.getRefersToFormula(), SpreadsheetVersion.EXCEL2007); + // not a named range, check for a table. + // do this second, as tables are sheet-specific, but named ranges are not, and may not have a sheet name given. + final XSSFSheet sheet = (XSSFSheet) wb.getSheet(wsSource.getSheet()); + for (XSSFTable table : sheet.getTables()) { + if (table.getName().equals(name)) { //case-sensitive? + return new AreaReference(table.getStartCellReference(), table.getEndCellReference()); + } + } + } + + throw new IllegalArgumentException("Name '" + name + "' was not found."); + } + /** * Generates a cache field for each column in the reference area for the pivot table. * @param sheet The sheet where the data i collected from @@ -123,7 +161,7 @@ public class XSSFPivotCacheDefinition extends POIXMLDocumentPart{ @Beta protected void createCacheFields(Sheet sheet) { //Get values for start row, start and end column - AreaReference ar = new AreaReference(ctPivotCacheDefinition.getCacheSource().getWorksheetSource().getRef()); + AreaReference ar = getPivotArea(sheet.getWorkbook()); CellReference firstCell = ar.getFirstCell(); CellReference lastCell = ar.getLastCell(); int columnStart = firstCell.getCol(); diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java index bf85f65de..e08af900b 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java @@ -30,11 +30,11 @@ import javax.xml.namespace.QName; import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.DataConsolidateFunction; import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.AreaReference; import org.apache.poi.ss.util.CellReference; import org.apache.poi.util.Beta; @@ -214,13 +214,8 @@ public class XSSFPivotTable extends POIXMLDocumentPart { } protected AreaReference getPivotArea() { - AreaReference pivotArea = new AreaReference( - getPivotCacheDefinition() - .getCTPivotCacheDefinition() - .getCacheSource() - .getWorksheetSource() - .getRef(), - SpreadsheetVersion.EXCEL2007); + final Workbook wb = getDataSheet().getWorkbook(); + AreaReference pivotArea = getPivotCacheDefinition().getPivotArea(wb); return pivotArea; } @@ -419,12 +414,14 @@ public class XSSFPivotTable extends POIXMLDocumentPart { /** * Creates cacheSource and workSheetSource for pivot table and sets the source reference as well assets the location of the pivot table - * @param source Source for data for pivot table + * @param sourceRef Source for data for pivot table - mutually exclusive with sourceName + * @param sourceName Source for data for pivot table - mutually exclusive with sourceRef * @param position Position for pivot table in sheet * @param sourceSheet Sheet where the source will be collected from */ @Beta - protected void createSourceReferences(AreaReference source, CellReference position, Sheet sourceSheet){ + protected void createSourceReferences(CellReference position, Sheet sourceSheet, PivotTableReferenceConfigurator refConfig){ + //Get cell one to the right and one down from position, add both to AreaReference and set pivot table location. AreaReference destination = new AreaReference(position, new CellReference(position.getRow()+1, position.getCol()+1)); @@ -448,9 +445,8 @@ public class XSSFPivotTable extends POIXMLDocumentPart { worksheetSource.setSheet(sourceSheet.getSheetName()); setDataSheet(sourceSheet); - String[] firstCell = source.getFirstCell().getCellRefParts(); - String[] lastCell = source.getLastCell().getCellRefParts(); - worksheetSource.setRef(firstCell[2]+firstCell[1]+':'+lastCell[2]+lastCell[1]); + refConfig.configureReference(worksheetSource); + if (worksheetSource.getName() == null && worksheetSource.getRef() == null) throw new IllegalArgumentException("Pivot table source area reference or name must be specified."); } @Beta @@ -465,11 +461,20 @@ public class XSSFPivotTable extends POIXMLDocumentPart { int firstColumn = sourceArea.getFirstCell().getCol(); int lastColumn = sourceArea.getLastCell().getCol(); CTPivotField pivotField; - for(int i = 0; i<=lastColumn-firstColumn; i++) { + for(int i = firstColumn; i<=lastColumn; i++) { pivotField = pivotFields.addNewPivotField(); pivotField.setDataField(false); pivotField.setShowAll(false); } pivotFields.setCount(pivotFields.sizeOfPivotFieldArray()); } + + protected static interface PivotTableReferenceConfigurator { + + /** + * Configure the name or area reference for the pivot table + * @param wsSource CTWorksheetSource that needs the pivot source reference assignment + */ + public void configureReference(CTWorksheetSource wsSource); + } } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java index d72dca445..8b9746489 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java @@ -64,8 +64,10 @@ import org.apache.poi.ss.usermodel.Footer; import org.apache.poi.ss.usermodel.Header; import org.apache.poi.ss.usermodel.IgnoredErrorType; import org.apache.poi.ss.usermodel.IndexedColors; +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.Table; import org.apache.poi.ss.util.AreaReference; import org.apache.poi.ss.util.CellAddress; import org.apache.poi.ss.util.CellRangeAddress; @@ -80,6 +82,7 @@ import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; import org.apache.poi.util.Removal; import org.apache.poi.xssf.model.CommentsTable; +import org.apache.poi.xssf.usermodel.XSSFPivotTable.PivotTableReferenceConfigurator; import org.apache.poi.xssf.usermodel.helpers.ColumnHelper; import org.apache.poi.xssf.usermodel.helpers.XSSFIgnoredErrorHelper; import org.apache.poi.xssf.usermodel.helpers.XSSFRowShifter; @@ -4158,27 +4161,56 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { } /** - * Create a pivot table and set area of source, source sheet and a position for pivot table - * @param source Area from where data will be collected - * @param position A reference to the cell where the table will start - * @param sourceSheet The sheet where source will be collected from + * Create a pivot table using the AreaReference range on sourceSheet, at the given position. + * If the source reference contains a sheet name, it must match the sourceSheet + * @param source location of pivot data + * @param position A reference to the top left cell where the pivot table will start + * @param sourceSheet The sheet containing the source data, if the source reference doesn't contain a sheet name + * @throws IllegalArgumentException if source references a sheet different than sourceSheet * @return The pivot table */ @Beta - public XSSFPivotTable createPivotTable(AreaReference source, CellReference position, Sheet sourceSheet) { + public XSSFPivotTable createPivotTable(final AreaReference source, CellReference position, Sheet sourceSheet) { final String sourceSheetName = source.getFirstCell().getSheetName(); if(sourceSheetName != null && !sourceSheetName.equalsIgnoreCase(sourceSheet.getSheetName())) { throw new IllegalArgumentException("The area is referenced in another sheet than the " + "defined source sheet " + sourceSheet.getSheetName() + "."); } + + return createPivotTable(position, sourceSheet, new PivotTableReferenceConfigurator() { + public void configureReference(CTWorksheetSource wsSource) { + final String[] firstCell = source.getFirstCell().getCellRefParts(); + final String firstRow = firstCell[1]; + final String firstCol = firstCell[2]; + final String[] lastCell = source.getLastCell().getCellRefParts(); + final String lastRow = lastCell[1]; + final String lastCol = lastCell[2]; + final String ref = firstCol+firstRow+':'+lastCol+lastRow; //or just source.formatAsString() + wsSource.setRef(ref); + } + }); + } + + /** + * Create a pivot table using the AreaReference or named/table range on sourceSheet, at the given position. + * If the source reference contains a sheet name, it must match the sourceSheet. + * @param sourceRef location of pivot data - mutually exclusive with SourceName + * @param sourceName range or table name for pivot data - mutually exclusive with SourceRef + * @param position A reference to the top left cell where the pivot table will start + * @param sourceSheet The sheet containing the source data, if the source reference doesn't contain a sheet name + * @throws IllegalArgumentException if source references a sheet different than sourceSheet + * @return The pivot table + */ + private XSSFPivotTable createPivotTable(CellReference position, Sheet sourceSheet, PivotTableReferenceConfigurator refConfig) { + XSSFPivotTable pivotTable = createPivotTable(); //Creates default settings for the pivot table pivotTable.setDefaultPivotTableDefinition(); //Set sources and references - pivotTable.createSourceReferences(source, position, sourceSheet); + pivotTable.createSourceReferences(position, sourceSheet, refConfig); - //Create cachefield/s and empty SharedItems + //Create cachefield/s and empty SharedItems - must be after creating references pivotTable.getPivotCacheDefinition().createCacheFields(sourceSheet); pivotTable.createDefaultDataColumns(); @@ -4186,9 +4218,10 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { } /** - * Create a pivot table and set area of source and a position for pivot table - * @param source Area from where data will be collected - * @param position A reference to the cell where the table will start + * Create a pivot table using the AreaReference range, at the given position. + * If the source reference contains a sheet name, that sheet is used, otherwise this sheet is assumed as the source sheet. + * @param source location of pivot data + * @param position A reference to the top left cell where the pivot table will start * @return The pivot table */ @Beta @@ -4201,6 +4234,57 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { return createPivotTable(source, position, this); } + /** + * Create a pivot table using the Name range reference on sourceSheet, at the given position. + * If the source reference contains a sheet name, it must match the sourceSheet + * @param source location of pivot data + * @param position A reference to the top left cell where the pivot table will start + * @param sourceSheet The sheet containing the source data, if the source reference doesn't contain a sheet name + * @throws IllegalArgumentException if source references a sheet different than sourceSheet + * @return The pivot table + */ + @Beta + public XSSFPivotTable createPivotTable(final Name source, CellReference position, Sheet sourceSheet) { + if(source.getSheetName() != null && !source.getSheetName().equals(sourceSheet.getSheetName())) { + throw new IllegalArgumentException("The named range references another sheet than the " + + "defined source sheet " + sourceSheet.getSheetName() + "."); + } + + return createPivotTable(position, sourceSheet, new PivotTableReferenceConfigurator() { + public void configureReference(CTWorksheetSource wsSource) { + wsSource.setName(source.getNameName()); + } + }); + } + + /** + * Create a pivot table using the Name range, at the given position. + * If the source reference contains a sheet name, that sheet is used, otherwise this sheet is assumed as the source sheet. + * @param source location of pivot data + * @param position A reference to the top left cell where the pivot table will start + * @return The pivot table + */ + @Beta + public XSSFPivotTable createPivotTable(Name source, CellReference position) { + return createPivotTable(source, position, getWorkbook().getSheet(source.getSheetName())); + } + + /** + * Create a pivot table using the Table, at the given position. + * Tables are required to have a sheet reference, so no additional logic around reference sheet is needed. + * @param source location of pivot data + * @param position A reference to the top left cell where the pivot table will start + * @return The pivot table + */ + @Beta + public XSSFPivotTable createPivotTable(final Table source, CellReference position) { + return createPivotTable(position, getWorkbook().getSheet(source.getSheetName()), new PivotTableReferenceConfigurator() { + public void configureReference(CTWorksheetSource wsSource) { + wsSource.setName(source.getName()); + } + }); + } + /** * Returns all the pivot tables for this Sheet */ diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTable.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/BaseTestXSSFPivotTable.java similarity index 74% rename from src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTable.java rename to src/ooxml/testcases/org/apache/poi/xssf/usermodel/BaseTestXSSFPivotTable.java index 851ca33d6..445812566 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTable.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/BaseTestXSSFPivotTable.java @@ -16,16 +16,13 @@ ==================================================================== */ package org.apache.poi.xssf.usermodel; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; +import static org.junit.Assert.*; import java.io.IOException; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.DataConsolidateFunction; -import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.util.AreaReference; import org.apache.poi.ss.util.CellReference; import org.apache.poi.xssf.XSSFITestDataProvider; @@ -38,97 +35,27 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotFields; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotTableDefinition; import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataConsolidateFunction; -public class TestXSSFPivotTable { +public abstract class BaseTestXSSFPivotTable { private static final XSSFITestDataProvider _testDataProvider = XSSFITestDataProvider.instance; - private XSSFWorkbook wb; - private XSSFPivotTable pivotTable; - private XSSFPivotTable offsetPivotTable; - private Cell offsetOuterCell; + protected XSSFWorkbook wb; + protected XSSFPivotTable pivotTable; + protected XSSFPivotTable offsetPivotTable; + protected Cell offsetOuterCell; + /** + * required to set up the test pivot tables and cell reference, either by name or reference. + * @see junit.framework.TestCase#setUp() + */ @Before - public void setUp(){ - wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); - - Row row1 = sheet.createRow(0); - // Create a cell and put a value in it. - Cell cell = row1.createCell(0); - cell.setCellValue("Names"); - Cell cell2 = row1.createCell(1); - cell2.setCellValue("#"); - Cell cell7 = row1.createCell(2); - cell7.setCellValue("Data"); - Cell cell10 = row1.createCell(3); - cell10.setCellValue("Value"); - - Row row2 = sheet.createRow(1); - Cell cell3 = row2.createCell(0); - cell3.setCellValue("Jan"); - Cell cell4 = row2.createCell(1); - cell4.setCellValue(10); - Cell cell8 = row2.createCell(2); - cell8.setCellValue("Apa"); - Cell cell11 = row1.createCell(3); - cell11.setCellValue(11.11); - - Row row3 = sheet.createRow(2); - Cell cell5 = row3.createCell(0); - cell5.setCellValue("Ben"); - Cell cell6 = row3.createCell(1); - cell6.setCellValue(9); - Cell cell9 = row3.createCell(2); - cell9.setCellValue("Bepa"); - Cell cell12 = row1.createCell(3); - cell12.setCellValue(12.12); - - AreaReference source = new AreaReference("A1:C2", _testDataProvider.getSpreadsheetVersion()); - pivotTable = sheet.createPivotTable(source, new CellReference("H5")); - - XSSFSheet offsetSheet = wb.createSheet(); - - Row tableRow_1 = offsetSheet.createRow(1); - offsetOuterCell = tableRow_1.createCell(1); - offsetOuterCell.setCellValue(-1); - Cell tableCell_1_1 = tableRow_1.createCell(2); - tableCell_1_1.setCellValue("Row #"); - Cell tableCell_1_2 = tableRow_1.createCell(3); - tableCell_1_2.setCellValue("Exponent"); - Cell tableCell_1_3 = tableRow_1.createCell(4); - tableCell_1_3.setCellValue("10^Exponent"); - - Row tableRow_2 = offsetSheet.createRow(2); - Cell tableCell_2_1 = tableRow_2.createCell(2); - tableCell_2_1.setCellValue(0); - Cell tableCell_2_2 = tableRow_2.createCell(3); - tableCell_2_2.setCellValue(0); - Cell tableCell_2_3 = tableRow_2.createCell(4); - tableCell_2_3.setCellValue(1); - - Row tableRow_3= offsetSheet.createRow(3); - Cell tableCell_3_1 = tableRow_3.createCell(2); - tableCell_3_1.setCellValue(1); - Cell tableCell_3_2 = tableRow_3.createCell(3); - tableCell_3_2.setCellValue(1); - Cell tableCell_3_3 = tableRow_3.createCell(4); - tableCell_3_3.setCellValue(10); - - Row tableRow_4 = offsetSheet.createRow(4); - Cell tableCell_4_1 = tableRow_4.createCell(2); - tableCell_4_1.setCellValue(2); - Cell tableCell_4_2 = tableRow_4.createCell(3); - tableCell_4_2.setCellValue(2); - Cell tableCell_4_3 = tableRow_4.createCell(4); - tableCell_4_3.setCellValue(100); - - AreaReference offsetSource = new AreaReference(new CellReference("C2"), new CellReference("E4")); - offsetPivotTable = offsetSheet.createPivotTable(offsetSource, new CellReference("C6")); - } + public abstract void setUp(); @After public void tearDown() throws IOException { - XSSFWorkbook wb2 = _testDataProvider.writeOutAndReadBack(wb); - wb.close(); - wb2.close(); + if (wb != null) { + XSSFWorkbook wb2 = _testDataProvider.writeOutAndReadBack(wb); + wb.close(); + wb2.close(); + } } /** @@ -155,6 +82,7 @@ public class TestXSSFPivotTable { assertEquals(0, (int)pivotTable.getRowLabelColumns().get(0)); assertEquals(1, (int)pivotTable.getRowLabelColumns().get(1)); } + /** * Verify that it's not possible to create a row label outside of the referenced area. */ @@ -314,6 +242,7 @@ public class TestXSSFPivotTable { /** * Verify that it's possible to create a new filter */ + @Test public void testAddReportFilter() { int columnIndex = 0; diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTableName.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTableName.java new file mode 100644 index 000000000..8df2a663d --- /dev/null +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTableName.java @@ -0,0 +1,112 @@ +/* ==================================================================== + 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.xssf.usermodel; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.util.CellReference; +import org.junit.Before; + +/** + * Test pivot tables created by named range + */ +public class TestXSSFPivotTableName extends BaseTestXSSFPivotTable { + + @Override + @Before + public void setUp(){ + wb = new XSSFWorkbook(); + XSSFSheet sheet = wb.createSheet(); + + Row row1 = sheet.createRow(0); + // Create a cell and put a value in it. + Cell cell = row1.createCell(0); + cell.setCellValue("Names"); + Cell cell2 = row1.createCell(1); + cell2.setCellValue("#"); + Cell cell7 = row1.createCell(2); + cell7.setCellValue("Data"); + Cell cell10 = row1.createCell(3); + cell10.setCellValue("Value"); + + Row row2 = sheet.createRow(1); + Cell cell3 = row2.createCell(0); + cell3.setCellValue("Jan"); + Cell cell4 = row2.createCell(1); + cell4.setCellValue(10); + Cell cell8 = row2.createCell(2); + cell8.setCellValue("Apa"); + Cell cell11 = row1.createCell(3); + cell11.setCellValue(11.11); + + Row row3 = sheet.createRow(2); + Cell cell5 = row3.createCell(0); + cell5.setCellValue("Ben"); + Cell cell6 = row3.createCell(1); + cell6.setCellValue(9); + Cell cell9 = row3.createCell(2); + cell9.setCellValue("Bepa"); + Cell cell12 = row1.createCell(3); + cell12.setCellValue(12.12); + + XSSFName namedRange = sheet.getWorkbook().createName(); + namedRange.setRefersToFormula(sheet.getSheetName() + "!" + "A1:C2"); + pivotTable = sheet.createPivotTable(namedRange, new CellReference("H5")); + + XSSFSheet offsetSheet = wb.createSheet(); + + Row tableRow_1 = offsetSheet.createRow(1); + offsetOuterCell = tableRow_1.createCell(1); + offsetOuterCell.setCellValue(-1); + Cell tableCell_1_1 = tableRow_1.createCell(2); + tableCell_1_1.setCellValue("Row #"); + Cell tableCell_1_2 = tableRow_1.createCell(3); + tableCell_1_2.setCellValue("Exponent"); + Cell tableCell_1_3 = tableRow_1.createCell(4); + tableCell_1_3.setCellValue("10^Exponent"); + + Row tableRow_2 = offsetSheet.createRow(2); + Cell tableCell_2_1 = tableRow_2.createCell(2); + tableCell_2_1.setCellValue(0); + Cell tableCell_2_2 = tableRow_2.createCell(3); + tableCell_2_2.setCellValue(0); + Cell tableCell_2_3 = tableRow_2.createCell(4); + tableCell_2_3.setCellValue(1); + + Row tableRow_3= offsetSheet.createRow(3); + Cell tableCell_3_1 = tableRow_3.createCell(2); + tableCell_3_1.setCellValue(1); + Cell tableCell_3_2 = tableRow_3.createCell(3); + tableCell_3_2.setCellValue(1); + Cell tableCell_3_3 = tableRow_3.createCell(4); + tableCell_3_3.setCellValue(10); + + Row tableRow_4 = offsetSheet.createRow(4); + Cell tableCell_4_1 = tableRow_4.createCell(2); + tableCell_4_1.setCellValue(2); + Cell tableCell_4_2 = tableRow_4.createCell(3); + tableCell_4_2.setCellValue(2); + Cell tableCell_4_3 = tableRow_4.createCell(4); + tableCell_4_3.setCellValue(100); + + namedRange = sheet.getWorkbook().createName(); + namedRange.setRefersToFormula("C2:E4"); + namedRange.setSheetIndex(sheet.getWorkbook().getSheetIndex(sheet)); + offsetPivotTable = offsetSheet.createPivotTable(namedRange, new CellReference("C6")); + } +} diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTableRef.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTableRef.java new file mode 100644 index 000000000..ec0c5c6c1 --- /dev/null +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPivotTableRef.java @@ -0,0 +1,111 @@ +/* ==================================================================== + 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.xssf.usermodel; + +import org.apache.poi.ss.SpreadsheetVersion; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.util.AreaReference; +import org.apache.poi.ss.util.CellReference; +import org.junit.Before; + +/** + * Test pivot tables created by area reference + */ +public class TestXSSFPivotTableRef extends BaseTestXSSFPivotTable { + + @Override + @Before + public void setUp(){ + wb = new XSSFWorkbook(); + XSSFSheet sheet = wb.createSheet(); + + Row row1 = sheet.createRow(0); + // Create a cell and put a value in it. + Cell cell = row1.createCell(0); + cell.setCellValue("Names"); + Cell cell2 = row1.createCell(1); + cell2.setCellValue("#"); + Cell cell7 = row1.createCell(2); + cell7.setCellValue("Data"); + Cell cell10 = row1.createCell(3); + cell10.setCellValue("Value"); + + Row row2 = sheet.createRow(1); + Cell cell3 = row2.createCell(0); + cell3.setCellValue("Jan"); + Cell cell4 = row2.createCell(1); + cell4.setCellValue(10); + Cell cell8 = row2.createCell(2); + cell8.setCellValue("Apa"); + Cell cell11 = row1.createCell(3); + cell11.setCellValue(11.11); + + Row row3 = sheet.createRow(2); + Cell cell5 = row3.createCell(0); + cell5.setCellValue("Ben"); + Cell cell6 = row3.createCell(1); + cell6.setCellValue(9); + Cell cell9 = row3.createCell(2); + cell9.setCellValue("Bepa"); + Cell cell12 = row1.createCell(3); + cell12.setCellValue(12.12); + + AreaReference source = new AreaReference("A1:C2", SpreadsheetVersion.EXCEL2007); + pivotTable = sheet.createPivotTable(source, new CellReference("H5")); + + XSSFSheet offsetSheet = wb.createSheet(); + + Row tableRow_1 = offsetSheet.createRow(1); + offsetOuterCell = tableRow_1.createCell(1); + offsetOuterCell.setCellValue(-1); + Cell tableCell_1_1 = tableRow_1.createCell(2); + tableCell_1_1.setCellValue("Row #"); + Cell tableCell_1_2 = tableRow_1.createCell(3); + tableCell_1_2.setCellValue("Exponent"); + Cell tableCell_1_3 = tableRow_1.createCell(4); + tableCell_1_3.setCellValue("10^Exponent"); + + Row tableRow_2 = offsetSheet.createRow(2); + Cell tableCell_2_1 = tableRow_2.createCell(2); + tableCell_2_1.setCellValue(0); + Cell tableCell_2_2 = tableRow_2.createCell(3); + tableCell_2_2.setCellValue(0); + Cell tableCell_2_3 = tableRow_2.createCell(4); + tableCell_2_3.setCellValue(1); + + Row tableRow_3= offsetSheet.createRow(3); + Cell tableCell_3_1 = tableRow_3.createCell(2); + tableCell_3_1.setCellValue(1); + Cell tableCell_3_2 = tableRow_3.createCell(3); + tableCell_3_2.setCellValue(1); + Cell tableCell_3_3 = tableRow_3.createCell(4); + tableCell_3_3.setCellValue(10); + + Row tableRow_4 = offsetSheet.createRow(4); + Cell tableCell_4_1 = tableRow_4.createCell(2); + tableCell_4_1.setCellValue(2); + Cell tableCell_4_2 = tableRow_4.createCell(3); + tableCell_4_2.setCellValue(2); + Cell tableCell_4_3 = tableRow_4.createCell(4); + tableCell_4_3.setCellValue(100); + + AreaReference offsetSource = new AreaReference(new CellReference("C2"), new CellReference("E4")); + offsetPivotTable = offsetSheet.createPivotTable(offsetSource, new CellReference("C6")); + } +} From a4c3ce29eab85d28d394c832939bbda3b761e686 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Tue, 20 Sep 2016 09:59:01 +0000 Subject: [PATCH 127/157] bug 59853: exclude BaseTestXSSFPivotTable from ooxml-lite git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761545 13f79535-47bb-0310-9956-ffa450edef68 --- src/ooxml/java/org/apache/poi/util/OOXMLLite.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ooxml/java/org/apache/poi/util/OOXMLLite.java b/src/ooxml/java/org/apache/poi/util/OOXMLLite.java index b32077123..afb60f600 100644 --- a/src/ooxml/java/org/apache/poi/util/OOXMLLite.java +++ b/src/ooxml/java/org/apache/poi/util/OOXMLLite.java @@ -96,6 +96,7 @@ public final class OOXMLLite { "BaseTestXSheet", "BaseTestXRow", "BaseTestXCell", + "BaseTestXSSFPivotTable", "TestSXSSFWorkbook\\$\\d", "TestSXSSFWorkbook\\$NullOutputStream", "TestUnfixedBugs", From c669e2ef673086e70bcada16abe313e02de8cd01 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Tue, 20 Sep 2016 20:24:54 +0000 Subject: [PATCH 128/157] Adjust handling of ByteBuffer some more git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761636 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/poifs/nio/FileBackedDataSource.java | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java b/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java index 47637daa3..32a8701fb 100644 --- a/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java +++ b/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java @@ -88,27 +88,26 @@ public class FileBackedDataSource extends DataSource { throw new IndexOutOfBoundsException("Position " + position + " past the end of the file"); } - // Do we read or map (for read/write? + // Do we read or map (for read/write)? ByteBuffer dst; - int worked = -1; if (writable) { dst = channel.map(FileChannel.MapMode.READ_WRITE, position, length); - worked = 0; - // remember the buffer for cleanup if necessary - buffersToClean.add(dst); + + // remember this buffer for cleanup + buffersToClean.add(dst); } else { - // Read + // allocate the buffer on the heap if we cannot map the data in directly channel.position(position); dst = ByteBuffer.allocate(length); - worked = IOUtils.readFully(channel, dst); + + // Read the contents and check that we could read some data + int worked = IOUtils.readFully(channel, dst); + if(worked == -1) { + throw new IndexOutOfBoundsException("Position " + position + " past the end of the file"); + } } - // Check - if(worked == -1) { - throw new IndexOutOfBoundsException("Position " + position + " past the end of the file"); - } - - // Ready it for reading + // make it ready for reading dst.position(0); // All done From 3adf725ba4d05197be630740ce3d6a1814ceceee Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 21 Sep 2016 01:03:12 +0000 Subject: [PATCH 129/157] bug 60158: add failing test cases for AIOOBE on VBAMacroReader git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761652 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/poifs/macros/TestVBAMacroReader.java | 18 +++++++++++++++++- test-data/document/60158.docm | Bin 0 -> 15617 bytes 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 test-data/document/60158.docm diff --git a/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java b/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java index 2d98a4f38..6693a5227 100644 --- a/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java +++ b/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java @@ -262,6 +262,10 @@ public class TestVBAMacroReader { reader.close(); } + private void skipTest(Throwable e) { + assumeTrue("This test currently fails." + e.getLocalizedMessage(), false); + } + // This test is written as expected-to-fail and should be rewritten // as expected-to-pass when the bug is fixed. @Test @@ -273,11 +277,23 @@ public class TestVBAMacroReader { if (e.getMessage().matches("Module offset for '.+' was never read.")) { //e.printStackTrace(); // NPE when reading module.offset in VBAMacroReader.readMacros (approx line 258) - assumeTrue("This test currently fails. See stdout.", false); + skipTest(e); } else { // something unexpected failed throw e; } } } + + // This test is written as expected-to-fail and should be rewritten + // as expected-to-pass when the bug is fixed. + @Test + public void bug60158() throws IOException { + try { + fromFile(POIDataSamples.getDocumentInstance(), "60158.docm"); + fail("This test passes now. Please update the unit test and bug 59858."); + } catch (ArrayIndexOutOfBoundsException e) { + skipTest(e); + } + } } diff --git a/test-data/document/60158.docm b/test-data/document/60158.docm new file mode 100644 index 0000000000000000000000000000000000000000..2b7908fe3ced68a794f1dfda7153604d453296c0 GIT binary patch literal 15617 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 bZ_|jJB Date: Wed, 21 Sep 2016 01:14:26 +0000 Subject: [PATCH 130/157] include class of caught exception git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761654 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/poifs/macros/TestVBAMacroReader.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java b/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java index 6693a5227..41d2ea175 100644 --- a/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java +++ b/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java @@ -27,6 +27,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.StringWriter; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -262,8 +263,8 @@ public class TestVBAMacroReader { reader.close(); } - private void skipTest(Throwable e) { - assumeTrue("This test currently fails." + e.getLocalizedMessage(), false); + private static void skipTest(Throwable e) { + assumeTrue("This test currently fails with " + e, false); } // This test is written as expected-to-fail and should be rewritten From 0558c3a08531b7e9df6d2446607d293ecc9cb540 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 21 Sep 2016 01:15:39 +0000 Subject: [PATCH 131/157] fix copy-paste error git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761655 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/poifs/macros/TestVBAMacroReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java b/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java index 41d2ea175..63fff7f96 100644 --- a/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java +++ b/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java @@ -292,7 +292,7 @@ public class TestVBAMacroReader { public void bug60158() throws IOException { try { fromFile(POIDataSamples.getDocumentInstance(), "60158.docm"); - fail("This test passes now. Please update the unit test and bug 59858."); + fail("This test passes now. Please update the unit test and bug 60158."); } catch (ArrayIndexOutOfBoundsException e) { skipTest(e); } From 92d0f35c84e709d5ffa0114948e4d0ff9c4eb68c Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 21 Sep 2016 01:41:54 +0000 Subject: [PATCH 132/157] bug 59933: override POILogger#log(int, Object...) in NullLogger git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761657 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/util/NullLogger.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/java/org/apache/poi/util/NullLogger.java b/src/java/org/apache/poi/util/NullLogger.java index fe0979cfe..d4fc57442 100644 --- a/src/java/org/apache/poi/util/NullLogger.java +++ b/src/java/org/apache/poi/util/NullLogger.java @@ -53,6 +53,18 @@ public class NullLogger extends POILogger { // do nothing } + /** + * Log a message. Lazily appends Object parameters together. + * If the last parameter is a {@link Throwable} it is logged specially. + * + * @param level One of DEBUG, INFO, WARN, ERROR, FATAL + * @param objs the objects to place in the message + */ + @Override + public void log(int level, Object... objs) { + // do nothing + } + /** * Check if a logger is enabled to log at the specified level From b44d6ec06235ca0dfbdb8f3170c7b536e64393bf Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 21 Sep 2016 02:05:58 +0000 Subject: [PATCH 133/157] make POILogFactory _loggers cache final git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761660 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/util/POILogFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java/org/apache/poi/util/POILogFactory.java b/src/java/org/apache/poi/util/POILogFactory.java index ba2551de7..1e34ccd29 100644 --- a/src/java/org/apache/poi/util/POILogFactory.java +++ b/src/java/org/apache/poi/util/POILogFactory.java @@ -35,7 +35,7 @@ public final class POILogFactory { /** * Map of POILogger instances, with classes as keys */ - private static Map _loggers = new HashMap(); + private static final Map _loggers = new HashMap(); /** * A common instance of NullLogger, as it does nothing From ad8506b7f50add845234cce9f935a15eed6a0e54 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 21 Sep 2016 02:12:54 +0000 Subject: [PATCH 134/157] bug 59933: demote accessibility of NullLogger methods to the same level as POILogger git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761662 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/util/NullLogger.java | 5 +++-- src/java/org/apache/poi/util/POILogger.java | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/java/org/apache/poi/util/NullLogger.java b/src/java/org/apache/poi/util/NullLogger.java index d4fc57442..8a50cffba 100644 --- a/src/java/org/apache/poi/util/NullLogger.java +++ b/src/java/org/apache/poi/util/NullLogger.java @@ -23,6 +23,7 @@ package org.apache.poi.util; * calls as cheap as possible by performing lazy evaluation of the log * message.

*/ +@Internal public class NullLogger extends POILogger { @Override public void initialize(final String cat) { @@ -37,7 +38,7 @@ public class NullLogger extends POILogger { */ @Override - public void log(final int level, final Object obj1) { + protected void log(final int level, final Object obj1) { // do nothing } @@ -49,7 +50,7 @@ public class NullLogger extends POILogger { * @param exception An exception to be logged */ @Override - public void log(int level, Object obj1, final Throwable exception) { + protected void log(int level, Object obj1, final Throwable exception) { // do nothing } diff --git a/src/java/org/apache/poi/util/POILogger.java b/src/java/org/apache/poi/util/POILogger.java index 04198bfba..9238de01c 100644 --- a/src/java/org/apache/poi/util/POILogger.java +++ b/src/java/org/apache/poi/util/POILogger.java @@ -68,6 +68,15 @@ public abstract class POILogger { /** * Check if a logger is enabled to log at the specified level + * This allows code to avoid building strings or evaluating functions in + * the arguments to log. + * + * An example: + *

+     * if (logger.check(POILogger.INFO)) {
+     *     logger.log(POILogger.INFO, "Avoid concatenating " + " strings and evaluating " + functions());
+     * }
+     * 
* * @param level One of DEBUG, INFO, WARN, ERROR, FATAL */ From 29128d019d429d204b34148fb4ab61a9f5a34687 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 21 Sep 2016 02:43:55 +0000 Subject: [PATCH 135/157] javadoc git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761664 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java index e08af900b..e6f91afde 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java @@ -414,10 +414,9 @@ public class XSSFPivotTable extends POIXMLDocumentPart { /** * Creates cacheSource and workSheetSource for pivot table and sets the source reference as well assets the location of the pivot table - * @param sourceRef Source for data for pivot table - mutually exclusive with sourceName - * @param sourceName Source for data for pivot table - mutually exclusive with sourceRef * @param position Position for pivot table in sheet * @param sourceSheet Sheet where the source will be collected from + * @param refConfig an configurator that knows how to configure pivot table references */ @Beta protected void createSourceReferences(CellReference position, Sheet sourceSheet, PivotTableReferenceConfigurator refConfig){ From 2be18345450c44f73b3aecde99250940a41cad87 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 21 Sep 2016 02:45:39 +0000 Subject: [PATCH 136/157] bug 59933: demote accessibility of POILogger implementations of log(int, Object) and log(int, Object, Throwable) to be consistent with the POILogger abstract class git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761665 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/util/CommonsLogger.java | 12 +++++++++--- src/java/org/apache/poi/util/NullLogger.java | 4 ++-- src/java/org/apache/poi/util/POILogger.java | 8 ++++---- src/java/org/apache/poi/util/SystemOutLogger.java | 6 +++--- .../org/apache/poi/util/DummyPOILogger.java | 5 +++-- src/testcases/org/apache/poi/util/TestPOILogger.java | 4 ++-- 6 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/java/org/apache/poi/util/CommonsLogger.java b/src/java/org/apache/poi/util/CommonsLogger.java index 1cbb9628c..bbb04af6d 100644 --- a/src/java/org/apache/poi/util/CommonsLogger.java +++ b/src/java/org/apache/poi/util/CommonsLogger.java @@ -30,7 +30,7 @@ import org.apache.commons.logging.LogFactory; */ public class CommonsLogger extends POILogger { - private static LogFactory _creator = LogFactory.getFactory(); + private static final LogFactory _creator = LogFactory.getFactory(); private Log log = null; @Override @@ -46,8 +46,10 @@ public class CommonsLogger extends POILogger * @param obj1 The object to log. */ @Override - public void log(final int level, final Object obj1) + protected void log(final int level, final Object obj1) { + // FIXME: What happens if level is in between two levels (an even number)? + // Should this be `if (level >= FATAL) ...`? if(level==FATAL) { if(log.isFatalEnabled()) @@ -100,9 +102,11 @@ public class CommonsLogger extends POILogger * @param exception An exception to be logged */ @Override - public void log(final int level, final Object obj1, + protected void log(final int level, final Object obj1, final Throwable exception) { + // FIXME: What happens if level is in between two levels (an even number)? + // Should this be `if (level >= FATAL) ...`? if(level==FATAL) { if(log.isFatalEnabled()) @@ -174,6 +178,8 @@ public class CommonsLogger extends POILogger @Override public boolean check(final int level) { + // FIXME: What happens if level is in between two levels (an even number)? + // Should this be `if (level >= FATAL) ...`? if(level==FATAL) { if(log.isFatalEnabled()) diff --git a/src/java/org/apache/poi/util/NullLogger.java b/src/java/org/apache/poi/util/NullLogger.java index 8a50cffba..e21adfaa7 100644 --- a/src/java/org/apache/poi/util/NullLogger.java +++ b/src/java/org/apache/poi/util/NullLogger.java @@ -38,7 +38,7 @@ public class NullLogger extends POILogger { */ @Override - protected void log(final int level, final Object obj1) { + protected void _log(final int level, final Object obj1) { // do nothing } @@ -50,7 +50,7 @@ public class NullLogger extends POILogger { * @param exception An exception to be logged */ @Override - protected void log(int level, Object obj1, final Throwable exception) { + protected void _log(int level, Object obj1, final Throwable exception) { // do nothing } diff --git a/src/java/org/apache/poi/util/POILogger.java b/src/java/org/apache/poi/util/POILogger.java index 9238de01c..c54c75425 100644 --- a/src/java/org/apache/poi/util/POILogger.java +++ b/src/java/org/apache/poi/util/POILogger.java @@ -54,7 +54,7 @@ public abstract class POILogger { * @param level One of DEBUG, INFO, WARN, ERROR, FATAL * @param obj1 The object to log. This is converted to a string. */ - abstract protected void log(int level, Object obj1); + abstract protected void _log(int level, Object obj1); /** * Log a message @@ -63,7 +63,7 @@ public abstract class POILogger { * @param obj1 The object to log. This is converted to a string. * @param exception An exception to be logged */ - abstract protected void log(int level, Object obj1, final Throwable exception); + abstract protected void _log(int level, Object obj1, final Throwable exception); /** @@ -107,9 +107,9 @@ public abstract class POILogger { // somehow this ambiguity works and doesn't lead to a loop, // but it's confusing ... if (lastEx == null) { - log(level, msg); + _log(level, msg); } else { - log(level, msg, lastEx); + _log(level, msg, lastEx); } } } diff --git a/src/java/org/apache/poi/util/SystemOutLogger.java b/src/java/org/apache/poi/util/SystemOutLogger.java index 36d96ca03..457f25410 100644 --- a/src/java/org/apache/poi/util/SystemOutLogger.java +++ b/src/java/org/apache/poi/util/SystemOutLogger.java @@ -42,9 +42,9 @@ public class SystemOutLogger extends POILogger * @param obj1 The object to log. */ @Override - public void log(final int level, final Object obj1) + protected void _log(final int level, final Object obj1) { - log(level, obj1, null); + _log(level, obj1, null); } /** @@ -56,7 +56,7 @@ public class SystemOutLogger extends POILogger */ @Override @SuppressForbidden("uses printStackTrace") - public void log(final int level, final Object obj1, + protected void _log(final int level, final Object obj1, final Throwable exception) { if (check(level)) { System.out.println("[" + _cat + "]" + LEVEL_STRINGS_SHORT[Math.min(LEVEL_STRINGS_SHORT.length-1, level)] + " " + obj1); diff --git a/src/testcases/org/apache/poi/util/DummyPOILogger.java b/src/testcases/org/apache/poi/util/DummyPOILogger.java index c8566fe66..7da48ce26 100644 --- a/src/testcases/org/apache/poi/util/DummyPOILogger.java +++ b/src/testcases/org/apache/poi/util/DummyPOILogger.java @@ -23,6 +23,7 @@ import java.util.List; * POILogger which logs into an ArrayList, so that * tests can see what got logged */ +@Internal public class DummyPOILogger extends POILogger { public Listlogged = new ArrayList(); @@ -39,12 +40,12 @@ public class DummyPOILogger extends POILogger { public void initialize(String cat) {} @Override - public void log(int level, Object obj1) { + protected void _log(int level, Object obj1) { logged.add(level + " - " + obj1); } @Override - public void log(int level, Object obj1, Throwable exception) { + protected void _log(int level, Object obj1, Throwable exception) { logged.add(level + " - " + obj1 + " - " + exception); } } diff --git a/src/testcases/org/apache/poi/util/TestPOILogger.java b/src/testcases/org/apache/poi/util/TestPOILogger.java index 3914b7643..6650ed9e6 100644 --- a/src/testcases/org/apache/poi/util/TestPOILogger.java +++ b/src/testcases/org/apache/poi/util/TestPOILogger.java @@ -65,13 +65,13 @@ public final class TestPOILogger extends POILogger { } @Override - public void log(int level, Object obj1) { + protected void _log(int level, Object obj1) { lastLog = (obj1 == null) ? "" : obj1.toString(); lastEx = null; } @Override - public void log(int level, Object obj1, Throwable exception) { + protected void _log(int level, Object obj1, Throwable exception) { lastLog = (obj1 == null) ? "" : obj1.toString(); lastEx = exception; } From deed3aa8d657104c8ba213199046c7150378a5dd Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 21 Sep 2016 03:19:31 +0000 Subject: [PATCH 137/157] bug 57200,59788: be more specific why a temporary directory could not be created git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761667 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/util/DefaultTempFileCreationStrategy.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/java/org/apache/poi/util/DefaultTempFileCreationStrategy.java b/src/java/org/apache/poi/util/DefaultTempFileCreationStrategy.java index ef9e8443a..6f4475287 100644 --- a/src/java/org/apache/poi/util/DefaultTempFileCreationStrategy.java +++ b/src/java/org/apache/poi/util/DefaultTempFileCreationStrategy.java @@ -83,15 +83,22 @@ public class DefaultTempFileCreationStrategy implements TempFileCreationStrategy } /** - * Attempt to create a directory + * Attempt to create a directory, including any necessary parent directories. + * Does nothing if directory already exists. * - * @param directory - * @throws IOException + * @param directory the directory to create + * @throws IOException if unable to create temporary directory or it is not a directory */ private void createTempDirectory(File directory) throws IOException { - if (!(directory.exists() || directory.mkdirs()) || !directory.isDirectory()) { + // create directory if it doesn't exist + final boolean dirExists = (directory.exists() || directory.mkdirs()); + + if (!dirExists) { throw new IOException("Could not create temporary directory '" + directory + "'"); } + else if (!directory.isDirectory()) { + throw new IOException("Could not create temporary directory. '" + directory + "' exists but is not a directory."); + } } @Override From 4e864476c6924b5bbdcc91dde1b51986f7debaad Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 21 Sep 2016 03:31:15 +0000 Subject: [PATCH 138/157] bug 60153: move flushSheets out to its own method git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761668 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/xssf/streaming/SXSSFWorkbook.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java index 331ad9a0f..6b9ce374f 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java @@ -907,7 +907,9 @@ public class SXSSFWorkbook implements Workbook { try { sheet.getSheetDataWriter().close(); } catch (IOException e) { - // ignore exception here + logger.log(POILogger.WARN, + "An exception occurred while closing sheet data writer for sheet " + + sheet.getSheetName() + ".", e); } } @@ -926,11 +928,8 @@ public class SXSSFWorkbook implements Workbook { @Override public void write(OutputStream stream) throws IOException { - for (SXSSFSheet sheet : _xFromSxHash.values()) - { - sheet.flushRows(); - } - + flushSheets(); + //Save the template File tmplFile = TempFile.createTempFile("poi-sxssf-template", ".xlsx"); try @@ -956,6 +955,13 @@ public class SXSSFWorkbook implements Workbook { } } + protected void flushSheets() throws IOException { + for (SXSSFSheet sheet : _xFromSxHash.values()) + { + sheet.flushRows(); + } + } + /** * Dispose of temporary files backing this workbook on disk. * Calling this method will render the workbook unusable. From 7e3f2ca8d13298e833a5c4d5b37e5c0d69d1fe18 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 21 Sep 2016 03:57:22 +0000 Subject: [PATCH 139/157] bug 59933: demote accessibility of POILogger implementations of log(int, Object) and log(int, Object, Throwable) to be consistent with the POILogger abstract class git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761669 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/util/CommonsLogger.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java/org/apache/poi/util/CommonsLogger.java b/src/java/org/apache/poi/util/CommonsLogger.java index bbb04af6d..a204fde17 100644 --- a/src/java/org/apache/poi/util/CommonsLogger.java +++ b/src/java/org/apache/poi/util/CommonsLogger.java @@ -46,7 +46,7 @@ public class CommonsLogger extends POILogger * @param obj1 The object to log. */ @Override - protected void log(final int level, final Object obj1) + protected void _log(final int level, final Object obj1) { // FIXME: What happens if level is in between two levels (an even number)? // Should this be `if (level >= FATAL) ...`? @@ -102,7 +102,7 @@ public class CommonsLogger extends POILogger * @param exception An exception to be logged */ @Override - protected void log(final int level, final Object obj1, + protected void _log(final int level, final Object obj1, final Throwable exception) { // FIXME: What happens if level is in between two levels (an even number)? From eedc13f5ce97d2c8fe703e10861e15ea6ff36e7e Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Wed, 21 Sep 2016 05:03:57 +0000 Subject: [PATCH 140/157] add fixturing for notifying us when a previously failing unit test passes (better than @Ignore) git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761672 13f79535-47bb-0310-9956-ffa450edef68 --- src/testcases/org/apache/poi/POITestCase.java | 59 +++++++++++++++++++ .../poi/poifs/macros/TestVBAMacroReader.java | 13 ++-- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/testcases/org/apache/poi/POITestCase.java b/src/testcases/org/apache/poi/POITestCase.java index 786c6e112..a8cc8e1db 100644 --- a/src/testcases/org/apache/poi/POITestCase.java +++ b/src/testcases/org/apache/poi/POITestCase.java @@ -23,6 +23,7 @@ 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 static org.junit.Assume.assumeTrue; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; @@ -174,4 +175,62 @@ public final class POITestCase { } } } + + /** + * Rather than adding {@literal @}Ignore to known-failing tests, + * write the test so that it notifies us if it starts passing. + * This is useful for closing related or forgotten bugs. + * + * An Example: + *
+     * public static int add(int a, int b) {
+     *     // a known bug in behavior that has not been fixed yet
+     *     raise UnsupportedOperationException("add");
+     * }
+     * 
+     * {@literal @}Test
+     * public void knownFailingUnitTest() {
+     *     try {
+     *         assertEquals(2, add(1,1));
+     *         // this test fails because the assumption that this bug had not been fixed is false
+     *         testPassesNow(12345);
+     *     } catch (UnsupportedOperationException e) {
+     *         // test is skipped because the assumption that this bug had not been fixed is true
+     *         skipTest(e);
+     *     }
+     * }
+     * 
+     * Once passing, this unit test can be rewritten as:
+     * {@literal @}Test
+     * public void knownPassingUnitTest() {
+     *     assertEquals(2, add(1,1));
+     * }
+     * 
+     * If you have a better idea how to simplify test code while still notifying
+     * us when a previous known-failing test now passes, please improve these.
+     * As a bonus, a known-failing test that fails should not be counted as a
+     * passing test.
+     * 
+     * One possible alternative is to expect the known exception, but without
+     * a clear message that it is a good thing to no longer get the expected
+     * exception once the test passes.
+     * {@literal @}Test(expected=UnsupportedOperationException.class)
+     * public void knownFailingUnitTest() {
+     *     assertEquals(2, add(1,1));
+     * }
+     *
+     * @param e  the exception that was caught that will no longer
+     * be raised when the bug is fixed 
+     */
+    public static void skipTest(Throwable e) {
+        assumeTrue("This test currently fails with " + e, false);
+    }
+    /**
+     * @see #skipTest(Throwable)
+     *
+     * @param bug  the bug number corresponding to a known bug in bugzilla
+     */
+    public static void testPassesNow(int bug) {
+        fail("This test passes now. Please update the unit test and bug " + bug + ".");
+    }
 }
diff --git a/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java b/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java
index 63fff7f96..614b4effa 100644
--- a/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java
+++ b/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java
@@ -18,16 +18,15 @@
 package org.apache.poi.poifs.macros;
 
 import static org.apache.poi.POITestCase.assertContains;
+import static org.apache.poi.POITestCase.skipTest;
+import static org.apache.poi.POITestCase.testPassesNow;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.StringWriter;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -263,17 +262,13 @@ public class TestVBAMacroReader {
         reader.close();
     }
     
-    private static void skipTest(Throwable e) {
-        assumeTrue("This test currently fails with " + e, false);
-    }
-    
     // This test is written as expected-to-fail and should be rewritten
     // as expected-to-pass when the bug is fixed.
     @Test
     public void bug59858() throws IOException {
         try {
             fromFile(POIDataSamples.getSpreadSheetInstance(), "59858.xls");
-            fail("This test passes now. Please update the unit test and bug 59858.");
+            testPassesNow(59858);
         } catch (IOException e) {
             if (e.getMessage().matches("Module offset for '.+' was never read.")) {
                 //e.printStackTrace();
@@ -292,7 +287,7 @@ public class TestVBAMacroReader {
     public void bug60158() throws IOException {
         try {
             fromFile(POIDataSamples.getDocumentInstance(), "60158.docm");
-            fail("This test passes now. Please update the unit test and bug 60158.");
+            testPassesNow(60158);
         } catch (ArrayIndexOutOfBoundsException e) {
             skipTest(e);
         }

From cbeddd0d11d0b3bb5fea428452a7c646f9877d2f Mon Sep 17 00:00:00 2001
From: Javen O'Neal 
Date: Wed, 21 Sep 2016 05:20:36 +0000
Subject: [PATCH 141/157] bug 59983: add failing unit test demonstrating
 formula shifting is apply twice to shared formulas; patch from Luca Martini

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761673 13f79535-47bb-0310-9956-ffa450edef68
---
 .../usermodel/helpers/XSSFRowShifter.java     |   3 +-
 .../usermodel/TestXSSFSheetShiftRows.java     |  53 ++++++++++++++++--
 .../TestShiftRowSharedFormula.xlsx            | Bin 0 -> 8431 bytes
 3 files changed, 51 insertions(+), 5 deletions(-)
 create mode 100644 test-data/spreadsheet/TestShiftRowSharedFormula.xlsx

diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java
index d11ed1fa8..e55b014a7 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java
@@ -147,7 +147,8 @@ public final class XSSFRowShifter extends RowShifter {
 
                 }
 
-                if (f.isSetRef()) { //Range of cells which the formula applies to.
+                //Range of cells which the formula applies to.
+                if (f.isSetRef()) {
                     String ref = f.getRef();
                     String shiftedRef = shiftFormula(row, ref, shifter);
                     if (shiftedRef != null) f.setRef(shiftedRef);
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java
index 3e2cd5403..6ff649fcc 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java
@@ -17,6 +17,8 @@
 
 package org.apache.poi.xssf.usermodel;
 
+import static org.apache.poi.POITestCase.skipTest;
+import static org.apache.poi.POITestCase.testPassesNow;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
@@ -24,6 +26,8 @@ import static org.junit.Assert.fail;
 
 import java.io.IOException;
 
+import junit.framework.AssertionFailedError;
+
 import org.apache.poi.ss.usermodel.BaseTestSheetShiftRows;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.CellType;
@@ -35,7 +39,7 @@ import org.apache.poi.ss.util.CellAddress;
 import org.apache.poi.ss.util.CellUtil;
 import org.apache.poi.xssf.XSSFITestDataProvider;
 import org.apache.poi.xssf.XSSFTestDataSamples;
-import org.junit.Ignore;
+import org.apache.xmlbeans.impl.values.XmlValueDisconnectedException;
 import org.junit.Test;
 
 public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows {
@@ -377,7 +381,9 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows {
         wb.close();
     }
     
-    @Ignore("Bug 59733 - shiftRows() causes org.apache.xmlbeans.impl.values.XmlValueDisconnectedException")
+    // This test is written as expected-to-fail and should be rewritten
+    // as expected-to-pass when the bug is fixed.
+    //@Ignore("Bug 59733 - shiftRows() causes org.apache.xmlbeans.impl.values.XmlValueDisconnectedException")
     @Test
     public void bug59733() throws IOException {
         Workbook workbook = new XSSFWorkbook();
@@ -399,9 +405,48 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows {
             at org.apache.poi.xssf.usermodel.XSSFRow.getRowNum(XSSFRow.java:363)
             at org.apache.poi.xssf.usermodel.TestXSSFSheetShiftRows.bug59733(TestXSSFSheetShiftRows.java:393)
          */
-        sheet.removeRow(sheet.getRow(0));
-        assertEquals(1, sheet.getRow(1).getRowNum());
+        try {
+            sheet.removeRow(sheet.getRow(0));
+            assertEquals(1, sheet.getRow(1).getRowNum());
+            testPassesNow(59733);
+        } catch (XmlValueDisconnectedException e) {
+            skipTest(e);
+        }
+        
 
         workbook.close();
+    }
+
+    private static String getCellFormula(Sheet sheet, String address) {
+        CellAddress cellAddress = new CellAddress(address);
+        Row row = sheet.getRow(cellAddress.getRow());
+        assertNotNull(row);
+        Cell cell = row.getCell(cellAddress.getColumn());
+        assertNotNull(cell);
+        assertEquals(CellType.FORMULA, cell.getCellTypeEnum());
+        return cell.getCellFormula();
+    }
+
+    // This test is written as expected-to-fail and should be rewritten
+    // as expected-to-pass when the bug is fixed.
+    @Test
+    public void testSharedFormulas() throws Exception {
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("TestShiftRowSharedFormula.xlsx");
+        XSSFSheet sheet = wb.getSheetAt(0);
+        assertEquals("SUM(C2:C4)", getCellFormula(sheet, "C5"));
+        assertEquals("SUM(D2:D4)", getCellFormula(sheet, "D5"));
+        assertEquals("SUM(E2:E4)", getCellFormula(sheet, "E5"));
+
+        sheet.shiftRows(3, sheet.getLastRowNum(), 1);
+        try {
+            assertEquals("SUM(C2:C5)", getCellFormula(sheet, "C6"));
+            assertEquals("SUM(D2:D5)", getCellFormula(sheet, "D6"));
+            assertEquals("SUM(E2:E5)", getCellFormula(sheet, "E6"));
+            testPassesNow(59983);
+        } catch (AssertionError e) {
+            skipTest(e);
+        }
+        
+        wb.close();
     }
 }
diff --git a/test-data/spreadsheet/TestShiftRowSharedFormula.xlsx b/test-data/spreadsheet/TestShiftRowSharedFormula.xlsx
new file mode 100644
index 0000000000000000000000000000000000000000..d8ac0c6e2e650e7cbe896cb589a16f7d11507c59
GIT binary patch
literal 8431
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
Date: Wed, 21 Sep 2016 05:32:26 +0000
Subject: [PATCH 142/157] replace @Ignore with
 POITestCase.skipTest/testPassesNow

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761674 13f79535-47bb-0310-9956-ffa450edef68
---
 .../usermodel/TestXSSFSheetShiftRows.java     |  6 ++--
 .../ss/usermodel/BaseTestSheetShiftRows.java  | 30 +++++++++++++++----
 2 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java
index 6ff649fcc..fa4c77fbf 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java
@@ -26,8 +26,6 @@ import static org.junit.Assert.fail;
 
 import java.io.IOException;
 
-import junit.framework.AssertionFailedError;
-
 import org.apache.poi.ss.usermodel.BaseTestSheetShiftRows;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.CellType;
@@ -405,6 +403,7 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows {
             at org.apache.poi.xssf.usermodel.XSSFRow.getRowNum(XSSFRow.java:363)
             at org.apache.poi.xssf.usermodel.TestXSSFSheetShiftRows.bug59733(TestXSSFSheetShiftRows.java:393)
          */
+        // FIXME: remove try, catch, and testPassesNow, skipTest when test passes
         try {
             sheet.removeRow(sheet.getRow(0));
             assertEquals(1, sheet.getRow(1).getRowNum());
@@ -437,7 +436,8 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows {
         assertEquals("SUM(D2:D4)", getCellFormula(sheet, "D5"));
         assertEquals("SUM(E2:E4)", getCellFormula(sheet, "E5"));
 
-        sheet.shiftRows(3, sheet.getLastRowNum(), 1);
+        sheet.shiftRows(3, sheet.getLastRowNum(), 1);
+        // FIXME: remove try, catch, and testPassesNow, skipTest when test passes
         try {
             assertEquals("SUM(C2:C5)", getCellFormula(sheet, "C6"));
             assertEquals("SUM(D2:D5)", getCellFormula(sheet, "D6"));
diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java
index efae0d80c..556e89b43 100644
--- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java
+++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java
@@ -17,6 +17,8 @@
 
 package org.apache.poi.ss.usermodel;
 
+import static org.apache.poi.POITestCase.skipTest;
+import static org.apache.poi.POITestCase.testPassesNow;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
@@ -295,7 +297,7 @@ public abstract class BaseTestSheetShiftRows {
         wb.close();
     }
 
-    @Ignore("bug 56454: Incorrectly handles merged regions that do not contain column 0")
+    //@Ignore("bug 56454: Incorrectly handles merged regions that do not contain column 0")
     @Test
     public final void shiftWithMergedRegions_bug56454() throws IOException {
         Workbook wb = _testDataProvider.createWorkbook();
@@ -328,7 +330,15 @@ public abstract class BaseTestSheetShiftRows {
         expectedMergedRegions.add(A4_B8);
         expectedMergedRegions.add(C4_D8);
         
-        assertEquals(expectedMergedRegions, sheet.getMergedRegions());
+        // This test is written as expected-to-fail and should be rewritten
+        // as expected-to-pass when the bug is fixed.
+        // FIXME: remove try, catch, and testPassesNow, skipTest when test passes
+        try {
+            assertEquals(expectedMergedRegions, sheet.getMergedRegions());
+            testPassesNow(56454);
+        } catch (AssertionError e) {
+            skipTest(e);
+        }
         wb.close();
     }
     
@@ -589,7 +599,7 @@ public abstract class BaseTestSheetShiftRows {
         read.close();
     }
     
-    @Ignore("bug 56454: Incorrectly handles merged regions that do not contain column 0")
+    //@Ignore("bug 56454: Incorrectly handles merged regions that do not contain column 0")
     @Test
     public void shiftRowsWithMergedRegionsThatDoNotContainColumnZero() throws IOException {
         Workbook wb = _testDataProvider.createWorkbook();
@@ -614,9 +624,17 @@ public abstract class BaseTestSheetShiftRows {
         // C5:D7 will be shifted down with same size
         sheet.shiftRows(4, sheet.getLastRowNum(), 1);
 
-        assertEquals(2, sheet.getNumMergedRegions());
-        assertEquals(CellRangeAddress.valueOf("A4:B8"), sheet.getMergedRegion(0));
-        assertEquals(CellRangeAddress.valueOf("C5:D8"), sheet.getMergedRegion(1));
+        // This test is written as expected-to-fail and should be rewritten
+        // as expected-to-pass when the bug is fixed.
+        // FIXME: remove try, catch, and testPassesNow, skipTest when test passes
+        try {
+            assertEquals(2, sheet.getNumMergedRegions());
+            assertEquals(CellRangeAddress.valueOf("A4:B8"), sheet.getMergedRegion(0));
+            assertEquals(CellRangeAddress.valueOf("C5:D8"), sheet.getMergedRegion(1));
+            testPassesNow(56454);
+        } catch (AssertionError e) {
+            skipTest(e);
+        }
         
         wb.close();
     }

From 7e9cc96c465929de200e08d8eb3f2b810a0e6793 Mon Sep 17 00:00:00 2001
From: Dominik Stadler 
Date: Wed, 21 Sep 2016 05:45:57 +0000
Subject: [PATCH 143/157] Compiler/IDE warnings, unnecessary keywords,

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761675 13f79535-47bb-0310-9956-ffa450edef68
---
 .../apache/poi/ss/usermodel/CellStyle.java    | 96 +++++++++----------
 .../apache/poi/ss/usermodel/CellValue.java    | 40 ++++++--
 .../org/apache/poi/ss/usermodel/Workbook.java | 27 +++---
 .../poi/extractor/ExtractorFactory.java       |  5 +-
 .../poi/poifs/crypt/dsig/SignatureConfig.java |  2 +-
 .../apache/poi/xslf/usermodel/XSLFShape.java  |  6 +-
 .../poi/poifs/crypt/TestSignatureInfo.java    |  7 +-
 .../poi/ss/formula/functions/TestProper.java  |  1 -
 .../poi/xssf/usermodel/TestXSSFSheet.java     |  6 +-
 .../src/org/apache/poi/hmef/Attachment.java   |  2 +
 .../apache/poi/hssf/usermodel/TestBugs.java   |  4 +-
 .../poi/ss/formula/atp/TestIfError.java       |  2 +-
 .../ss/usermodel/BaseTestBugzillaIssues.java  |  3 -
 .../BaseTestSheetUpdateArrayFormulas.java     |  2 +-
 14 files changed, 111 insertions(+), 92 deletions(-)

diff --git a/src/java/org/apache/poi/ss/usermodel/CellStyle.java b/src/java/org/apache/poi/ss/usermodel/CellStyle.java
index df3d57259..1eab8dec1 100644
--- a/src/java/org/apache/poi/ss/usermodel/CellStyle.java
+++ b/src/java/org/apache/poi/ss/usermodel/CellStyle.java
@@ -26,308 +26,308 @@ public interface CellStyle {
      * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#GENERAL} instead.
      */
     @Removal(version="3.17")
-    static final short ALIGN_GENERAL = 0x0; //HorizontalAlignment.GENERAL.getCode();
+    short ALIGN_GENERAL = 0x0; //HorizontalAlignment.GENERAL.getCode();
 
     /**
      * left-justified horizontal alignment
      * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#LEFT} instead.
      */
     @Removal(version="3.17")
-    static final short ALIGN_LEFT = 0x1; //HorizontalAlignment.LEFT.getCode();
+    short ALIGN_LEFT = 0x1; //HorizontalAlignment.LEFT.getCode();
 
     /**
      * center horizontal alignment
      * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#CENTER} instead.
      */
     @Removal(version="3.17")
-    static final short ALIGN_CENTER = 0x2; //HorizontalAlignment.CENTER.getCode();
+    short ALIGN_CENTER = 0x2; //HorizontalAlignment.CENTER.getCode();
 
     /**
      * right-justified horizontal alignment
      * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#RIGHT} instead.
      */
     @Removal(version="3.17")
-    static final short ALIGN_RIGHT = 0x3; //HorizontalAlignment.RIGHT.getCode();
+    short ALIGN_RIGHT = 0x3; //HorizontalAlignment.RIGHT.getCode();
 
     /**
      * fill? horizontal alignment
      * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#FILL} instead.
      */
     @Removal(version="3.17")
-    static final short ALIGN_FILL = 0x4; //HorizontalAlignment.FILL.getCode();
+    short ALIGN_FILL = 0x4; //HorizontalAlignment.FILL.getCode();
 
     /**
      * justified horizontal alignment
      * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#JUSTIFY} instead.
      */
     @Removal(version="3.17")
-    static final short ALIGN_JUSTIFY = 0x5; //HorizontalAlignment.JUSTIFY.getCode();
+    short ALIGN_JUSTIFY = 0x5; //HorizontalAlignment.JUSTIFY.getCode();
 
     /**
      * center-selection? horizontal alignment
      * @deprecated POI 3.15 beta 3. Use {@link HorizontalAlignment#CENTER_SELECTION} instead.
      */
     @Removal(version="3.17")
-    static final short ALIGN_CENTER_SELECTION = 0x6; //HorizontalAlignment.CENTER_SELECTION.getCode();
+    short ALIGN_CENTER_SELECTION = 0x6; //HorizontalAlignment.CENTER_SELECTION.getCode();
 
     /**
      * top-aligned vertical alignment
      * @deprecated POI 3.15 beta 3. Use {@link VerticalAlignment#TOP} instead.
      */
     @Removal(version="3.17")
-    static final short VERTICAL_TOP = 0x0; //VerticalAlignment.TOP.getCode();
+    short VERTICAL_TOP = 0x0; //VerticalAlignment.TOP.getCode();
 
     /**
      * center-aligned vertical alignment
      * @deprecated POI 3.15 beta 3. Use {@link VerticalAlignment#CENTER} instead.
      */
     @Removal(version="3.17")
-    static final short VERTICAL_CENTER = 0x1; //VerticalAlignment.CENTER.getCode();
+    short VERTICAL_CENTER = 0x1; //VerticalAlignment.CENTER.getCode();
 
     /**
      * bottom-aligned vertical alignment
      * @deprecated POI 3.15 beta 3. Use {@link VerticalAlignment#BOTTOM} instead.
      */
     @Removal(version="3.17")
-    static final short VERTICAL_BOTTOM = 0x2; //VerticalAlignment.BOTTOM.getCode();
+    short VERTICAL_BOTTOM = 0x2; //VerticalAlignment.BOTTOM.getCode();
 
     /**
      * vertically justified vertical alignment
      * @deprecated POI 3.15 beta 3. Use {@link VerticalAlignment#JUSTIFY} instead.
      */
     @Removal(version="3.17")
-    static final short VERTICAL_JUSTIFY = 0x3; //VerticalAlignment.JUSTIFY.getCode();
+    short VERTICAL_JUSTIFY = 0x3; //VerticalAlignment.JUSTIFY.getCode();
 
     /**
      * No border
      * @deprecated 3.15 beta 2. Use {@link BorderStyle#NONE} instead.
      */
     @Removal(version="3.17")
-    static final short BORDER_NONE = 0x0; //BorderStyle.NONE.getCode();
+    short BORDER_NONE = 0x0; //BorderStyle.NONE.getCode();
 
     /**
      * Thin border
      * @deprecated 3.15 beta 2. Use {@link BorderStyle#THIN} instead.
      */
     @Removal(version="3.17")
-    static final short BORDER_THIN = 0x1; //BorderStyle.THIN.getCode();
+    short BORDER_THIN = 0x1; //BorderStyle.THIN.getCode();
 
     /**
      * Medium border
      * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM} instead.
      */
     @Removal(version="3.17")
-    static final short BORDER_MEDIUM = 0x2; //BorderStyle.MEDIUM.getCode();
+    short BORDER_MEDIUM = 0x2; //BorderStyle.MEDIUM.getCode();
 
     /**
      * dash border
      * @deprecated 3.15 beta 2. Use {@link BorderStyle#DASHED} instead.
      */
     @Removal(version="3.17")
-    static final short BORDER_DASHED = 0x3; //BorderStyle.DASHED.getCode();
+    short BORDER_DASHED = 0x3; //BorderStyle.DASHED.getCode();
 
     /**
      * dot border
      * @deprecated 3.15 beta 2. Use {@link BorderStyle#DOTTED} instead.
      */
     @Removal(version="3.17")
-    static final short BORDER_DOTTED = 0x4; //BorderStyle.DOTTED.getCode();
+    short BORDER_DOTTED = 0x4; //BorderStyle.DOTTED.getCode();
 
     /**
      * Thick border
      * @deprecated 3.15 beta 2. Use {@link BorderStyle#THICK} instead.
      */
     @Removal(version="3.17")
-    static final short BORDER_THICK = 0x5; //BorderStyle.THICK.getCode();
+    short BORDER_THICK = 0x5; //BorderStyle.THICK.getCode();
 
     /**
      * double-line border
      * @deprecated 3.15 beta 2. Use {@link BorderStyle#DOUBLE} instead.
      */
     @Removal(version="3.17")
-    static final short BORDER_DOUBLE = 0x6; //BorderStyle.DOUBLE.getCode();
+    short BORDER_DOUBLE = 0x6; //BorderStyle.DOUBLE.getCode();
 
     /**
      * hair-line border
      * @deprecated 3.15 beta 2. Use {@link BorderStyle#HAIR} instead.
      */
     @Removal(version="3.17")
-    static final short BORDER_HAIR = 0x7; //BorderStyle.HAIR.getCode();
+    short BORDER_HAIR = 0x7; //BorderStyle.HAIR.getCode();
 
     /**
      * Medium dashed border
      * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM_DASHED} instead.
      */
     @Removal(version="3.17")
-    static final short BORDER_MEDIUM_DASHED = 0x8; //BorderStyle.MEDIUM_DASHED.getCode();
+    short BORDER_MEDIUM_DASHED = 0x8; //BorderStyle.MEDIUM_DASHED.getCode();
 
     /**
      * dash-dot border
      * @deprecated 3.15 beta 2. Use {@link BorderStyle#DASH_DOT} instead.
      */
     @Removal(version="3.17")
-    static final short BORDER_DASH_DOT = 0x9; //BorderStyle.DASH_DOT.getCode();
+    short BORDER_DASH_DOT = 0x9; //BorderStyle.DASH_DOT.getCode();
 
     /**
      * medium dash-dot border
      * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM_DASH_DOT} instead.
      */
     @Removal(version="3.17")
-    static final short BORDER_MEDIUM_DASH_DOT = 0xA; //BorderStyle.MEDIUM_DASH_DOT.getCode();
+    short BORDER_MEDIUM_DASH_DOT = 0xA; //BorderStyle.MEDIUM_DASH_DOT.getCode();
 
     /**
      * dash-dot-dot border
      * @deprecated 3.15 beta 2. Use {@link BorderStyle#DASH_DOT_DOT} instead.
      */
     @Removal(version="3.17")
-    static final short BORDER_DASH_DOT_DOT = 0xB; //BorderStyle.DASH_DOT_DOT.getCode();
+    short BORDER_DASH_DOT_DOT = 0xB; //BorderStyle.DASH_DOT_DOT.getCode();
 
     /**
      * medium dash-dot-dot border
      * @deprecated 3.15 beta 2. Use {@link BorderStyle#MEDIUM_DASH_DOT_DOT} instead.
      */
     @Removal(version="3.17")
-    static final short BORDER_MEDIUM_DASH_DOT_DOT = 0xC; //BorderStyle.MEDIUM_DASH_DOT_DOT.getCode();
+    short BORDER_MEDIUM_DASH_DOT_DOT = 0xC; //BorderStyle.MEDIUM_DASH_DOT_DOT.getCode();
 
     /**
      * slanted dash-dot border
      * @deprecated 3.15 beta 2. Use {@link BorderStyle#SLANTED_DASH_DOT} instead.
      */
     @Removal(version="3.17")
-    static final short BORDER_SLANTED_DASH_DOT = 0xD; //BorderStyle.SLANTED_DASH_DOT.getCode();
+    short BORDER_SLANTED_DASH_DOT = 0xD; //BorderStyle.SLANTED_DASH_DOT.getCode();
 
     /** 
      * Fill Pattern: No background
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#NO_FILL} instead.
      */
     @Removal(version="3.17")
-    static final short NO_FILL = 0; //FillPatternType.NO_FILL.getCode();
+    short NO_FILL = 0; //FillPatternType.NO_FILL.getCode();
 
     /**
      * Fill Pattern: Solidly filled
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#SOLID_FOREGROUND} instead.
      */
     @Removal(version="3.17")
-    static final short SOLID_FOREGROUND = 1; //FillPatternType.SOLID_FOREGROUND.getCode();
+    short SOLID_FOREGROUND = 1; //FillPatternType.SOLID_FOREGROUND.getCode();
 
     /**
      * Fill Pattern: Small fine dots
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#FINE_DOTS} instead.
      */
     @Removal(version="3.17")
-    static final short FINE_DOTS = 2; //FillPatternType.FINE_DOTS.getCode();
+    short FINE_DOTS = 2; //FillPatternType.FINE_DOTS.getCode();
 
     /**
      * Fill Pattern: Wide dots
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#ALT_BARS} instead.
      */
     @Removal(version="3.17")
-    static final short ALT_BARS = 3; //FillPatternType.ALT_BARS.getCode();
+    short ALT_BARS = 3; //FillPatternType.ALT_BARS.getCode();
 
     /**
      * Fill Pattern: Sparse dots
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#SPARSE_DOTS} instead.
      */
     @Removal(version="3.17")
-    static final short SPARSE_DOTS = 4; //FillPatternType.SPARSE_DOTS.getCode();
+    short SPARSE_DOTS = 4; //FillPatternType.SPARSE_DOTS.getCode();
 
     /**
      * Fill Pattern: Thick horizontal bands
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#THICK_HORZ_BANDS} instead.
      */
     @Removal(version="3.17")
-    static final short THICK_HORZ_BANDS = 5; //FillPatternType.THICK_HORZ_BANDS.getCode();
+    short THICK_HORZ_BANDS = 5; //FillPatternType.THICK_HORZ_BANDS.getCode();
 
     /**
      * Fill Pattern: Thick vertical bands
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#THICK_VERT_BANDS} instead.
      */
     @Removal(version="3.17")
-    static final short THICK_VERT_BANDS = 6; //FillPatternType.THICK_VERT_BANDS.getCode();
+    short THICK_VERT_BANDS = 6; //FillPatternType.THICK_VERT_BANDS.getCode();
 
     /**
      * Fill Pattern: Thick backward facing diagonals
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#THICK_BACKWARD_DIAG} instead.
      */
     @Removal(version="3.17")
-    static final short THICK_BACKWARD_DIAG = 7; //FillPatternType.THICK_BACKWARD_DIAG.getCode();
+    short THICK_BACKWARD_DIAG = 7; //FillPatternType.THICK_BACKWARD_DIAG.getCode();
 
     /**
      * Fill Pattern: Thick forward facing diagonals
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#THICK_FORWARD_DIAG} instead.
      */
     @Removal(version="3.17")
-    static final short THICK_FORWARD_DIAG = 8; //FillPatternType.THICK_FORWARD_DIAG.getCode();
+    short THICK_FORWARD_DIAG = 8; //FillPatternType.THICK_FORWARD_DIAG.getCode();
 
     /**
      * Fill Pattern: Large spots
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#BIG_SPOTS} instead.
      */
     @Removal(version="3.17")
-    static final short BIG_SPOTS = 9; //FillPatternType.BIG_SPOTS.getCode();
+    short BIG_SPOTS = 9; //FillPatternType.BIG_SPOTS.getCode();
 
     /**
      * Fill Pattern: Brick-like layout
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#BRICKS} instead.
      */
     @Removal(version="3.17")
-    static final short BRICKS = 10; //FillPatternType.BRICKS.getCode();
+    short BRICKS = 10; //FillPatternType.BRICKS.getCode();
 
     /**
      * Fill Pattern: Thin horizontal bands
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#THIN_HORZ_BANDS} instead.
      */
     @Removal(version="3.17")
-    static final short THIN_HORZ_BANDS = 11; //FillPatternType.THIN_HORZ_BANDS.getCode();
+    short THIN_HORZ_BANDS = 11; //FillPatternType.THIN_HORZ_BANDS.getCode();
 
     /**
      * Fill Pattern: Thin vertical bands
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#THIN_VERT_BANDS} instead.
      */
     @Removal(version="3.17")
-    static final short THIN_VERT_BANDS = 12; //FillPatternType.THIN_VERT_BANDS.getCode();
+    short THIN_VERT_BANDS = 12; //FillPatternType.THIN_VERT_BANDS.getCode();
 
     /**
      * Fill Pattern: Thin backward diagonal
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#THIN_BACKWARD_DIAG} instead.
      */
     @Removal(version="3.17")
-    static final short THIN_BACKWARD_DIAG = 13; //FillPatternType.THIN_BACKWARD_DIAG.getCode();
+    short THIN_BACKWARD_DIAG = 13; //FillPatternType.THIN_BACKWARD_DIAG.getCode();
 
     /**
      * Fill Pattern: Thin forward diagonal
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#THIN_FORWARD_DIAG} instead.
      */
     @Removal(version="3.17")
-    static final short THIN_FORWARD_DIAG = 14; //FillPatternType.THIN_FORWARD_DIAG.getCode();
+    short THIN_FORWARD_DIAG = 14; //FillPatternType.THIN_FORWARD_DIAG.getCode();
 
     /**
      * Fill Pattern: Squares
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#SQUARES} instead.
      */
     @Removal(version="3.17")
-    static final short SQUARES = 15; //FillPatternType.SQUARES.getCode();
+    short SQUARES = 15; //FillPatternType.SQUARES.getCode();
 
     /**
      * Fill Pattern: Diamonds
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#DIAMONDS} instead.
      */
     @Removal(version="3.17")
-    static final short DIAMONDS = 16; //FillPatternType.DIAMONDS.getCode();
+    short DIAMONDS = 16; //FillPatternType.DIAMONDS.getCode();
 
     /**
      * Fill Pattern: Less Dots
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#LESS_DOTS} instead.
      */
     @Removal(version="3.17")
-    static final short LESS_DOTS = 17; //FillPatternType.LESS_DOTS.getCode();
+    short LESS_DOTS = 17; //FillPatternType.LESS_DOTS.getCode();
 
     /**
      * Fill Pattern: Least Dots
      * @deprecated 3.15 beta 3. Use {@link FillPatternType#LEAST_DOTS} instead.
      */
     @Removal(version="3.17")
-    static final short LEAST_DOTS = 18; //FillPatternType.LEAST_DOTS.getCode();
+    short LEAST_DOTS = 18; //FillPatternType.LEAST_DOTS.getCode();
 
     /**
      * get the index within the Workbook (sequence within the collection of ExtnededFormat objects)
@@ -353,7 +353,7 @@ public interface CellStyle {
     /**
      * Get the format string
      */
-    public String getDataFormatString();
+    String getDataFormatString();
 
     /**
      * set the font for this style
@@ -870,17 +870,17 @@ public interface CellStyle {
      *  to be of the same type (HSSFCellStyle or
      *  XSSFCellStyle)
      */
-    public void cloneStyleFrom(CellStyle source);
+    void cloneStyleFrom(CellStyle source);
     
     /**
      * Controls if the Cell should be auto-sized
      *  to shrink to fit if the text is too long
      */
-    public void setShrinkToFit(boolean shrinkToFit);
+    void setShrinkToFit(boolean shrinkToFit);
 
     /**
      * Should the Cell be auto-sized by Excel to shrink
      *  it to fit if this text is too long?
      */
-    public boolean getShrinkToFit();
+    boolean getShrinkToFit();
 }
diff --git a/src/java/org/apache/poi/ss/usermodel/CellValue.java b/src/java/org/apache/poi/ss/usermodel/CellValue.java
index 301accfca..b10210882 100644
--- a/src/java/org/apache/poi/ss/usermodel/CellValue.java
+++ b/src/java/org/apache/poi/ss/usermodel/CellValue.java
@@ -18,6 +18,8 @@
 package org.apache.poi.ss.usermodel;
 
 import org.apache.poi.ss.formula.eval.ErrorEval;
+import org.apache.poi.util.Internal;
+import org.apache.poi.util.Removal;
 
 /**
  * Mimics the 'data view' of a cell. This allows formula evaluator
@@ -47,12 +49,15 @@ public final class CellValue {
 	public CellValue(double numberValue) {
 		this(CellType.NUMERIC, numberValue, false, null, 0);
 	}
+
 	public static CellValue valueOf(boolean booleanValue) {
 		return booleanValue ? TRUE : FALSE;
 	}
+
 	public CellValue(String stringValue) {
 		this(CellType.STRING, 0.0, false, stringValue, 0);
 	}
+
 	public static CellValue getError(int errorCode) {
 		return new CellValue(CellType.ERROR, 0.0, false, null, errorCode);
 	}
@@ -64,30 +69,44 @@ public final class CellValue {
 	public boolean getBooleanValue() {
 		return _booleanValue;
 	}
+
 	/**
 	 * @return Returns the numberValue.
 	 */
 	public double getNumberValue() {
 		return _numberValue;
 	}
+
 	/**
 	 * @return Returns the stringValue.
 	 */
 	public String getStringValue() {
 		return _textValue;
 	}
+
+    /**
+     * Return the cell type.
+     *
+     * @return the cell type
+     * @since POI 3.15
+     * @deprecated POI 3.15
+     * Will be renamed to getCellTypeEnum() when we make the CellType enum transition in POI 4.0. See bug 59791.
+     */
+    @Internal(since="POI 3.15 beta 3")
+    @Removal(version="4.2")
+    public CellType getCellTypeEnum() {
+        return _cellType;
+    }
+
 	/**
-	 * @return Returns the cellType.
-	 * @since POI 3.15
-	 */
-	public CellType getCellTypeEnum() {
-		return _cellType;
-	}
-	/**
-	 * @return Returns the cellType.
+	 * Return the cell type.
+	 *
+	 * Will return {@link CellType} in version 4.0 of POI.
+	 * For forwards compatibility, do not hard-code cell type literals in your code.
+	 *
+	 * @return the cell type
+	 *
 	 * @deprecated POI 3.15. Use {@link #getCellTypeEnum()} instead.
-	 * In the future, the signature of this method will be changed to return a
-	 * {@link CellType}.
 	 */
 	@Deprecated
 	public int getCellType() {
@@ -100,6 +119,7 @@ public final class CellValue {
 	public byte getErrorValue() {
 		return (byte) _errorCode;
 	}
+
 	public String toString() {
 		StringBuffer sb = new StringBuffer(64);
 		sb.append(getClass().getName()).append(" [");
diff --git a/src/java/org/apache/poi/ss/usermodel/Workbook.java b/src/java/org/apache/poi/ss/usermodel/Workbook.java
index e52615fb1..85c7ca724 100644
--- a/src/java/org/apache/poi/ss/usermodel/Workbook.java
+++ b/src/java/org/apache/poi/ss/usermodel/Workbook.java
@@ -35,22 +35,22 @@ import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
 public interface Workbook extends Closeable, Iterable {
 
     /** Extended windows meta file */
-    public static final int PICTURE_TYPE_EMF = 2;
+    int PICTURE_TYPE_EMF = 2;
 
     /** Windows Meta File */
-    public static final int PICTURE_TYPE_WMF = 3;
+    int PICTURE_TYPE_WMF = 3;
 
     /** Mac PICT format */
-    public static final int PICTURE_TYPE_PICT = 4;
+    int PICTURE_TYPE_PICT = 4;
 
     /** JPEG format */
-    public static final int PICTURE_TYPE_JPEG = 5;
+    int PICTURE_TYPE_JPEG = 5;
 
     /** PNG format */
-    public static final int PICTURE_TYPE_PNG = 6;
+    int PICTURE_TYPE_PNG = 6;
 
     /** Device independent bitmap */
-    public static final int PICTURE_TYPE_DIB = 7;
+    int PICTURE_TYPE_DIB = 7;
 
 
     /**
@@ -58,14 +58,14 @@ public interface Workbook extends Closeable, Iterable {
      *
      * @see #setSheetHidden(int, int)
      */
-    public static final int SHEET_STATE_VISIBLE = 0;
+    int SHEET_STATE_VISIBLE = 0;
 
     /**
      * Indicates the book window is hidden, but can be shown by the user via the user interface.
      *
      * @see #setSheetHidden(int, int)
      */
-    public static final int SHEET_STATE_HIDDEN = 1;
+    int SHEET_STATE_HIDDEN = 1;
 
     /**
      * Indicates the sheet is hidden and cannot be shown in the user interface (UI).
@@ -77,7 +77,7 @@ public interface Workbook extends Closeable, Iterable {
      *
      * @see #setSheetHidden(int, int)
      */
-    public static final int SHEET_STATE_VERY_HIDDEN = 2;
+    int SHEET_STATE_VERY_HIDDEN = 2;
 
     /**
      * Convenience method to get the active sheet.  The active sheet is is the sheet
@@ -169,7 +169,7 @@ public interface Workbook extends Closeable, Iterable {
     int getSheetIndex(Sheet sheet);
 
     /**
-     * Sreate an Sheet for this Workbook, adds it to the sheets and returns
+     * Create a Sheet for this Workbook, adds it to the sheets and returns
      * the high level representation.  Use this to create new sheets.
      *
      * @return Sheet representing the new sheet.
@@ -217,7 +217,7 @@ public interface Workbook extends Closeable, Iterable {
      * See {@link org.apache.poi.ss.util.WorkbookUtil#createSafeSheetName(String nameProposal)}
      *      for a safe way to create valid names
      * 

- * @param sheetname sheetname to set for the sheet. + * @param sheetname The name to set for the sheet. * @return Sheet representing the new sheet. * @throws IllegalArgumentException if the name is null or invalid * or workbook already contains a sheet with this name @@ -617,7 +617,7 @@ public interface Workbook extends Closeable, Iterable { * workbook values when the workbook is opened * @since 3.8 */ - public void setForceFormulaRecalculation(boolean value); + void setForceFormulaRecalculation(boolean value); /** * Whether Excel will be asked to recalculate all formulas when the workbook is opened. @@ -632,6 +632,5 @@ public interface Workbook extends Closeable, Iterable { * @return SpreadsheetVersion enum * @since 3.14 beta 2 */ - public SpreadsheetVersion getSpreadsheetVersion(); - + SpreadsheetVersion getSpreadsheetVersion(); } diff --git a/src/ooxml/java/org/apache/poi/extractor/ExtractorFactory.java b/src/ooxml/java/org/apache/poi/extractor/ExtractorFactory.java index a67e83e24..cdd35b359 100644 --- a/src/ooxml/java/org/apache/poi/extractor/ExtractorFactory.java +++ b/src/ooxml/java/org/apache/poi/extractor/ExtractorFactory.java @@ -33,7 +33,6 @@ import org.apache.poi.hsmf.datatypes.AttachmentChunks; import org.apache.poi.hsmf.extractor.OutlookTextExtactor; import org.apache.poi.hssf.extractor.ExcelExtractor; import org.apache.poi.hwpf.extractor.WordExtractor; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackageAccess; @@ -123,7 +122,7 @@ public class ExtractorFactory { return OLE2ExtractorFactory.getPreferEventExtractor(); } - public static POITextExtractor createExtractor(File f) throws IOException, InvalidFormatException, OpenXML4JException, XmlException { + public static POITextExtractor createExtractor(File f) throws IOException, OpenXML4JException, XmlException { NPOIFSFileSystem fs = null; try { fs = new NPOIFSFileSystem(f); @@ -163,7 +162,7 @@ public class ExtractorFactory { } } - public static POITextExtractor createExtractor(InputStream inp) throws IOException, InvalidFormatException, OpenXML4JException, XmlException { + public static POITextExtractor createExtractor(InputStream inp) throws IOException, OpenXML4JException, XmlException { // Figure out the kind of stream // If clearly doesn't do mark/reset, wrap up if (! inp.markSupported()) { diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java index 25efc1e55..6779d8a21 100644 --- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java +++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java @@ -64,7 +64,7 @@ public class SignatureConfig { private static final POILogger LOG = POILogFactory.getLogger(SignatureConfig.class); - public static interface SignatureConfigurable { + public interface SignatureConfigurable { void setSignatureConfig(SignatureConfig signatureConfig); } diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java index 0c4e4971d..70df3f806 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java @@ -134,7 +134,7 @@ public abstract class XSLFShape implements Shape { if (this instanceof PlaceableShape) { PlaceableShape ps = (PlaceableShape)this; - ps.setAnchor(((PlaceableShape)sh).getAnchor()); + ps.setAnchor(sh.getAnchor()); } @@ -257,7 +257,7 @@ public abstract class XSLFShape implements Shape { * Different types of placeholders are allowed and can be specified by using the placeholder * type attribute for this element * - * @param placeholder + * @param placeholder The shape to use as placeholder or null if no placeholder should be set. */ protected void setPlaceholder(Placeholder placeholder) { String xquery = "declare namespace p='"+PML_NS+"' .//*/p:nvPr"; @@ -494,7 +494,7 @@ public abstract class XSLFShape implements Shape { int idx = (int)fillRef.getIdx(); CTSchemeColor phClr = fillRef.getSchemeClr(); CTStyleMatrix matrix = theme.getXmlObject().getThemeElements().getFmtScheme(); - XmlObject styleLst = null; + final XmlObject styleLst; int childIdx; if (idx >= 1 && idx <= 999) { childIdx = idx-1; diff --git a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java index 77c91cdca..202b9e18e 100644 --- a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java +++ b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java @@ -55,6 +55,7 @@ import org.apache.poi.POIDataSamples; import org.apache.poi.POITestCase; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackageAccess; +import org.apache.poi.openxml4j.opc.PackageRelationshipTypes; import org.apache.poi.poifs.crypt.dsig.DigestInfo; import org.apache.poi.poifs.crypt.dsig.SignatureConfig; import org.apache.poi.poifs.crypt.dsig.SignatureInfo; @@ -99,7 +100,7 @@ public class TestSignatureInfo { public static void initBouncy() throws IOException { CryptoFunctions.registerBouncyCastle(); - /*** TODO : set cal to now ... only set to fixed date for debugging ... */ + // Set cal to now ... only set to fixed date for debugging ... cal = LocaleUtil.getLocaleCalendar(LocaleUtil.TIMEZONE_UTC); assertNotNull(cal); // cal.set(2014, 7, 6, 21, 42, 12); @@ -403,7 +404,9 @@ public class TestSignatureInfo { // verify Iterator spIter = si.getSignatureParts().iterator(); - assertTrue(spIter.hasNext()); + assertTrue("Had: " + si.getSignatureConfig().getOpcPackage(). + getRelationshipsByType(PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN), + spIter.hasNext()); SignaturePart sp = spIter.next(); boolean valid = sp.validate(); assertTrue(valid); diff --git a/src/ooxml/testcases/org/apache/poi/ss/formula/functions/TestProper.java b/src/ooxml/testcases/org/apache/poi/ss/formula/functions/TestProper.java index a24fd8879..921dc445e 100644 --- a/src/ooxml/testcases/org/apache/poi/ss/formula/functions/TestProper.java +++ b/src/ooxml/testcases/org/apache/poi/ss/formula/functions/TestProper.java @@ -31,7 +31,6 @@ import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import junit.framework.AssertionFailedError; -import junit.framework.TestCase; import org.junit.Test; import static org.junit.Assert.assertEquals; diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java index 3f7be066d..2c561b222 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java @@ -1581,7 +1581,7 @@ public final class TestXSSFSheet extends BaseTestXSheet { System.out.println("Array formulas currently unsupported"); // FIXME: Array Formula set with Sheet.setArrayFormula() instead of cell.setFormula() /* - assertEquals("[Array Formula] N7 cell type", CellType.FORMULA, cell.getCellType()); + assertEquals("[Array Formula] N7 cell type", CellType.FORMULA, cell.getCellTypeEnum()); assertEquals("[Array Formula] N7 cell formula", "{SUM(H7:J7*{1,2,3})}", cell.getCellFormula()); */ @@ -1792,12 +1792,12 @@ public final class TestXSSFSheet extends BaseTestXSheet { // System.out.println("Array formulas currently unsupported"); /* // FIXME: Array Formula set with Sheet.setArrayFormula() instead of cell.setFormula() - assertEquals("[Array Formula] N10 cell type", CellType.FORMULA, cell.getCellType()); + assertEquals("[Array Formula] N10 cell type", CellType.FORMULA, cell.getCellTypeEnum()); assertEquals("[Array Formula] N10 cell formula", "{SUM(H10:J10*{1,2,3})}", cell.getCellFormula()); cell = CellUtil.getCell(destRow2, col); // FIXME: Array Formula set with Sheet.setArrayFormula() instead of cell.setFormula() - assertEquals("[Array Formula] N11 cell type", CellType.FORMULA, cell.getCellType()); + assertEquals("[Array Formula] N11 cell type", CellType.FORMULA, cell.getCellTypeEnum()); assertEquals("[Array Formula] N11 cell formula", "{SUM(H11:J11*{1,2,3})}", cell.getCellFormula()); */ diff --git a/src/scratchpad/src/org/apache/poi/hmef/Attachment.java b/src/scratchpad/src/org/apache/poi/hmef/Attachment.java index 89b063c26..59c90a4dc 100644 --- a/src/scratchpad/src/org/apache/poi/hmef/Attachment.java +++ b/src/scratchpad/src/org/apache/poi/hmef/Attachment.java @@ -137,6 +137,8 @@ public final class Attachment { /** * Returns the contents of the attachment. + * + * @throws IllegalArgumentException if there is no AttachmentData available in this Attachment */ public byte[] getContents() { TNEFAttribute contents = getAttribute(TNEFProperty.ID_ATTACHDATA); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java index 2ce6e1de8..65042127e 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java @@ -1885,12 +1885,12 @@ public final class TestBugs extends BaseTestBugzillaIssues { // TODO - Fix these so they work... /*row = s.getRow(4); - assertEquals(CellType.FORMULA, row.getCell(1).getCellType()); + assertEquals(CellType.FORMULA, row.getCell(1).getCellTypeEnum()); assertEquals("'[$http://gagravarr.org/FormulaRefs2.xls]Sheet1'!B2", row.getCell(1).getCellFormula()); assertEquals(123.0, row.getCell(1).getNumericCellValue(), 0); row = s.getRow(5); - assertEquals(CellType.FORMULA, row.getCell(1).getCellType()); + assertEquals(CellType.FORMULA, row.getCell(1).getCellTypeEnum()); assertEquals("'[$http://example.com/FormulaRefs.xls]Sheet1'!B1", row.getCell(1).getCellFormula()); assertEquals(234.0, row.getCell(1).getNumericCellValue(), 0);*/ diff --git a/src/testcases/org/apache/poi/ss/formula/atp/TestIfError.java b/src/testcases/org/apache/poi/ss/formula/atp/TestIfError.java index ebf6951f0..3a0a5b9b7 100644 --- a/src/testcases/org/apache/poi/ss/formula/atp/TestIfError.java +++ b/src/testcases/org/apache/poi/ss/formula/atp/TestIfError.java @@ -84,7 +84,7 @@ public class TestIfError extends TestCase { assertEquals("Checks that the cell is numeric", - CellType.STRING, evaluator.evaluate(cell2).getCellTypeEnum()); + CellType.STRING, evaluator.evaluate(cell2).getCellTypeEnum()); assertEquals("Rounds -10 to a nearest multiple of -3 (-9)", "Error in calculation", evaluator.evaluate(cell2).getStringValue()); diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java index f9725ba8a..7e41827a7 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java @@ -33,12 +33,9 @@ import java.awt.font.FontRenderContext; import java.awt.font.TextAttribute; import java.awt.font.TextLayout; import java.awt.geom.Rectangle2D; -import java.io.FileInputStream; import java.io.IOException; import java.text.AttributedString; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; import static org.junit.Assert.*; diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetUpdateArrayFormulas.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetUpdateArrayFormulas.java index 5e2ad4a8d..bbd95cccd 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetUpdateArrayFormulas.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetUpdateArrayFormulas.java @@ -570,7 +570,7 @@ public abstract class BaseTestSheetUpdateArrayFormulas { assertEquals(cra.formatAsString(), mcell.getArrayFormulaRange().formatAsString()); assertEquals("A2:A4*B2:B4", mcell.getCellFormula()); assertTrue(mcell.isPartOfArrayFormulaGroup()); - assertEquals(CellType.FORMULA, mcell.getCellType()); + assertEquals(CellType.FORMULA, mcell.getCellTypeEnum()); } */ From 08e643ea1258ab57fcfd190041b53d128f11b277 Mon Sep 17 00:00:00 2001 From: David North Date: Wed, 21 Sep 2016 22:03:57 +0000 Subject: [PATCH 144/157] Add 3,15 to DOAP file git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761823 13f79535-47bb-0310-9956-ffa450edef68 --- doap_POI.rdf | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doap_POI.rdf b/doap_POI.rdf index 5369344cd..08106f476 100644 --- a/doap_POI.rdf +++ b/doap_POI.rdf @@ -35,6 +35,13 @@ Java + + + Apache POI 3.15 + 2016-09-21 + 3.15 + + Apache POI 3.14 From a09fe683ddaba8f8c09e6f4994f0c0eed8b0018f Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Thu, 22 Sep 2016 03:29:00 +0000 Subject: [PATCH 145/157] bug 45565: add failing unit test for bug 45565 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761841 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/extractor/TestExtractorFactory.java | 13 +++++++++++++ test-data/spreadsheet/45565.xls | Bin 0 -> 13824 bytes 2 files changed, 13 insertions(+) create mode 100644 test-data/spreadsheet/45565.xls diff --git a/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java b/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java index 9d206f719..92a963f07 100644 --- a/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java +++ b/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java @@ -16,6 +16,7 @@ ==================================================================== */ package org.apache.poi.extractor; +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; @@ -37,6 +38,7 @@ import org.apache.poi.hdgf.extractor.VisioTextExtractor; import org.apache.poi.hpbf.extractor.PublisherTextExtractor; import org.apache.poi.hslf.extractor.PowerPointExtractor; import org.apache.poi.hsmf.extractor.OutlookTextExtactor; +import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.OldExcelFormatException; import org.apache.poi.hssf.extractor.EventBasedExcelExtractor; import org.apache.poi.hssf.extractor.ExcelExtractor; @@ -1019,4 +1021,15 @@ public class TestExtractorFactory { // expected here } } + + // This bug is currently open. This test will fail with "expected error not thrown" when the bug has been fixed. + // When this happens, change this from @Test(expected=...) to @Test + @Test(expected=AssertionError.class) + public void test45565() throws Exception { + POITextExtractor extractor = ExtractorFactory.createExtractor(HSSFTestDataSamples.getSampleFile("45565.xls")); + String text = extractor.getText(); + assertContains(text, "testdoc"); + assertContains(text, "test phrase"); + extractor.close(); + } } diff --git a/test-data/spreadsheet/45565.xls b/test-data/spreadsheet/45565.xls new file mode 100644 index 0000000000000000000000000000000000000000..7facba52bff94d0c37da2019b3aa0202f6e35e28 GIT binary patch literal 13824 zcmeHOU2IfE6#njZce}eSZFkF$R@tmY1GJR@jY`5#R}mu*L;^7okhG-~+Z0*Yt`Q~1 zMQvgtDuxGnFj0KcXcVJ?7o+VPJ`jls5BgvV;msNsBS8{m{l2-q-Q9M#DMmrb%*{D7 zd*t1dHSj(|3Bm8^HX0UO&C~4yGxx;eUic zIK++&2GE!|Q~m8QlU2ZZ_;A8MLJnLYJ%xQ52T!N_Ur6mt+??=;v7y_M4Z|FGtDPVm z%Bt`#c^${0a$<%z8vdCn`<3CVnKSBa!}gWGEM38JVBM|0q$&4?;mwBEkvlkL>ilRV z%g}_=ET4brh=x0`Kj1u!H2TqvJ^1%>zaAl4T4eg+^~IAAkNXF(810pmcCr)PD(Z%*Dhv54rTl`z z(mYSyA$H}Oa_T0-QAut2a;54!&@rvg2hmCt%K%+yykPxQ&&!o6Z$P0H<+~V+Vz#-x zF6R>_cG+-3a@}}F{=1hoygs4N5z&sGD$e$?kjL$)ffIGPQbIF|LBxG`I8Vq{_B+1Wt8%TX^5@rnOpwX6(cb6;<7W|<_J zNRec@BnNAXB<+Xc=UBQ2BTk3}G=J^jXKX_~klUn!22}oQ zVvN7x<1K_koCgpZc9P^t#4mB)#4M(3N%KfofQD-<=Y>4m45249hvdnCIpay6Y~jWu~cG@?A7uQ&yCm`l#UAN0+|euybQar;)c9d8^?s8%egvr27au zr#2j7&WK+(pv-y2lz!Fl<9u|fgkvuMgt@?I2QwH(I~+X8vNX$A=ZYry7*5K*T$~8f zww(MHkWyQZs$7urdiZmTD02|bm3rzn<3q&MW8ZN?bj$B%{6VcNcjN-W>tW~I%Vd_n zj)#ZX9`L&HLERN8=`LDhI#ODbY~TW|I^k4vQU{_rGER_9^fkueMQpp&;<1J?nQy|F z!Elx-dD4j?Ch$#&(NBd{Xao`yA=5jU*_G;vtQybW!4A_%QW!&*0ila&&neR{bZRr5 zic_A&mo%Z^PU+|?xD&uxy1GqxR7Kh9RCj!IM{OmZtL)C~33uuy++kahNJM@l_VuN^ z2YWqNI_Zkn?`wQ9oHQ$hBvpH1zWTa}PzvrQUcun6=GQ}%%yihd@lL*V!=5G^w~B{- zw&JiiFc|NXhP%wb;3hRT6>c1cc0OHhAq=kBkSEq zNt_;WjHIdNA}eW@Qyq6xq5N-6tsDA#(y77J?o49cfu7zyMrZbN_`sXF(|Qv_Hac|b zEvEIFVS`1$B481)2v`Ix0u}*_fJML}U=gqgSOhEr=G?nW?rJ#t4%h!} zS3lMI{~{?&()xcRNqf#(_wx$~PYD3}0CRw(wR@JNb^mLmxuhc`?FVQdK>GtDq~iSm z)mgV;ZDMUIy)TvS&h)4Dn$HLI3u{cf%&r*6Sy_7k+M95{5EYWk3(0oWvY?b|1471b zNu>t{^+{>a)VKQx#KZ=RfJML}U=gqgSOhEr76FTZMZh9p5xDIT&^lhrVXb@lS>7DE z)6plbqxHWIt@U+gOG{;~*|mPx@h`3Wl^}8zB^X$2qhq*jG;(4ZVln99f!-nHAH*)!jpK3nDmD7&KgD2lY?P&~Pr?F$e z6VEv2KR_n*%Z?dW)MgVyfM+hB#WTFRjqmG;!fs=eBpDtNO;J)gETVqhL%M%vs$b_` d#t&Lj|D)8 Date: Thu, 22 Sep 2016 03:37:09 +0000 Subject: [PATCH 146/157] add comment for purpose of test git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761842 13f79535-47bb-0310-9956-ffa450edef68 --- .../testcases/org/apache/poi/extractor/TestExtractorFactory.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java b/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java index 92a963f07..26fe68a63 100644 --- a/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java +++ b/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java @@ -1024,6 +1024,7 @@ public class TestExtractorFactory { // This bug is currently open. This test will fail with "expected error not thrown" when the bug has been fixed. // When this happens, change this from @Test(expected=...) to @Test + // bug 45565: text within TextBoxes is extracted by ExcelExtractor and WordExtractor @Test(expected=AssertionError.class) public void test45565() throws Exception { POITextExtractor extractor = ExtractorFactory.createExtractor(HSSFTestDataSamples.getSampleFile("45565.xls")); From 43f7d5bfdc926a2789c77d8d50e6b9e4f9d31bd8 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Thu, 22 Sep 2016 03:48:49 +0000 Subject: [PATCH 147/157] use equalsIgnoreCase for case-insensitive string comparisons git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761843 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/hssf/usermodel/HSSFDataFormat.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFDataFormat.java b/src/java/org/apache/poi/hssf/usermodel/HSSFDataFormat.java index 6eecc7b2c..23fe8cad7 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFDataFormat.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFDataFormat.java @@ -20,7 +20,6 @@ package org.apache.poi.hssf.usermodel; import java.util.Arrays; import java.util.Iterator; import java.util.List; -import java.util.Locale; import java.util.Vector; import org.apache.poi.hssf.model.InternalWorkbook; @@ -90,7 +89,7 @@ public final class HSSFDataFormat implements DataFormat { public short getFormat(String pFormat) { // Normalise the format string String format; - if (pFormat.toUpperCase(Locale.ROOT).equals("TEXT")) { + if (pFormat.equalsIgnoreCase("TEXT")) { format = "@"; } else { format = pFormat; From e9a16f2c5e7bda761eb1a93c1dd4c1776ee5bc90 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Thu, 22 Sep 2016 04:02:56 +0000 Subject: [PATCH 148/157] fix NPE git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761844 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/poi/xssf/usermodel/helpers/ColumnHelper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/ColumnHelper.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/ColumnHelper.java index 1e51e5e3f..b27100656 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/ColumnHelper.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/ColumnHelper.java @@ -319,6 +319,7 @@ public class ColumnHelper { } public int getIndexOfColumn(CTCols cols, CTCol searchCol) { + if (cols == null || searchCol == null) return -1; int i = 0; for (CTCol col : cols.getColArray()) { if (col.getMin() == searchCol.getMin() && col.getMax() == searchCol.getMax()) { From 257e6197ca24fba97c5fe8e7637ab1278b9b59e8 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Thu, 22 Sep 2016 04:24:22 +0000 Subject: [PATCH 149/157] add failing unit test for bug 55076: collapsing column groups only hides the first column git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761846 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/xssf/usermodel/TestXSSFBugs.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) 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 e695f385f..fea0262c4 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java @@ -3091,4 +3091,35 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertEquals("09 Mar 2016", result); } + + // This bug is currently open. When this bug is fixed, it should not throw an AssertionError + @Test(expected=AssertionError.class) + public void test55076_collapseColumnGroups() throws Exception { + Workbook wb = new XSSFWorkbook(); + Sheet sheet = wb.createSheet(); + + // this column collapsing bug only occurs when the grouped columns are different widths + sheet.setColumnWidth(1, 400); + sheet.setColumnWidth(2, 600); + sheet.setColumnWidth(3, 800); + + assertEquals(400, sheet.getColumnWidth(1)); + assertEquals(600, sheet.getColumnWidth(2)); + assertEquals(800, sheet.getColumnWidth(3)); + + sheet.groupColumn(1, 3); + sheet.setColumnGroupCollapsed(1, true); + + assertEquals(400, sheet.getColumnWidth(1)); + assertEquals(600, sheet.getColumnWidth(2)); + assertEquals(800, sheet.getColumnWidth(3)); + + // none of the columns should be hidden + // column group collapsing is a different concept + for (int c=0; c<5; c++) { + assertFalse("Column " + c, sheet.isColumnHidden(c)); + } + + wb.close(); + } } From 839870a49d8ecfb7a7c8593e6a1dffa0f472cc50 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Thu, 22 Sep 2016 04:37:04 +0000 Subject: [PATCH 150/157] check column outline level for bug 55076 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761847 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/xssf/usermodel/TestXSSFBugs.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) 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 fea0262c4..7fb1b507d 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java @@ -3110,9 +3110,11 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { sheet.groupColumn(1, 3); sheet.setColumnGroupCollapsed(1, true); - assertEquals(400, sheet.getColumnWidth(1)); - assertEquals(600, sheet.getColumnWidth(2)); - assertEquals(800, sheet.getColumnWidth(3)); + assertEquals(0, sheet.getColumnOutlineLevel(0)); + assertEquals(1, sheet.getColumnOutlineLevel(1)); + assertEquals(1, sheet.getColumnOutlineLevel(2)); + assertEquals(1, sheet.getColumnOutlineLevel(3)); + assertEquals(0, sheet.getColumnOutlineLevel(4)); // none of the columns should be hidden // column group collapsing is a different concept @@ -3120,6 +3122,10 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertFalse("Column " + c, sheet.isColumnHidden(c)); } + assertEquals(400, sheet.getColumnWidth(1)); + assertEquals(600, sheet.getColumnWidth(2)); + assertEquals(800, sheet.getColumnWidth(3)); + wb.close(); } } From 551d46f3c148757b3801c7a25045d6bea380b733 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Thu, 22 Sep 2016 07:36:52 +0000 Subject: [PATCH 151/157] bug 59687: add failing unit test showing that comments when the row that contains the comment is deleted; patch and file contributed by Greg Woolsey git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761860 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/xssf/usermodel/TestXSSFSheet.java | 18 ++++++++++++++++++ test-data/spreadsheet/59687.xlsx | Bin 0 -> 9580 bytes 2 files changed, 18 insertions(+) create mode 100644 test-data/spreadsheet/59687.xlsx diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java index 2c561b222..34ae2cfc4 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java @@ -2020,4 +2020,22 @@ public final class TestXSSFSheet extends BaseTestXSheet { } } + + // bug 59687: XSSFSheet.RemoveRow doesn't handle row gaps properly when removing row comments + // This test is currently failing (thus expected AssertionError). When this bug is fixed, no error should be thrown. + @Test(expected=AssertionError.class) + public void testRemoveRowWithCommentAndGapAbove() throws IOException { + final Workbook wb = _testDataProvider.openSampleWorkbook("59687.xlsx"); + final Sheet sheet = wb.getSheetAt(0); + + // comment exists + CellAddress commentCellAddress = new CellAddress("A4"); + assertNotNull(sheet.getCellComment(commentCellAddress)); + + assertEquals("Wrong starting # of comments", 1, sheet.getCellComments().size()); + + sheet.removeRow(sheet.getRow(commentCellAddress.getRow())); + + assertEquals("There should not be any comments left!", 0, sheet.getCellComments().size()); + } } diff --git a/test-data/spreadsheet/59687.xlsx b/test-data/spreadsheet/59687.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..8ce567fab3179817d000e3d815f0aa7485c39e4d GIT binary patch literal 9580 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 literal 0 HcmV?d00001 From 596bba09627e761c4d1f53fbf19ef6bbebd55770 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Thu, 22 Sep 2016 07:50:33 +0000 Subject: [PATCH 152/157] bug 59687: correctly delete comments from rows when removing a row and the workbook contains empty rows above the deleted row; patch from Greg Woolsey git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761861 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/poi/xssf/usermodel/XSSFSheet.java | 10 ++++++---- .../org/apache/poi/xssf/usermodel/TestXSSFSheet.java | 3 +-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java index 8b9746489..bc2f071be 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java @@ -1928,15 +1928,17 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { } // Performance optimization: explicit boxing is slightly faster than auto-unboxing, though may use more memory - final Integer rownumI = new Integer(row.getRowNum()); // NOSONAR - int idx = _rows.headMap(rownumI).size(); - _rows.remove(rownumI); + final int rowNum = row.getRowNum(); + final Integer rowNumI = new Integer(rowNum); // NOSONAR + // this is not the physical row number! + final int idx = _rows.headMap(rowNumI).size(); + _rows.remove(rowNumI); worksheet.getSheetData().removeRow(idx); // also remove any comment located in that row if(sheetComments != null) { for (CellAddress ref : getCellComments().keySet()) { - if (ref.getRow() == idx) { + if (ref.getRow() == rowNum) { sheetComments.removeComment(ref); } } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java index 34ae2cfc4..24c1d7237 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java @@ -2022,8 +2022,7 @@ public final class TestXSSFSheet extends BaseTestXSheet { } // bug 59687: XSSFSheet.RemoveRow doesn't handle row gaps properly when removing row comments - // This test is currently failing (thus expected AssertionError). When this bug is fixed, no error should be thrown. - @Test(expected=AssertionError.class) + @Test public void testRemoveRowWithCommentAndGapAbove() throws IOException { final Workbook wb = _testDataProvider.openSampleWorkbook("59687.xlsx"); final Sheet sheet = wb.getSheetAt(0); From d709038f24dafa504c70bb9aff454c3bfee13155 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Thu, 22 Sep 2016 09:21:56 +0000 Subject: [PATCH 153/157] add gradle build script for building POI with gradle git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761871 13f79535-47bb-0310-9956-ffa450edef68 --- build.gradle | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 build.gradle diff --git a/build.gradle b/build.gradle new file mode 100644 index 000000000..20f98e820 --- /dev/null +++ b/build.gradle @@ -0,0 +1,21 @@ +/* ==================================================================== + 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. +==================================================================== */ + +// For help converting an Ant build to a Gradle build, see +// https://docs.gradle.org/current/userguide/ant.html + +ant.importBuild 'build.xml' From 12ca2205b0ad85372da0ddbc5b4506736c217ee8 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Thu, 22 Sep 2016 09:24:48 +0000 Subject: [PATCH 154/157] bug 57843: add failing unit test: Word 6.0 (1993) fails with ArrayIndexOutOfBoundsException git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761873 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/TestAllFiles.java | 1 + .../apache/poi/hwpf/usermodel/TestBugs.java | 17 +++++++++++++++++ test-data/document/57843.doc | Bin 0 -> 8192 bytes 3 files changed, 18 insertions(+) create mode 100644 test-data/document/57843.doc diff --git a/src/integrationtest/org/apache/poi/TestAllFiles.java b/src/integrationtest/org/apache/poi/TestAllFiles.java index e364c9f28..6def523db 100644 --- a/src/integrationtest/org/apache/poi/TestAllFiles.java +++ b/src/integrationtest/org/apache/poi/TestAllFiles.java @@ -232,6 +232,7 @@ public class TestAllFiles { EXPECTED_FAILURES.add("spreadsheet/43493.xls"); EXPECTED_FAILURES.add("spreadsheet/46904.xls"); EXPECTED_FAILURES.add("document/Bug50955.doc"); + EXPECTED_FAILURES.add("document/57843.doc"); EXPECTED_FAILURES.add("slideshow/PPT95.ppt"); EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_DCTermsNamespaceLimitedUseFAIL.docx"); EXPECTED_FAILURES.add("openxml4j/OPCCompliance_CoreProperties_DoNotUseCompatibilityMarkupFAIL.docx"); diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestBugs.java b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestBugs.java index 6a69aab8a..b4591ad45 100644 --- a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestBugs.java +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestBugs.java @@ -32,11 +32,13 @@ import org.apache.poi.hwpf.model.PlexOfField; import org.apache.poi.hwpf.model.SubdocumentType; import org.apache.poi.hwpf.model.io.HWPFOutputStream; import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.util.IOUtils; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -901,4 +903,19 @@ public class TestBugs extends TestCase HWPFDocument hwpfDocument2 = HWPFTestDataSamples.writeOutAndReadBack(hwpfDocument); assertNotNull(hwpfDocument2); } + + public void test57843() throws IOException { + try { + File f = POIDataSamples.getDocumentInstance().getFile("57843.doc"); + boolean readOnly = true; + POIFSFileSystem fs = new POIFSFileSystem(f, readOnly); + HWPFOldDocument doc = new HWPFOldDocument(fs); + assertNotNull(doc); + doc.close(); + fs.close(); + fixed("57843"); + } catch (ArrayIndexOutOfBoundsException e) { + // expected until this bug is fixed + } + } } diff --git a/test-data/document/57843.doc b/test-data/document/57843.doc new file mode 100644 index 0000000000000000000000000000000000000000..57be6c6ed1ce6efb034dad41b5ad3638f5269d36 GIT binary patch literal 8192 zcmeHM-)|g89UuQnW7=(#6igKHFlr@8(Dkrm;wB(bJ2nn!$ie*l6aUO@sPf%wsw&v$m$zPlX8srrxzul4op z&X4cU&-XiXyLW$m{G+#je(LvZ==uhmVE1>X*^$2fG29dR>lnj~;`#p0&Q96OaC>+? zMjrSWx{f1w6vK)r=1+i*f~G;A0X+$N3KW2z2GQKZ>+$!%HKy_B7-!#P8Ct`7i0;9! z88)?>^HdM^z04n9|3Q3bY!Z{+DkqMyWynuin_XoM_Qt-;M-84}<753%7&T{9U!&~2 z4(WzPYz1w|a%dvGA4aVi)px3tPd1Srqvj0vO`+rDvqf)VwS;WP)}e!D$?)`jpJ&+E z7}aFT;r}Lo@#Q~wzgKNP!zs4mtxlQnvA+!Ko8BkX%tpEG>iy?NO z=<#9Ye}?mnK^$hSlgg}bTJ$V8Qs^b@%lo+=kWg{?1A6BBiRdgrfK`a&ewNgGrx}m z-{;GHs&9ndr$gcYx=yfSH!s^a(9*SE`&o>Cr<`|?md>T$#e8aSmg}gU!}AB_^FdoI z8MqF*Zq&R@aH{+^JYET@#;cZ2+(+^2YU}~cs})r{%yIa6*u&L$wZ3Yr{>P=Q^!{|) zZwaH5h`*xSiS7n-bF=68s;l$mM3^nfFD9L+&Yz!Km^~L<5-O9nqmo3{`05ote|BMZ zAvisM?(7*pKR^G%g%>Z(2Jx0>wAheIVs-A~dL~`4B14%rq~UWf*7(`k+1VgiGj;y5 zZ19V@jcfdp?nskq!*!FpSn>@goTP`m=}U=y9oqOF`xf=!VmA{N%lN|E^s7Xk)J+I)PEUqr+F&toUbZl9p)zBkx1SU;a1D&Jd0{UaG7_7#n@{Ka@MgF zd^1eOjv}%azakpi2nREzBO7ZZDXX5v! zb)!RRt%hg$s!kA31^zA;u7*X05*sp8VELdf%Q|i64hAp7a-BezZmg|@ttu6!hgL^< z=scUR&du>i8F*1+1o|rLL>7`Gu1nq}B`Jta@07L#BG93sw)0GiQDRatB^|kKYaosm zIz*@)>rC=2C)m^h7w`ERUlAP@@zZc8#FHCaMnri9mZfi>sc{8oXIy42z!mm%m5VuG z08KY#7-u@sEpm0DLoAEP<=0e4NhA103C9E51?Eb3L!SsSYh{)j-Ox^jKtuyRp==$c##!9C4SX3+{%;Dnhimyn*zxsv~WElrE$)Jlau~U1QYk{B?Gs)O(@)fzL$Wo6EaDh!#d~O24krWhyH*p8T>&rLcF21IbT18#3(31oJoaGunv7MU`^?-Dx zHATq7+&Y~iUz-jdkYwLi;Hntj@XzEonCfjR3j#?Cf+e2jurbwG6q0P&Y*N91Mo5g@ z7lN+NQ8XJK*2Kh%^(YpJks|6L;z$Z&PM##JCA{T}9Gx6tP7~FDRoICDid1C1ig`N`$VRV}#{uH7Tas%9G>ilQ$uv!| zw4sqQvtK6_pkt~tY$PbCr+slC)%)k|VI)!(h?LP8axemJBt)Z%_bUTu0@b@L5fs{E zP!IwCswN~=z$FC``-$_<+k=*pPuS z!c1+z0L!Hd>!l|Mq%g2cB~~@5X1SL3d%aj06^iHP#fCP z_86dk7=%Z3MbF2mtQLabs+?)D1)*x``nFGG%FU7s0%mWkQ44Vj_1)T)p{mv8g5s%{kWe{QDDu^)91rY{rgMI<}5cDh1Z$ZBU z31mtG^e$dz-v+&hk4Eo0lkS2NCtEhnA!&Y81xg+PeH!~ zeE=f7{hPip{+XKBzqEhz&tl5R=5M3M?y+&=d9N7z6Pp}(nizQMpEbVC)kdK5%^Kkj`14|?+6Dk zdUJ#~j)-&l#t|yf697}*9mU(5&&_-vs%>KLxBOKc3$AG#IM`F@9cLT8w4oFBCts<7^U4-#W<{EM+nJ2d@V@Fg!`}4ll<30}-)x{r~^~ literal 0 HcmV?d00001 From 6dc4bcf1de802444be86f388cc67ce6bc2e0270a Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Thu, 22 Sep 2016 09:30:24 +0000 Subject: [PATCH 155/157] ignore .gradle directory git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1761875 13f79535-47bb-0310-9956-ffa450edef68 From e3ad266c4fbdd40e75f9367e5820ab423b083021 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Sun, 25 Sep 2016 02:21:41 +0000 Subject: [PATCH 156/157] add onealj@apache.org 8BABDD6C to KEYS git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1762154 13f79535-47bb-0310-9956-ffa450edef68 --- KEYS | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/KEYS b/KEYS index 6767cb00a..adc245d13 100644 --- a/KEYS +++ b/KEYS @@ -2386,3 +2386,102 @@ cCRRHYCeAZDU5UMxi0nonfT+060i2rLPSd7o0bstG7gb1pD99rKxL57M7uy+WBnk YobtRLhWHvHyWS4dKqiteeTwAqG2ZFOq98KCu1LXMKj42HqwOtB3L23HlhqVyA== =8e4G -----END PGP PUBLIC KEY BLOCK----- +pub 4096R/8BABDD6C 2015-10-10 [expires: 2017-10-09] +uid Javen O'Neal +uid Javen O'Neal +sub 4096R/309424B4 2015-10-10 [expires: 2017-10-09] + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2.0.22 (GNU/Linux) + +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 +2Nr+AmDDs6ZOEI5zhwxioePw/Cg= +=9lKb +-----END PGP PUBLIC KEY BLOCK----- From db79fe043c57f186a40ec996fbb6e64c2a197e54 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Wed, 28 Sep 2016 08:44:14 +0000 Subject: [PATCH 157/157] Adjust some JavaDoc and remove some unnecessary String.valueOf() calls and fix some other compiler warnings git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1762617 13f79535-47bb-0310-9956-ffa450edef68 --- .../hssf/usermodel/examples/InCellLists.java | 54 ++++++++----------- .../poi/hssf/usermodel/HSSFWorkbook.java | 3 +- .../poi/ss/formula/functions/Bin2Dec.java | 2 +- .../org/apache/poi/ss/usermodel/Workbook.java | 2 + .../org/apache/poi/ss/util/SheetUtil.java | 19 ++++--- .../poi/hwpf/converter/WordToFoUtils.java | 16 +++--- .../filesystem/TestPOIFSDocumentPath.java | 10 ++-- 7 files changed, 48 insertions(+), 58 deletions(-) diff --git a/src/examples/src/org/apache/poi/hssf/usermodel/examples/InCellLists.java b/src/examples/src/org/apache/poi/hssf/usermodel/examples/InCellLists.java index a666c6ab7..e1d4cbcbf 100644 --- a/src/examples/src/org/apache/poi/hssf/usermodel/examples/InCellLists.java +++ b/src/examples/src/org/apache/poi/hssf/usermodel/examples/InCellLists.java @@ -67,27 +67,21 @@ public class InCellLists { * the Excel spreadsheet file this code will create. */ public void demonstrateMethodCalls(String outputFilename) throws IOException { - HSSFWorkbook workbook = null; - HSSFSheet sheet = null; - HSSFRow row = null; - HSSFCell cell = null; - ArrayList multiLevelListItems = null; - ArrayList listItems = null; + HSSFWorkbook workbook = new HSSFWorkbook(); try { - workbook = new HSSFWorkbook(); - sheet = workbook.createSheet("In Cell Lists"); - row = sheet.createRow(0); + HSSFSheet sheet = workbook.createSheet("In Cell Lists"); + HSSFRow row = sheet.createRow(0); // Create a cell at A1 and insert a single, bulleted, item into // that cell. - cell = row.createCell(0); + HSSFCell cell = row.createCell(0); this.bulletedItemInCell(workbook, "List Item", cell); // Create a cell at A2 and insert a plain list - that is one // whose items are neither bulleted or numbered - into that cell. row = sheet.createRow(1); cell = row.createCell(0); - listItems = new ArrayList(); + ArrayList listItems = new ArrayList(); listItems.add("List Item One."); listItems.add("List Item Two."); listItems.add("List Item Three."); @@ -131,7 +125,7 @@ public class InCellLists { // to preserve order. row = sheet.createRow(4); cell = row.createCell(0); - multiLevelListItems = new ArrayList(); + ArrayList multiLevelListItems = new ArrayList(); listItems = new ArrayList(); listItems.add("ML List Item One - Sub Item One."); listItems.add("ML List Item One - Sub Item Two."); @@ -189,9 +183,7 @@ public class InCellLists { ioEx.printStackTrace(System.out); } finally { - if (workbook != null) { - workbook.close(); - } + workbook.close(); } } @@ -236,7 +228,7 @@ public class InCellLists { * will be written. */ public void listInCell(HSSFWorkbook workbook, ArrayList listItems, HSSFCell cell) { - StringBuffer buffer = new StringBuffer(); + StringBuilder buffer = new StringBuilder(); HSSFCellStyle wrapStyle = workbook.createCellStyle(); wrapStyle.setWrapText(true); for(String listItem : listItems) { @@ -269,7 +261,7 @@ public class InCellLists { HSSFCell cell, int startingValue, int increment) { - StringBuffer buffer = new StringBuffer(); + StringBuilder buffer = new StringBuilder(); int itemNumber = startingValue; // Note that again, an HSSFCellStye object is required and that // it's wrap text property should be set to 'true' @@ -278,7 +270,7 @@ public class InCellLists { // Note that the basic method is identical to the listInCell() method // with one difference; a number prefixed to the items text. for(String listItem : listItems) { - buffer.append(String.valueOf(itemNumber) + ". "); + buffer.append(itemNumber).append(". "); buffer.append(listItem); buffer.append("\n"); itemNumber += increment; @@ -303,7 +295,7 @@ public class InCellLists { public void bulletedListInCell(HSSFWorkbook workbook, ArrayList listItems, HSSFCell cell) { - StringBuffer buffer = new StringBuffer(); + StringBuilder buffer = new StringBuilder(); // Note that again, an HSSFCellStye object is required and that // it's wrap text property should be set to 'true' HSSFCellStyle wrapStyle = workbook.createCellStyle(); @@ -339,8 +331,7 @@ public class InCellLists { public void multiLevelListInCell(HSSFWorkbook workbook, ArrayList multiLevelListItems, HSSFCell cell) { - StringBuffer buffer = new StringBuffer(); - ArrayList lowerLevelItems = null; + StringBuilder buffer = new StringBuilder(); // Note that again, an HSSFCellStye object is required and that // it's wrap text property should be set to 'true' HSSFCellStyle wrapStyle = workbook.createCellStyle(); @@ -353,7 +344,7 @@ public class InCellLists { buffer.append("\n"); // and then an ArrayList whose elements encapsulate the text // for the lower level list items. - lowerLevelItems = multiLevelListItem.getLowerLevelItems(); + ArrayList lowerLevelItems = multiLevelListItem.getLowerLevelItems(); if(!(lowerLevelItems == null) && !(lowerLevelItems.isEmpty())) { for(String item : lowerLevelItems) { buffer.append(InCellLists.TAB); @@ -401,10 +392,8 @@ public class InCellLists { int highLevelIncrement, int lowLevelStartingValue, int lowLevelIncrement) { - StringBuffer buffer = new StringBuffer(); + StringBuilder buffer = new StringBuilder(); int highLevelItemNumber = highLevelStartingValue; - int lowLevelItemNumber = 0; - ArrayList lowerLevelItems = null; // Note that again, an HSSFCellStye object is required and that // it's wrap text property should be set to 'true' HSSFCellStyle wrapStyle = workbook.createCellStyle(); @@ -413,20 +402,20 @@ public class InCellLists { for(MultiLevelListItem multiLevelListItem : multiLevelListItems) { // For each element in the ArrayList, get the text for the high // level list item...... - buffer.append(String.valueOf(highLevelItemNumber)); + buffer.append(highLevelItemNumber); buffer.append(". "); buffer.append(multiLevelListItem.getItemText()); buffer.append("\n"); // and then an ArrayList whose elements encapsulate the text // for the lower level list items. - lowerLevelItems = multiLevelListItem.getLowerLevelItems(); + ArrayList lowerLevelItems = multiLevelListItem.getLowerLevelItems(); if(!(lowerLevelItems == null) && !(lowerLevelItems.isEmpty())) { - lowLevelItemNumber = lowLevelStartingValue; + int lowLevelItemNumber = lowLevelStartingValue; for(String item : lowerLevelItems) { buffer.append(InCellLists.TAB); - buffer.append(String.valueOf(highLevelItemNumber)); + buffer.append(highLevelItemNumber); buffer.append("."); - buffer.append(String.valueOf(lowLevelItemNumber)); + buffer.append(lowLevelItemNumber); buffer.append(" "); buffer.append(item); buffer.append("\n"); @@ -459,8 +448,7 @@ public class InCellLists { public void multiLevelBulletedListInCell(HSSFWorkbook workbook, ArrayList multiLevelListItems, HSSFCell cell) { - StringBuffer buffer = new StringBuffer(); - ArrayList lowerLevelItems = null; + StringBuilder buffer = new StringBuilder(); // Note that again, an HSSFCellStye object is required and that // it's wrap text property should be set to 'true' HSSFCellStyle wrapStyle = workbook.createCellStyle(); @@ -475,7 +463,7 @@ public class InCellLists { buffer.append("\n"); // and then an ArrayList whose elements encapsulate the text // for the lower level list items. - lowerLevelItems = multiLevelListItem.getLowerLevelItems(); + ArrayList lowerLevelItems = multiLevelListItem.getLowerLevelItems(); if(!(lowerLevelItems == null) && !(lowerLevelItems.isEmpty())) { for(String item : lowerLevelItems) { buffer.append(InCellLists.TAB); diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index ba015a9f1..f6456bffa 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -954,8 +954,9 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss * Get the HSSFSheet object at the given index. * @param index of the sheet number (0-based physical & logical) * @return HSSFSheet at the provided index + * @throws IllegalArgumentException if the index is out of range (index + * < 0 || index >= getNumberOfSheets()). */ - @Override public HSSFSheet getSheetAt(int index) { diff --git a/src/java/org/apache/poi/ss/formula/functions/Bin2Dec.java b/src/java/org/apache/poi/ss/formula/functions/Bin2Dec.java index 9617877ca..cb206051c 100644 --- a/src/java/org/apache/poi/ss/formula/functions/Bin2Dec.java +++ b/src/java/org/apache/poi/ss/formula/functions/Bin2Dec.java @@ -84,7 +84,7 @@ public class Bin2Dec extends Fixed1ArgFunction implements FreeRefFunction { //Add 1 to obtained number sum++; - value = "-" + String.valueOf(sum); + value = "-" + sum; } } catch (NumberFormatException e) { return ErrorEval.NUM_ERROR; diff --git a/src/java/org/apache/poi/ss/usermodel/Workbook.java b/src/java/org/apache/poi/ss/usermodel/Workbook.java index 85c7ca724..f5043b727 100644 --- a/src/java/org/apache/poi/ss/usermodel/Workbook.java +++ b/src/java/org/apache/poi/ss/usermodel/Workbook.java @@ -253,6 +253,8 @@ public interface Workbook extends Closeable, Iterable { * * @param index of the sheet number (0-based physical & logical) * @return Sheet at the provided index + * @throws IllegalArgumentException if the index is out of range (index + * < 0 || index >= getNumberOfSheets()). */ Sheet getSheetAt(int index); diff --git a/src/java/org/apache/poi/ss/util/SheetUtil.java b/src/java/org/apache/poi/ss/util/SheetUtil.java index d64dbeba8..f234380fe 100644 --- a/src/java/org/apache/poi/ss/util/SheetUtil.java +++ b/src/java/org/apache/poi/ss/util/SheetUtil.java @@ -128,7 +128,7 @@ public class SheetUtil { // We should only be checking merged regions if useMergedCells is true. Why are we doing this for-loop? int colspan = 1; for (CellRangeAddress region : sheet.getMergedRegions()) { - if (containsCell(region, row.getRowNum(), column)) { + if (region.isInRange(row.getRowNum(), column)) { if (!useMergedCells) { // If we're not using merged cells, skip this one and move on to the next. return -1; @@ -151,8 +151,8 @@ public class SheetUtil { if (cellType == CellType.STRING) { RichTextString rt = cell.getRichStringCellValue(); String[] lines = rt.getString().split("\\n"); - for (int i = 0; i < lines.length; i++) { - String txt = lines[i] + defaultChar; + for (String line : lines) { + String txt = line + defaultChar; AttributedString str = new AttributedString(txt); copyAttributes(font, str, 0, txt.length()); @@ -193,7 +193,7 @@ public class SheetUtil { * @param defaultCharWidth the width of a character using the default font in a workbook * @param colspan the number of columns that is spanned by the cell (1 if the cell is not part of a merged region) * @param style the cell style, which contains text rotation and indention information needed to compute the cell width - * @param width the minimum best-fit width. This algorithm will only return values greater than or equal to the minimum width. + * @param minWidth the minimum best-fit width. This algorithm will only return values greater than or equal to the minimum width. * @param str the text contained in the cell * @return the best fit cell width */ @@ -219,8 +219,7 @@ public class SheetUtil { } // frameWidth accounts for leading spaces which is excluded from bounds.getWidth() final double frameWidth = bounds.getX() + bounds.getWidth(); - final double width = Math.max(minWidth, ((frameWidth / colspan) / defaultCharWidth) + style.getIndention()); - return width; + return Math.max(minWidth, ((frameWidth / colspan) / defaultCharWidth) + style.getIndention()); } /** @@ -273,13 +272,12 @@ public class SheetUtil { AttributedString str = new AttributedString(String.valueOf(defaultChar)); copyAttributes(defaultFont, str, 0, 1); TextLayout layout = new TextLayout(str.getIterator(), fontRenderContext); - int defaultCharWidth = (int) layout.getAdvance(); - return defaultCharWidth; + return (int) layout.getAdvance(); } /** * Compute width of a single cell in a row - * Convenience method for {@link getCellWidth} + * Convenience method for {@link #getCellWidth} * * @param row the row that contains the cell of interest * @param column the column number of the cell whose width is to be calculated @@ -334,7 +332,7 @@ public class SheetUtil { private static void copyAttributes(Font font, AttributedString str, int startIdx, int endIdx) { str.addAttribute(TextAttribute.FAMILY, font.getFontName(), startIdx, endIdx); str.addAttribute(TextAttribute.SIZE, (float)font.getFontHeightInPoints()); - if (font.getBoldweight() == Font.BOLDWEIGHT_BOLD) str.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, startIdx, endIdx); + if (font.getBold()) str.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, startIdx, endIdx); if (font.getItalic() ) str.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, startIdx, endIdx); if (font.getUnderline() == Font.U_SINGLE ) str.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, startIdx, endIdx); } @@ -348,6 +346,7 @@ public class SheetUtil { * @return true if the range contains the cell [rowIx, colIx] * @deprecated 3.15 beta 2. Use {@link CellRangeAddressBase#isInRange(int, int)}. */ + @Deprecated public static boolean containsCell(CellRangeAddress cr, int rowIx, int colIx) { return cr.isInRange(rowIx, colIx); } diff --git a/src/scratchpad/src/org/apache/poi/hwpf/converter/WordToFoUtils.java b/src/scratchpad/src/org/apache/poi/hwpf/converter/WordToFoUtils.java index e901de821..32cf161a5 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/converter/WordToFoUtils.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/converter/WordToFoUtils.java @@ -154,37 +154,37 @@ public class WordToFoUtils extends AbstractWordUtils { block.setAttribute( "text-indent", - String.valueOf( paragraph.getFirstLineIndent() - / TWIPS_PER_PT ) + paragraph.getFirstLineIndent() + / TWIPS_PER_PT + "pt" ); } if ( paragraph.getIndentFromLeft() != 0 ) { block.setAttribute( "start-indent", - String.valueOf( paragraph.getIndentFromLeft() - / TWIPS_PER_PT ) + paragraph.getIndentFromLeft() + / TWIPS_PER_PT + "pt" ); } if ( paragraph.getIndentFromRight() != 0 ) { block.setAttribute( "end-indent", - String.valueOf( paragraph.getIndentFromRight() - / TWIPS_PER_PT ) + paragraph.getIndentFromRight() + / TWIPS_PER_PT + "pt" ); } if ( paragraph.getSpacingBefore() != 0 ) { block.setAttribute( "space-before", - String.valueOf( paragraph.getSpacingBefore() / TWIPS_PER_PT ) + paragraph.getSpacingBefore() / TWIPS_PER_PT + "pt" ); } if ( paragraph.getSpacingAfter() != 0 ) { block.setAttribute( "space-after", - String.valueOf( paragraph.getSpacingAfter() / TWIPS_PER_PT ) + paragraph.getSpacingAfter() / TWIPS_PER_PT + "pt" ); } } diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSDocumentPath.java b/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSDocumentPath.java index fef200fdc..0ca030438 100644 --- a/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSDocumentPath.java +++ b/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSDocumentPath.java @@ -227,7 +227,7 @@ public final class TestPOIFSDocumentPath extends TestCase { { for (int k = 0; k < paths.length; k++) { - assertEquals(String.valueOf(j) + "<>" + String.valueOf(k), + assertEquals(j + "<>" + k, paths[ j ], paths[ k ]); } } @@ -274,13 +274,13 @@ public final class TestPOIFSDocumentPath extends TestCase { { if (k == j) { - assertEquals(String.valueOf(j) + "<>" - + String.valueOf(k), fullPaths[ j ], + assertEquals(j + "<>" + + k, fullPaths[ j ], builtUpPaths[ k ]); } else { - assertTrue(String.valueOf(j) + "<>" + String.valueOf(k), + assertTrue(j + "<>" + k, !(fullPaths[ j ].equals(builtUpPaths[ k ]))); } } @@ -306,7 +306,7 @@ public final class TestPOIFSDocumentPath extends TestCase { { for (int j = 0; j < badPaths.length; j++) { - assertTrue(String.valueOf(j) + "<>" + String.valueOf(k), + assertTrue(j + "<>" + k, !(fullPaths[ k ].equals(badPaths[ j ]))); } }