]> source.dussan.org Git - poi.git/commitdiff
merge with trunk
authorAndreas Beeker <kiwiwings@apache.org>
Wed, 17 Sep 2014 21:12:36 +0000 (21:12 +0000)
committerAndreas Beeker <kiwiwings@apache.org>
Wed, 17 Sep 2014 21:12:36 +0000 (21:12 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/xml_signature@1625828 13f79535-47bb-0310-9956-ffa450edef68

125 files changed:
KEYS
build.xml
src/examples/src/org/apache/poi/xssf/eventusermodel/examples/FromHowTo.java
src/java/org/apache/poi/hssf/dev/BiffViewer.java
src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java
src/java/org/apache/poi/hssf/record/DConRefRecord.java
src/java/org/apache/poi/hssf/record/DrawingGroupRecord.java
src/java/org/apache/poi/hssf/record/PasswordRecord.java
src/java/org/apache/poi/hssf/record/aggregates/WorksheetProtectionBlock.java
src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java
src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
src/java/org/apache/poi/hssf/usermodel/HSSFShape.java
src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java
src/java/org/apache/poi/poifs/crypt/HashAlgorithm.java
src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java
src/java/org/apache/poi/ss/SpreadsheetVersion.java
src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java
src/java/org/apache/poi/util/ArrayUtil.java
src/java/org/apache/poi/util/XMLHelper.java
src/ooxml/java/org/apache/poi/POIXMLProperties.java
src/ooxml/java/org/apache/poi/POIXMLPropertiesTextExtractor.java
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/PackagePropertiesUnmarshaller.java
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java
src/ooxml/java/org/apache/poi/util/DocumentHelper.java
src/ooxml/java/org/apache/poi/util/SAXHelper.java
src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java
src/ooxml/java/org/apache/poi/xslf/extractor/XSLFPowerPointExtractor.java
src/ooxml/java/org/apache/poi/xslf/model/geom/CustomGeometry.java
src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTable.java
src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTableRow.java
src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTextBody.java
src/ooxml/java/org/apache/poi/xslf/usermodel/RenderableShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFCommentAuthors.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFComments.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFCommonSlideData.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTable.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableRow.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableStyles.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
src/ooxml/java/org/apache/poi/xssf/eventusermodel/ReadOnlySharedStringsTable.java
src/ooxml/java/org/apache/poi/xssf/eventusermodel/XSSFSheetXMLHandler.java
src/ooxml/java/org/apache/poi/xssf/extractor/XSSFEventBasedExcelExtractor.java
src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java
src/ooxml/java/org/apache/poi/xssf/extractor/XSSFImportFromXML.java
src/ooxml/java/org/apache/poi/xssf/model/CommentsTable.java
src/ooxml/java/org/apache/poi/xssf/model/MapInfo.java
src/ooxml/java/org/apache/poi/xssf/model/SingleXmlCells.java
src/ooxml/java/org/apache/poi/xssf/model/ThemesTable.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChart.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheDefinition.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/ColumnHelper.java
src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java
src/ooxml/java/org/apache/poi/xssf/util/CTColComparator.java
src/ooxml/java/org/apache/poi/xwpf/model/XWPFCommentsDecorator.java
src/ooxml/java/org/apache/poi/xwpf/model/XWPFHyperlinkDecorator.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/AbstractXWPFSDT.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFComment.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnotes.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFLatentStyles.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTContent.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java
src/ooxml/testcases/org/apache/poi/TestPOIXMLProperties.java
src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java
src/ooxml/testcases/org/apache/poi/poifs/crypt/PkiTestUtils.java
src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java
src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXMLSlideShow.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java
src/ooxml/testcases/org/apache/poi/xssf/TestSheetProtection.java
src/ooxml/testcases/org/apache/poi/xssf/TestWorkbookProtection.java
src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFExportToXML.java
src/ooxml/testcases/org/apache/poi/xssf/model/TestCalculationChain.java
src/ooxml/testcases/org/apache/poi/xssf/model/TestMapInfo.java
src/ooxml/testcases/org/apache/poi/xssf/model/TestThemesTable.java [new file with mode: 0644]
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFColGrouping.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFColor.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFont.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFRichTextString.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/extensions/TestXSSFCellFill.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/helpers/TestColumnHelper.java
src/ooxml/testcases/org/apache/poi/xssf/util/TestCTColComparator.java
src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java
src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java
src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFRun.java
src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java
src/scratchpad/src/org/apache/poi/hwpf/model/NilPICFAndBinData.java
src/scratchpad/src/org/apache/poi/hwpf/model/PlfLfo.java
src/scratchpad/src/org/apache/poi/hwpf/model/Sttb.java
src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java
src/testcases/org/apache/poi/hssf/record/TestDConRefRecord.java
src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java
test-data/spreadsheet/56730.xlsx [new file with mode: 0644]
test-data/spreadsheet/Themes.xlsx [new file with mode: 0644]
test-data/spreadsheet/workbookProtection-sheet_password-2013.xlsx [new file with mode: 0644]
test-data/spreadsheet/workbookProtection-workbook_password-2013.xlsx [new file with mode: 0644]
test-data/spreadsheet/workbookProtection-workbook_password_user_range-2010.xlsx [new file with mode: 0644]

diff --git a/KEYS b/KEYS
index 5c1de0c2a3191f5e8c4e8842c54ee376b623e4e1..340f8504dbe8553857e7376ef117b175db1a5096 100644 (file)
--- a/KEYS
+++ b/KEYS
@@ -1753,3 +1753,46 @@ 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 <kiwiwings@apache.org>
+uid                  Andreas Beeker (kiwiwings) <andreas.beeker@gmx.de>
+sub   2048R/EE864ED6 2014-08-17 [expires: 2016-08-16]
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1
+
+mQENBFPwtjQBCADWg7jYCGq+QFGfB8nLLQs/WEw4XJiAY9q65qWX1clNuVgTF9Nn
+ABBOy4KiSDR9XWmARZlC2trKfdoFEnNJ6EnFkLhOjzZKiy4jkyxCctKfbV+sMzCm
+ODjjNQtn+nYmOu7a8Xg3g3vTnikkuHZqWvK0O0VYouW/p1NHelUejQbOPuUKukD1
+omzskuYgteTZ9Jn8efJMIymg9dGubuvN4HvUdEO0/u6K2MCZjIqNEPeqWIuZXeMb
++4nGv2r0jSQAU94g3hueooqbUf+Mk2+H5O1d/h2Cii9qVvi6gELdVw9H+5Ir9AFc
+ynsmvxrPIxraBMPgrXmvPFOTlqlizyFv2O7pABEBAAG0MkFuZHJlYXMgQmVla2Vy
+IChraXdpd2luZ3MpIDxhbmRyZWFzLmJlZWtlckBnbXguZGU+iQE+BBMBAgAoBQJT
+8LY0AhsDBQkDwmcABgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRCpPhxLJgYs
+4wvFB/9hEV8LzHUpD0X/vM9pfW1ZbTl2GNiZfuMh6/KlqB3C4gL3SLLRlk4mEPM3
+qlZWCqZiWVp5zz1C/j/+BLJW3c+j3rCUEAsobsR6HkxBr7N0LUnurbMXyiOvdg4l
+AS42Vi1JrydFdih1HCI3NiGMHAV/8NEdtmLt7Ue8Opx01R6rwXBomX5BHJXnzbZR
+bCbdor/UnO8ff5K4jwd6yhY0BV+bI2uD+vGq9nMld0JGj7W7qB+HzOAxpINtHksQ
+htTV/PBWjHTCNhOdGh1zyoyvJSshm1NkvwBVZYMs/0ujApcqxAXytGXonLiMmZME
+COjxAigph8T4PCEKdIqdsVxkC2ybtCVBbmRyZWFzIEJlZWtlciA8a2l3aXdpbmdz
+QGFwYWNoZS5vcmc+iQE+BBMBAgAoBQJT8RApAhsDBQkDwmcABgsJCAcDAgYVCAIJ
+CgsEFgIDAQIeAQIXgAAKCRCpPhxLJgYs4732CAC0tb5Wqjf3+/2M6ZzsJR9lqOI6
+SIwaxu0qnHVUJNzRrF01886uae7k086RCVvEXmSxnmGk86odbx/e7gD0esC9xoxz
+GRdo5AtMEh18b4fRsq3cdywPDUjvgQBvWXw+jhpJbJe7RRRKZS6X0dRLACn24tGw
+GPOkn1cE5gkHxUraEk84PKi69znCULasPOV1X46xU2j42N+v0XC3F1ZgFTesvBPh
+O9Nfaj99GnxpL8PmWyKvKm8SSLTmzLoZ+cXSNGGjJtsrnQn5tmhmEgp5K4DX7lsx
++lmfJ9X7+OUxgVHdkesz69d3h+9wBtVl6WqaA+Ocn/0xWr0X55J1OsW+1N2SuQEN
+BFPwtjQBCACln6mHC8Js3T3KJgNydimOCAFhLmS4e0ur03Y1nckB9zB/pMTLulDg
+tZwWSin3Kd40VZDyKi6mqOp5ldz6AsZ2CSx1GfI9iVhfuFqOaiBLqpNpdvf9nGL9
+OVoy1SdwTXgnboiIFtbTG3sVwD4x4qTRbmT22Ln/mIAICR2wxFBkzpbIQ7MfR/zE
+gRh2VlRUUrWUsnYdOh0xfxuYgsnPCjpTY8hvEno3H6kzXKmj2GQJtawMVs5bRo/G
+CM9lBBR/PAhB65ACzLmUUSsxjlmjZw0tCcOufg1RyAF/l6YVw1UOJaqXBfSPeZkL
+QBj9p8VNpasX/acIfpEaZLE8QhoO11ajABEBAAGJASUEGAECAA8FAlPwtjQCGwwF
+CQPCZwAACgkQqT4cSyYGLOPzLggAjHrdpMjZrHM5WqnxkJ1Eib1g14aScMGdOIw9
+NOSQ2AGvJjbSy4xyMEUg3S14I73JGYtJu8g9YvCHbuWiyzySBIuGNinMI/ZjET/w
+1noqoNaSlIY4UfFh30g+OikEzP9WXmo0Scg0XH/fJhX1wCpM/TVlphX0yNGmmkNB
+BqerRXC7Md4XOy001vvXZGM7vy+xOotyBOy/D4WNERSz3GVS3juCQGMWvMdqKQa+
+qoiVaXWfFHwg8u4bSHunrzNja17GyaZHdCEmM9vFzlaqBkoLWCMwIcaKnX9stQJp
+FZwpzgut7DanaPcCDk7LMBbntaJwRC72M0qcj16SUAdAuGt1yQ==
+=0DjT
+-----END PGP PUBLIC KEY BLOCK-----
index 8f27b57feb2883a25099da5c8dbb40300ef84604..8be3cb707de0eb7db6c26fba07ad0f007ca2635c 100644 (file)
--- a/build.xml
+++ b/build.xml
@@ -164,13 +164,17 @@ under the License.
     <property name="ooxml.xmlbeans26.jar" location="${ooxml.lib}/xmlbeans-2.6.0.jar"/>
     <property name="ooxml.xmlbeans26.url"
               value="${repository.m2}/maven2/org/apache/xmlbeans/xmlbeans/2.6.0/xmlbeans-2.6.0.jar"/>
-
+       
     <!-- coverage libs -->
     <property name="jacoco.zip" location="${main.lib}/jacoco-0.7.1.201405082137.zip"/>
     <property name="jacoco.url" value="${repository.m2}/maven2/org/jacoco/jacoco/0.7.1.201405082137/jacoco-0.7.1.201405082137.zip"/>
     <property name="asm.jar" location="${main.lib}/asm-all-5.0.3.jar"/>
     <property name="asm.url" value="${repository.m2}/maven2/org/ow2/asm/asm-all/5.0.3/asm-all-5.0.3.jar"/>
        
+       <!-- for testing with older Xerces implementation -->
+    <property name="xerces.jar" location="${main.lib}/xercesImpl-2.6.1.jar"/>
+    <property name="xerces.url" value="${repository.m2}/maven2/xerces/xercesImpl/2.6.1//xercesImpl-2.6.1.jar"/>
+
     <!-- license checks -->
     <property name="rat.jar" location="${main.lib}/apache-rat-0.10.jar"/>
     <property name="rat.url" value="${repository.m2}/maven2/org/apache/rat/apache-rat/0.10/apache-rat-0.10.jar"/>
@@ -254,6 +258,7 @@ under the License.
         <path refid="main.classpath"/>
         <pathelement location="${main.output.dir}"/>
         <pathelement location="${main.output.test.dir}"/>
+       <pathelement location="${additionaljar}"/>
     </path>
 
     <path id="test.scratchpad.classpath">
@@ -261,6 +266,7 @@ under the License.
         <pathelement location="${main.output.test.dir}"/>
         <pathelement location="${scratchpad.output.dir}"/>
         <pathelement location="${scratchpad.output.test.dir}"/>
+       <pathelement location="${additionaljar}"/>
     </path>
 
     <path id="test.ooxml.classpath">
@@ -268,6 +274,7 @@ under the License.
         <pathelement location="${ooxml.output.dir}"/>
         <pathelement location="${ooxml.output.test.dir}"/>
         <pathelement location="${main.output.test.dir}"/>
+       <pathelement location="${additionaljar}"/>
     </path>
 
     <path id="ooxml-lite.classpath">
@@ -300,6 +307,7 @@ under the License.
         <pathelement location="${excelant.output.dir}"/>
         <pathelement location="${excelant.output.test.dir}"/>
         <pathelement location="${main.output.test.dir}"/>
+       <pathelement location="${additionaljar}"/>
     </path>
 
     <path id="lib.jacoco">
@@ -372,6 +380,7 @@ under the License.
                                <include name="jacoco-0.6*"/>
                                <include name="log4j-1.2.13*"/>
                                <include name="org.jacoco.*-0.6.*"/>
+                               <include name="dom4j*"/>
                        </fileset>
                </delete>
 
@@ -388,6 +397,7 @@ under the License.
                     <available file="${asm.jar}"/>
                     <available file="${jacoco.zip}"/>
                     <available file="${rat.jar}"/>
+                    <available file="${xerces.jar}"/>
                 </and>
                 <isset property="disconnected"/>
             </or>
@@ -438,6 +448,10 @@ under the License.
                 <include name="lib/*.jar"/>
             </patternset>
         </unzip>
+        <antcall target="downloadfile">
+            <param name="sourcefile" value="${xerces.url}"/>
+            <param name="destfile" value="${xerces.jar}"/>
+        </antcall>
         <antcall target="downloadfile">
             <param name="sourcefile" value="${rat.url}"/>
             <param name="destfile" value="${rat.jar}"/>
index fc6604c649569729cccd045c146c3793eaa27303..4df63448ede05f127991d9d8ba7675444018cac5 100644 (file)
@@ -115,6 +115,7 @@ public class FromHowTo {
                        if(nextIsString) {
                                int idx = Integer.parseInt(lastContents);
                                lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
+            nextIsString = false;
                        }
 
                        // v => contents of a cell
index 19cdd02942e7ffdf0d3bef259b47124280c8d39e..5451b27899a5d4fe84883843c6e6b7d1a9a64fc9 100644 (file)
@@ -145,7 +145,7 @@ public final class BiffViewer {
                        case DatRecord.sid:            return new DatRecord(in);
                        case DataFormatRecord.sid:     return new DataFormatRecord(in);
                        case DateWindow1904Record.sid: return new DateWindow1904Record(in);
-               case DConRefRecord.sid: return new DConRefRecord(in);
+                       case DConRefRecord.sid: return new DConRefRecord(in);
                        case DefaultColWidthRecord.sid:return new DefaultColWidthRecord(in);
                        case DefaultDataLabelTextPropertiesRecord.sid: return new DefaultDataLabelTextPropertiesRecord(in);
                        case DefaultRowHeightRecord.sid: return new DefaultRowHeightRecord(in);
index 078f0205d79daf70ec0e14039fe3ff5c9aa349f6..d3263834c7a79759d56bc290c61fa18bd80eefd1 100644 (file)
@@ -57,20 +57,19 @@ public abstract class AbstractEscherHolderRecord extends Record {
     public AbstractEscherHolderRecord(RecordInputStream in)
     {
         escherRecords = new ArrayList<EscherRecord>();
-        if (! DESERIALISE )
-        {
+        if (! DESERIALISE ) {
             rawDataContainer.concatenate(in.readRemainder());
-        }
-        else
-        {
+        } else {
             byte[] data = in.readAllContinuedRemainder();
             convertToEscherRecords( 0, data.length, data );
         }
     }
 
     protected void convertRawBytesToEscherRecords() {
-        byte[] rawData = getRawData();
-       convertToEscherRecords(0, rawData.length, rawData);
+        if (! DESERIALISE ) {
+            byte[] rawData = getRawData();
+               convertToEscherRecords(0, rawData.length, rawData);
+        }
     }
     private void convertToEscherRecords( int offset, int size, byte[] data )
     {
@@ -224,7 +223,7 @@ public abstract class AbstractEscherHolderRecord extends Record {
 
     public EscherRecord getEscherRecord(int index)
     {
-        return (EscherRecord) escherRecords.get(index);
+        return escherRecords.get(index);
     }
 
     /**
index 629dc00e515cf42685de1314708b846ee90d3639..deccff347b9bbdbc196f52d79371cfdeb531b233 100644 (file)
  */
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.ArrayUtil;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.LittleEndianOutput;
 
+import java.util.Arrays;
+
 /**
  * DConRef records specify a range in a workbook (internal or external) that serves as a data source
  * for pivot tables or data consolidation.
@@ -273,7 +274,7 @@ public class DConRefRecord extends StandardRecord
      */
     public byte[] getPath()
     {
-        return ArrayUtil.copyOf(path, path.length);
+        return Arrays.copyOf(path, path.length);
     }
 
     /**
@@ -291,7 +292,7 @@ public class DConRefRecord extends StandardRecord
             {
                 offset++;
             }
-            String out = new String(ArrayUtil.copyOfRange(path, offset, path.length));
+            String out = new String(Arrays.copyOfRange(path, offset, path.length));
             //UNC paths have \u0003 chars as path separators.
             out = out.replaceAll("\u0003", "/");
             return out;
index 1264b60bcce61b627234a4822342ef73eabe913c..eeddf5e21a692cb5b96353a32f42451dfde50b26 100644 (file)
@@ -118,7 +118,7 @@ public final class DrawingGroupRecord extends AbstractEscherHolderRecord {
                 writeHeader( data, offset, segmentLength );
             writtenActualData += 4;
             offset += 4;
-            ArrayUtil.arraycopy( rawData, writtenRawData, data, offset, segmentLength );
+            System.arraycopy( rawData, writtenRawData, data, offset, segmentLength );
             offset += segmentLength;
             writtenRawData += segmentLength;
             writtenActualData += segmentLength;
index 9baff6f97d443db500e7252854ca7815fc412270..c38a1230cad71bd9521303790e74fbf7ccf54440 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.hssf.record;
 
+import org.apache.poi.poifs.crypt.CryptoFunctions;
 import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndianOutput;
 
@@ -39,23 +40,13 @@ public final class PasswordRecord extends StandardRecord {
         field_1_password = in.readShort();
     }
 
-    //this is the world's lamest "security".  thanks to Wouter van Vugt for making me
-    //not have to try real hard.  -ACO
+    /**
+     * Return the password hash
+     *
+     * @deprecated use {@link CryptoFunctions#createXorVerifier1(String)}
+     */
     public static short hashPassword(String password) {
-        byte[] passwordCharacters = password.getBytes();
-        int hash = 0;
-        if (passwordCharacters.length > 0) {
-            int charIndex = passwordCharacters.length;
-            while (charIndex-- > 0) {
-                hash = ((hash >> 14) & 0x01) | ((hash << 1) & 0x7fff);
-                hash ^= passwordCharacters[charIndex];
-            }
-            // also hash with charcount
-            hash = ((hash >> 14) & 0x01) | ((hash << 1) & 0x7fff);
-            hash ^= passwordCharacters.length;
-            hash ^= (0x8000 | ('N' << 8) | 'K');
-        }
-        return (short)hash;
+        return (short)CryptoFunctions.createXorVerifier1(password);
     }
 
     /**
index f838485f74d65d079f228438d8a1236b2e5a06e3..275fbf123a6b3dbd2f16e92d3391ef84d3c03dd3 100644 (file)
@@ -24,6 +24,7 @@ import org.apache.poi.hssf.record.ProtectRecord;
 import org.apache.poi.hssf.record.Record;
 import org.apache.poi.hssf.record.RecordFormatException;
 import org.apache.poi.hssf.record.ScenarioProtectRecord;
+import org.apache.poi.poifs.crypt.CryptoFunctions;
 
 /**
  * Groups the sheet protection records for a worksheet.
@@ -186,7 +187,7 @@ public final class WorksheetProtectionBlock extends RecordAggregate {
                ProtectRecord prec = getProtect();
                PasswordRecord pass = getPassword();
                prec.setProtect(true);
-               pass.setPassword(PasswordRecord.hashPassword(password));
+               pass.setPassword((short)CryptoFunctions.createXorVerifier1(password));
                if (_objectProtectRecord == null && shouldProtectObjects) {
                        ObjectProtectRecord rec = createObjectProtect();
                        rec.setProtect(true);
index de18107683c1a0689a4c578b78ff0f66ba761b6c..a69efe4eecca5d21d0e2c50362b3f9651c8e081c 100644 (file)
@@ -827,6 +827,29 @@ public final class HSSFCellStyle implements CellStyle {
        return _format.getShrinkToFit();
     }
        
+    /**
+     * Get the reading order, for RTL/LTR ordering of
+     *  the text.
+     * <p>0 means Context (Default), 1 means Left To Right,
+     *  and 2 means Right to Left</p>
+     *
+     * @return order - the reading order (0,1,2)
+     */
+    public short getReadingOrder() {
+        return _format.getReadingOrder();
+    }
+    /**
+     * Sets the reading order, for RTL/LTR ordering of
+     *  the text.
+     * <p>0 means Context (Default), 1 means Left To Right,
+     *  and 2 means Right to Left</p>
+     *
+     * @param order - the reading order (0,1,2)
+     */
+    public void setReadingOrder(short order) {
+        _format.setReadingOrder(order);
+    }
+    
     /**
      * Verifies that this style belongs to the supplied Workbook.
      * Will throw an exception if it belongs to a different one.
index 0a65bbd8ffe4b0c7358783f57cb1b085938399b7..c46f7b7a92f5f1ea6c9c7022b4f3115fca2f2d01 100644 (file)
@@ -42,6 +42,10 @@ public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor {
     /**
      * Creates a new client anchor and sets the top-left and bottom-right
      * coordinates of the anchor.
+     * 
+     * Note: Microsoft Excel seems to sometimes disallow 
+     * higher y1 than y2 or higher x1 than x2, you might need to 
+     * reverse them and draw shapes vertically or horizontally flipped! 
      *
      * @param dx1  the x coordinate within the first cell.
      * @param dy1  the y coordinate within the first cell.
@@ -186,8 +190,12 @@ public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor {
     }
 
     /**
-     * Dets the top-left and bottom-right
-     * coordinates of the anchor.
+     * Sets the top-left and bottom-right coordinates of 
+     * the anchor.
+     * 
+     * Note: Microsoft Excel seems to sometimes disallow 
+     * higher y1 than y2 or higher x1 than x2, you might need to 
+     * reverse them and draw shapes vertically or horizontally flipped! 
      *
      * @param x1   the x coordinate within the first cell.
      * @param y1   the y coordinate within the first cell.
index 7745801fd2362ff5db15830a5e44d6a56499a203..dda4b395759509f438d169d397e212e06902e6c8 100644 (file)
@@ -171,6 +171,10 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
     /**
      * Creates a simple shape.  This includes such shapes as lines, rectangles,
      * and ovals.
+     * 
+     * Note: Microsoft Excel seems to sometimes disallow 
+     * higher y1 than y2 or higher x1 than x2 in the anchor, you might need to 
+     * reverse them and draw shapes vertically or horizontally flipped! 
      *
      * @param anchor the client anchor describes how this group is attached
      *               to the sheet.
index 4ea7d31e6a6b75bee07e46a3da6cc8477a712892..4775122f8206b7edb1466f62b8cb39ae2515ccc2 100644 (file)
@@ -27,6 +27,11 @@ import java.io.IOException;
 
 /**
  * An abstract shape.
+ * 
+ * Note: Microsoft Excel seems to sometimes disallow 
+ * higher y1 than y2 or higher x1 than x2 in the anchor, you might need to 
+ * reverse them and draw shapes vertically or horizontally flipped via
+ * setFlipVertical() or setFlipHorizontally(). 
  */
 public abstract class HSSFShape {
     public static final int LINEWIDTH_ONE_PT = 12700;
index c84431fd85c9d456742c29173e435c6d352aea40..875ade3ab9ad912c4cb4a63d3cd1068835d9a30a 100644 (file)
@@ -181,14 +181,20 @@ public class CryptoFunctions {
     }\r
 \r
     /**\r
-     * \r
+     * Initialize a new cipher object with the given cipher properties\r
+     * If the given algorithm is not implemented in the JCE, it will try to load it from the bouncy castle\r
+     * provider.\r
      *\r
-     * @param key\r
-     * @param chain\r
-     * @param vec\r
+     * @param key the secrect key\r
+     * @param cipherAlgorithm the cipher algorithm\r
+     * @param chain the chaining mode\r
+     * @param vec the initialization vector (IV), can be null\r
      * @param cipherMode Cipher.DECRYPT_MODE or Cipher.ENCRYPT_MODE\r
+     * @param padding\r
      * @return the requested cipher\r
      * @throws GeneralSecurityException\r
+     * @throws EncryptedDocumentException if the initialization failed or if an algorithm was specified,\r
+     *   which depends on a missing bouncy castle provider \r
      */\r
     public static Cipher getCipher(Key key, CipherAlgorithm cipherAlgorithm, ChainingMode chain, byte[] vec, int cipherMode, String padding) {\r
         int keySizeInBytes = key.getEncoded().length;\r
@@ -227,10 +233,26 @@ public class CryptoFunctions {
         }\r
     }    \r
     \r
+    /**\r
+     * Returns a new byte array with a truncated to the given size. \r
+     * If the hash has less then size bytes, it will be filled with 0x36-bytes\r
+     *\r
+     * @param hash the to be truncated/filled hash byte array\r
+     * @param size the size of the returned byte array\r
+     * @return the padded hash\r
+     */\r
     public static byte[] getBlock36(byte[] hash, int size) {\r
         return getBlockX(hash, size, (byte)0x36);\r
     }\r
 \r
+    /**\r
+     * Returns a new byte array with a truncated to the given size. \r
+     * If the hash has less then size bytes, it will be filled with 0-bytes\r
+     *\r
+     * @param hash the to be truncated/filled hash byte array\r
+     * @param size the size of the returned byte array\r
+     * @return the padded hash\r
+     */\r
     public static byte[] getBlock0(byte[] hash, int size) {\r
         return getBlockX(hash, size, (byte)0);\r
     }\r
@@ -334,11 +356,11 @@ public class CryptoFunctions {
         byte[] generatedKey = new byte[4];\r
 \r
         //Maximum length of the password is 15 chars.\r
-        final int intMaxPasswordLength = 15; \r
+        final int maxPasswordLength = 15; \r
         \r
         if (!"".equals(password)) {\r
             // Truncate the password to 15 characters\r
-            password = password.substring(0, Math.min(password.length(), intMaxPasswordLength));\r
+            password = password.substring(0, Math.min(password.length(), maxPasswordLength));\r
 \r
             // Construct a new NULL-terminated string consisting of single-byte characters:\r
             //  -- > Get the single-byte values by iterating through the Unicode characters of the truncated Password.\r
@@ -362,7 +384,7 @@ public class CryptoFunctions {
             //          the most significant, if the bit is set, XOR the keys high-order word with the corresponding word from \r
             //          the Encryption Matrix\r
             for (int i = 0; i < arrByteChars.length; i++) {\r
-                int tmp = intMaxPasswordLength - arrByteChars.length + i;\r
+                int tmp = maxPasswordLength - arrByteChars.length + i;\r
                 for (int intBit = 0; intBit < 7; intBit++) {\r
                     if ((arrByteChars[i] & (0x0001 << intBit)) != 0) {\r
                         highOrderWord ^= EncryptionMatrix[tmp][intBit];\r
@@ -372,22 +394,28 @@ public class CryptoFunctions {
             \r
             // Compute the low-order word of the new key:\r
             \r
-            // Initialize with 0\r
-            int lowOrderWord = 0;\r
+            // SET Verifier TO 0x0000\r
+            short verifier = 0;\r
 \r
-            // For each character in the password, going backwards\r
-            for (int i = arrByteChars.length - 1; i >= 0; i--) {\r
-                // low-order word = (((low-order word SHR 14) AND 0x0001) OR (low-order word SHL 1) AND 0x7FFF)) XOR character\r
-                lowOrderWord = (((lowOrderWord >> 14) & 0x0001) | ((lowOrderWord << 1) & 0x7FFF)) ^ arrByteChars[i];\r
+            // FOR EACH PasswordByte IN PasswordArray IN REVERSE ORDER\r
+            for (int i = arrByteChars.length-1; i >= 0; i--) {\r
+                // SET Verifier TO Intermediate3 BITWISE XOR PasswordByte\r
+                verifier = rotateLeftBase15Bit(verifier);\r
+                verifier ^= arrByteChars[i];\r
             }\r
 \r
-            // Lastly,low-order word = (((low-order word SHR 14) AND 0x0001) OR (low-order word SHL 1) AND 0x7FFF)) XOR password length XOR 0xCE4B.\r
-            lowOrderWord = (((lowOrderWord >> 14) & 0x0001) | ((lowOrderWord << 1) & 0x7FFF)) ^ arrByteChars.length ^ 0xCE4B;\r
+            // as we haven't prepended the password length into the input array\r
+            // we need to do it now separately ...\r
+            verifier = rotateLeftBase15Bit(verifier);\r
+            verifier ^= arrByteChars.length;\r
+            \r
+            // RETURN Verifier BITWISE XOR 0xCE4B\r
+            verifier ^= 0xCE4B; // (0x8000 | ('N' << 8) | 'K')\r
 \r
             // The byte order of the result shall be reversed [password "Example": 0x64CEED7E becomes 7EEDCE64],\r
             // and that value shall be hashed as defined by the attribute values.\r
             \r
-            LittleEndian.putShort(generatedKey, 0, (short)lowOrderWord);\r
+            LittleEndian.putShort(generatedKey, 0, verifier);\r
             LittleEndian.putShort(generatedKey, 2, (short)highOrderWord);\r
         }\r
         \r
@@ -424,7 +452,7 @@ public class CryptoFunctions {
      * @see <a href="http://msdn.microsoft.com/en-us/library/dd905229.aspx">2.3.7.4 Binary Document Password Verifier Derivation Method 2</a>\r
      * \r
      * @param password the password\r
-     * @return the verifier\r
+     * @return the verifier (actually a short value)\r
      */\r
     public static int createXorVerifier1(String password) {\r
         // the verifier for method 1 is part of the verifier for method 2\r
@@ -483,4 +511,25 @@ public class CryptoFunctions {
     private static byte rotateLeft(byte bits, int shift) {\r
         return (byte)(((bits & 0xff) << shift) | ((bits & 0xff) >>> (8 - shift)));\r
     }\r
+    \r
+    private static short rotateLeftBase15Bit(short verifier) {\r
+        /*\r
+         * IF (Verifier BITWISE AND 0x4000) is 0x0000\r
+         *    SET Intermediate1 TO 0\r
+         * ELSE\r
+         *    SET Intermediate1 TO 1\r
+         * ENDIF\r
+         */\r
+        short intermediate1 = (short)(((verifier & 0x4000) == 0) ? 0 : 1);\r
+        /*\r
+         *  SET Intermediate2 TO Verifier MULTIPLED BY 2\r
+         *  SET most significant bit of Intermediate2 TO 0\r
+         */\r
+        short intermediate2 = (short)((verifier<<1) & 0x7FFF);\r
+        /*\r
+         *  SET Intermediate3 TO Intermediate1 BITWISE OR Intermediate2\r
+         */\r
+        short intermediate3 = (short)(intermediate1 | intermediate2);\r
+        return intermediate3;\r
+    }\r
 }\r
index e69f8f073645f6b1f048ec0ceb5f4f741ce8e291..8f2efc2f7179636894fce8689b6eb5aae376a6b8 100644 (file)
@@ -68,4 +68,11 @@ public enum HashAlgorithm {
         }\r
         throw new EncryptedDocumentException("hash algorithm not found");\r
     }\r
+    \r
+    public static HashAlgorithm fromString(String string) {\r
+        for (HashAlgorithm ha : values()) {\r
+            if (ha.ecmaString.equalsIgnoreCase(string) || ha.jceId.equalsIgnoreCase(string)) return ha;\r
+        }\r
+        throw new EncryptedDocumentException("hash algorithm not found");\r
+    }\r
 }
\ No newline at end of file
index 6099bb1ece4fdf8a7e9ceffa833afcbed6bc5156..f21f6a39a03ca6a1b5db1296d07cd9a368209ca4 100644 (file)
@@ -153,7 +153,8 @@ public class NPOIFSFileSystem extends BlockStore
      *  when you're done to have the underlying file closed, as the file is
      *  kept open during normal operation to read the data out.</p> 
      *  
-     * @param file the File from which to read the data
+     * @param file the File from which to read or read/write the data
+     * @param readOnly whether the POIFileSystem will only be used in read-only mode
      *
      * @exception IOException on errors reading, or on invalid data
      */
@@ -165,20 +166,40 @@ public class NPOIFSFileSystem extends BlockStore
     
     /**
      * <p>Creates a POIFSFileSystem from an open <tt>FileChannel</tt>. This uses 
-     *  less memory than creating from an <tt>InputStream</tt>.</p>
+     *  less memory than creating from an <tt>InputStream</tt>. The stream will
+     *  be used in read-only mode.</p>
      *  
      * <p>Note that with this constructor, you will need to call {@link #close()}
      *  when you're done to have the underlying Channel closed, as the channel is
      *  kept open during normal operation to read the data out.</p> 
      *  
-     * @param channel the FileChannel from which to read and write the data
+     * @param channel the FileChannel from which to read the data
      *
      * @exception IOException on errors reading, or on invalid data
      */
     public NPOIFSFileSystem(FileChannel channel)
          throws IOException
     {
-       this(channel, null, false, false);
+       this(channel, true);
+    }
+    
+    /**
+     * <p>Creates a POIFSFileSystem from an open <tt>FileChannel</tt>. This uses 
+     *  less memory than creating from an <tt>InputStream</tt>.</p>
+     *  
+     * <p>Note that with this constructor, you will need to call {@link #close()}
+     *  when you're done to have the underlying Channel closed, as the channel is
+     *  kept open during normal operation to read the data out.</p> 
+     *  
+     * @param channel the FileChannel from which to read or read/write the data
+     * @param readOnly whether the POIFileSystem will only be used in read-only mode
+     *
+     * @exception IOException on errors reading, or on invalid data
+     */
+    public NPOIFSFileSystem(FileChannel channel, boolean readOnly)
+         throws IOException
+    {
+       this(channel, null, readOnly, false);
     }
     
     private NPOIFSFileSystem(FileChannel channel, File srcFile, boolean readOnly, boolean closeChannelOnError)
index 8030e02283f4865b6004555ec539e53dbe10421d..45594d3c263e0e824e795cc4a41a95526375c760 100644 (file)
@@ -21,105 +21,111 @@ import org.apache.poi.ss.util.CellReference;
 
 /**
  * This enum allows spreadsheets from multiple Excel versions to be handled by the common code.
- * Properties of this enum correspond to attributes of the <i>spreadsheet</i> that are easily
+ * <p>Properties of this enum correspond to attributes of the <i>spreadsheet</i> that are easily
  * discernable to the user.  It is not intended to deal with low-level issues like file formats.
- * <p/>
- *
- * @author Josh Micich
- * @author Yegor Kozlov
  */
 public enum SpreadsheetVersion {
-       /**
-        * Excel97 format aka BIFF8
-        * <ul>
-        * <li>The total number of available columns is 256 (2^8)</li>
-        * <li>The total number of available rows is 64k (2^16)</li>
-        * <li>The maximum number of arguments to a function is 30</li>
-        * <li>Number of conditional format conditions on a cell is 3</li>
+    /**
+     * Excel97 format aka BIFF8
+     * <ul>
+     * <li>The total number of available columns is 256 (2^8)</li>
+     * <li>The total number of available rows is 64k (2^16)</li>
+     * <li>The maximum number of arguments to a function is 30</li>
+     * <li>Number of conditional format conditions on a cell is 3</li>
+     * <li>Number of cell styles is 4000</li>
      * <li>Length of text cell contents is 32767</li>
-        * </ul>
-        */
-       EXCEL97(0x10000, 0x0100, 30, 3, 32767),
-
-       /**
-        * Excel2007
-        *
-        * <ul>
-        * <li>The total number of available columns is 16K (2^14)</li>
-        * <li>The total number of available rows is 1M (2^20)</li>
-        * <li>The maximum number of arguments to a function is 255</li>
-        * <li>Number of conditional format conditions on a cell is unlimited
-        * (actually limited by available memory in Excel)</li>
+     * </ul>
+     */
+    EXCEL97(0x10000, 0x0100, 30, 3, 4000, 32767),
+
+    /**
+     * Excel2007
+     *
+     * <ul>
+     * <li>The total number of available columns is 16K (2^14)</li>
+     * <li>The total number of available rows is 1M (2^20)</li>
+     * <li>The maximum number of arguments to a function is 255</li>
+     * <li>Number of conditional format conditions on a cell is unlimited
+     * (actually limited by available memory in Excel)</li>
+     * <li>Number of cell styles is 64000</li>
      * <li>Length of text cell contents is 32767</li>
-        * <ul>
-        */
-       EXCEL2007(0x100000, 0x4000, 255, Integer.MAX_VALUE, 32767);
-
-       private final int _maxRows;
-       private final int _maxColumns;
-       private final int _maxFunctionArgs;
-       private final int _maxCondFormats;
+     * <ul>
+     */
+    EXCEL2007(0x100000, 0x4000, 255, Integer.MAX_VALUE, 64000, 32767);
+
+    private final int _maxRows;
+    private final int _maxColumns;
+    private final int _maxFunctionArgs;
+    private final int _maxCondFormats;
+    private final int _maxCellStyles;
     private final int _maxTextLength;
 
-       private SpreadsheetVersion(int maxRows, int maxColumns, int maxFunctionArgs, int maxCondFormats, int maxText) {
-               _maxRows = maxRows;
-               _maxColumns = maxColumns;
-               _maxFunctionArgs = maxFunctionArgs;
-               _maxCondFormats = maxCondFormats;
+    private SpreadsheetVersion(int maxRows, int maxColumns, int maxFunctionArgs, int maxCondFormats, int maxCellStyles, int maxText) {
+        _maxRows = maxRows;
+        _maxColumns = maxColumns;
+        _maxFunctionArgs = maxFunctionArgs;
+        _maxCondFormats = maxCondFormats;
+        _maxCellStyles = maxCellStyles;
         _maxTextLength = maxText;
     }
 
-       /**
-        * @return the maximum number of usable rows in each spreadsheet
-        */
-       public int getMaxRows() {
-               return _maxRows;
-       }
-
-       /**
-        * @return the last (maximum) valid row index, equals to <code> getMaxRows() - 1 </code>
-        */
-       public int getLastRowIndex() {
-               return _maxRows - 1;
-       }
-
-       /**
-        * @return the maximum number of usable columns in each spreadsheet
-        */
-       public int getMaxColumns() {
-               return _maxColumns;
-       }
-
-       /**
-        * @return the last (maximum) valid column index, equals to <code> getMaxColumns() - 1 </code>
-        */
-       public int getLastColumnIndex() {
-               return _maxColumns - 1;
-       }
-
-       /**
-        * @return the maximum number arguments that can be passed to a multi-arg function (e.g. COUNTIF)
-        */
-       public int getMaxFunctionArgs() {
-               return _maxFunctionArgs;
-       }
-
-       /**
-        *
-        * @return the maximum number of conditional format conditions on a cell
-        */
-       public int getMaxConditionalFormats() {
-               return _maxCondFormats;
-       }
-
-       /**
-        *
-        * @return the last valid column index in a ALPHA-26 representation
-        *  (<code>IV</code> or <code>XFD</code>).
-        */
-       public String getLastColumnName() {
-               return CellReference.convertNumToColString(getLastColumnIndex());
-       }
+    /**
+     * @return the maximum number of usable rows in each spreadsheet
+     */
+    public int getMaxRows() {
+        return _maxRows;
+    }
+
+    /**
+     * @return the last (maximum) valid row index, equals to <code> getMaxRows() - 1 </code>
+     */
+    public int getLastRowIndex() {
+        return _maxRows - 1;
+    }
+
+    /**
+     * @return the maximum number of usable columns in each spreadsheet
+     */
+    public int getMaxColumns() {
+        return _maxColumns;
+    }
+
+    /**
+     * @return the last (maximum) valid column index, equals to <code> getMaxColumns() - 1 </code>
+     */
+    public int getLastColumnIndex() {
+        return _maxColumns - 1;
+    }
+
+    /**
+     * @return the maximum number arguments that can be passed to a multi-arg function (e.g. COUNTIF)
+     */
+    public int getMaxFunctionArgs() {
+        return _maxFunctionArgs;
+    }
+
+    /**
+     * @return the maximum number of conditional format conditions on a cell
+     */
+    public int getMaxConditionalFormats() {
+        return _maxCondFormats;
+    }
+
+    /**
+     * @return the maximum number of cell styles per spreadsheet
+     */
+    public int getMaxCellStyles() {
+        return _maxCellStyles;
+    }
+
+    /**
+     *
+     * @return the last valid column index in a ALPHA-26 representation
+     *  (<code>IV</code> or <code>XFD</code>).
+     */
+    public String getLastColumnName() {
+        return CellReference.convertNumToColString(getLastColumnIndex());
+    }
 
     /**
      * @return the maximum length of a text cell
@@ -127,5 +133,4 @@ public enum SpreadsheetVersion {
     public int getMaxTextLength() {
         return _maxTextLength;
     }
-
 }
index 8a32c9c8b1a1a582089b504cf478a830ee194a29..7cc140877619d41a8d610b85810717db48430757 100644 (file)
@@ -39,6 +39,7 @@ import org.apache.poi.ss.formula.eval.NumberEval;
 import org.apache.poi.ss.formula.eval.OperandResolver;
 import org.apache.poi.ss.formula.eval.StringEval;
 import org.apache.poi.ss.formula.eval.ValueEval;
+import org.apache.poi.ss.formula.function.FunctionMetadataRegistry;
 import org.apache.poi.ss.formula.functions.Choose;
 import org.apache.poi.ss.formula.functions.FreeRefFunction;
 import org.apache.poi.ss.formula.functions.Function;
@@ -486,12 +487,15 @@ public final class WorkbookEvaluator {
                                                continue;
                                        }
                                        if (evaluatedPredicate) {
-                                               // nothing to skip - true param folows
+                                               // nothing to skip - true param follows
                                        } else {
                                                int dist = attrPtg.getData();
                                                i+= countTokensToBeSkipped(ptgs, i, dist);
                                                Ptg nextPtg = ptgs[i+1];
-                                               if (ptgs[i] instanceof AttrPtg && nextPtg instanceof FuncVarPtg) {
+                                               if (ptgs[i] instanceof AttrPtg && nextPtg instanceof FuncVarPtg && 
+                                                       // in order to verify that there is no third param, we need to check 
+                                                       // if we really have the IF next or some other FuncVarPtg as third param, e.g. ROW()/COLUMN()!
+                                                       ((FuncVarPtg)nextPtg).getFunctionIndex() == FunctionMetadataRegistry.FUNCTION_INDEX_IF) {
                                                        // this is an if statement without a false param (as opposed to MissingArgPtg as the false param)
                                                        i++;
                                                        stack.push(BoolEval.FALSE);
index c8d46e134123c97ff8c9c21eac6ed3c5bd070193..17f6a2964a75ce1dcf2b73f56775167a3db77b3a 100644 (file)
@@ -106,89 +106,4 @@ public class ArrayUtil
        // We're done - array will now have everything moved as required
     }
 
-    /**
-     * Copies the specified array, truncating or padding with zeros (if
-     * necessary) so the copy has the specified length. This method is temporary
-     * replace for Arrays.copyOf() until we start to require JDK 1.6.
-     * 
-     * @param source
-     *            the array to be copied
-     * @param newLength
-     *            the length of the copy to be returned
-     * @return a copy of the original array, truncated or padded with zeros to
-     *         obtain the specified length
-     * @throws NegativeArraySizeException
-     *             if <tt>newLength</tt> is negative
-     * @throws NullPointerException
-     *             if <tt>original</tt> is null
-     */
-    public static byte[] copyOf( byte[] source, int newLength )
-    {
-        byte[] result = new byte[newLength];
-        System.arraycopy( source, 0, result, 0,
-                Math.min( source.length, newLength ) );
-        return result;
-    }
-
-    /**
-     * Copies the specified array into specified result array, truncating or
-     * padding with zeros (if necessary) so the copy has the specified length.
-     * This method is temporary replace for Arrays.copyOf() until we start to
-     * require JDK 1.6.
-     * 
-     * @param source
-     *            the array to be copied
-     * @param result
-     *            the array to be filled and returned
-     * @throws NegativeArraySizeException
-     *             if <tt>newLength</tt> is negative
-     * @throws NullPointerException
-     *             if <tt>original</tt> is null
-     */
-    public static <T> T[] copyOf( T[] source, T[] result )
-    {
-        System.arraycopy( source, 0, result, 0,
-                Math.min( source.length, result.length ) );
-        return result;
-    }
-
-    /**
-     * Copies the specified range of the specified array into a new array.
-     * The initial index of the range (<tt>from</tt>) must lie between zero
-     * and <tt>original.length</tt>, inclusive.  The value at
-     * <tt>original[from]</tt> is placed into the initial element of the copy
-     * (unless <tt>from == original.length</tt> or <tt>from == to</tt>).
-     * Values from subsequent elements in the original array are placed into
-     * subsequent elements in the copy.  The final index of the range
-     * (<tt>to</tt>), which must be greater than or equal to <tt>from</tt>,
-     * may be greater than <tt>original.length</tt>, in which case
-     * <tt>(byte)0</tt> is placed in all elements of the copy whose index is
-     * greater than or equal to <tt>original.length - from</tt>.  The length
-     * of the returned array will be <tt>to - from</tt>.
-     *
-     * This method is temporary
-     * replace for Arrays.copyOfRange() until we start to require JDK 1.6.
-     *
-     * @param original the array from which a range is to be copied
-     * @param from the initial index of the range to be copied, inclusive
-     * @param to the final index of the range to be copied, exclusive.
-     *     (This index may lie outside the array.)
-     * @return a new array containing the specified range from the original array,
-     *     truncated or padded with zeros to obtain the required length
-     * @throws ArrayIndexOutOfBoundsException if <tt>from &lt; 0</tt>
-     *     or <tt>from &gt; original.length()</tt>
-     * @throws IllegalArgumentException if <tt>from &gt; to</tt>
-     * @throws NullPointerException if <tt>original</tt> is null
-     * @since 1.6
-     */
-    public static byte[] copyOfRange(byte[] original, int from, int to) {
-        int newLength = to - from;
-        if (newLength < 0)
-            throw new IllegalArgumentException(from + " > " + to);
-        byte[] copy = new byte[newLength];
-        System.arraycopy(original, from, copy, 0,
-                Math.min(original.length - from, newLength));
-        return copy;
-    }
-
 }
index f2da6077620c4925a6fd9e1d3d999821adfe9e41..3e97cee0b31be0b9402681b1a9a375f7fc2d5621 100644 (file)
@@ -19,7 +19,6 @@ package org.apache.poi.util;
 
 import javax.xml.XMLConstants;
 import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
 
 /**
  * Helper methods for working with javax.xml classes.
@@ -27,22 +26,31 @@ import javax.xml.parsers.ParserConfigurationException;
  */
 public final class XMLHelper
 {
+    private static POILogger logger = POILogFactory.getLogger(XMLHelper.class);
+    
     /**
      * Creates a new DocumentBuilderFactory, with sensible defaults
      */
     public static DocumentBuilderFactory getDocumentBuilderFactory() {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setExpandEntityReferences(false);
+        trySetSAXFeature(factory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
+        trySetSAXFeature(factory, "http://xml.org/sax/features/external-general-entities", false);
+        trySetSAXFeature(factory, "http://xml.org/sax/features/external-parameter-entities", false);
+        trySetSAXFeature(factory, "http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+        trySetSAXFeature(factory, "http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
+        return factory;
+    }
+    
+    private static void trySetSAXFeature(DocumentBuilderFactory documentBuilderFactory, String feature, boolean enabled) {
         try {
-            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-            factory.setXIncludeAware(false);
-            factory.setExpandEntityReferences(false);
-            factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
-            factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
-            factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
-            factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
-            factory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
-            return factory;
-        } catch (ParserConfigurationException e) {
-            throw new RuntimeException("Broken XML Setup", e);
+            documentBuilderFactory.setFeature(feature, enabled);
+        } catch (Exception e) {
+            logger.log(POILogger.WARN, "SAX Feature unsupported", feature, e);
+        } catch (AbstractMethodError ame) {
+            logger.log(POILogger.WARN, "Cannot set SAX feature because outdated XML parser in classpath", feature, ame);
         }
     }
+    
+
 }
index d7a17191238aba0a83ed5722bc8c00abd0dadd84..27c1c49d11e2584070726c458705fe4fe911814a 100644 (file)
@@ -285,6 +285,117 @@ public class POIXMLProperties {
                public org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.CTProperties getUnderlyingProperties() {
                        return props.getProperties();
                }
+               
+        public String getTemplate() {
+            if (props.getProperties().isSetTemplate()) {
+                return props.getProperties().getTemplate();
+            }
+            return null;
+        }
+        public String getManager() {
+            if (props.getProperties().isSetManager()) {
+                return props.getProperties().getManager();
+            }
+            return null;
+        }
+        public String getCompany() {
+            if (props.getProperties().isSetCompany()) {
+                return props.getProperties().getCompany();
+            }
+            return null;
+        }
+        public String getPresentationFormat() {
+            if (props.getProperties().isSetPresentationFormat()) {
+                return props.getProperties().getPresentationFormat();
+            }
+            return null;
+        }
+        public String getApplication() {
+            if (props.getProperties().isSetApplication()) {
+                return props.getProperties().getApplication();
+            }
+            return null;
+        }
+        public String getAppVersion() {
+            if (props.getProperties().isSetAppVersion()) {
+                return props.getProperties().getAppVersion();
+            }
+            return null;
+        }
+
+        public int getPages() {
+            if (props.getProperties().isSetPages()) {
+                return props.getProperties().getPages();
+            }
+            return -1;
+        }
+        public int getWords() {
+            if (props.getProperties().isSetWords()) {
+                return props.getProperties().getWords();
+            }
+            return -1;
+        }
+        public int getCharacters() {
+            if (props.getProperties().isSetCharacters()) {
+                return props.getProperties().getCharacters();
+            }
+            return -1;
+        }
+        public int getCharactersWithSpaces() {
+            if (props.getProperties().isSetCharactersWithSpaces()) {
+                return props.getProperties().getCharactersWithSpaces();
+            }
+            return -1;
+        }
+        public int getLines() {
+            if (props.getProperties().isSetLines()) {
+                return props.getProperties().getLines();
+            }
+            return -1;
+        }
+        public int getParagraphs() {
+            if (props.getProperties().isSetParagraphs()) {
+                return props.getProperties().getParagraphs();
+            }
+            return -1;
+        }
+        public int getSlides() {
+            if (props.getProperties().isSetSlides()) {
+                return props.getProperties().getSlides();
+            }
+            return -1;
+        }
+        public int getNotes() {
+            if (props.getProperties().isSetNotes()) {
+                return props.getProperties().getNotes();
+            }
+            return -1;
+        }
+        public int getTotalTime()  {
+            if (props.getProperties().isSetTotalTime()) {
+                return props.getProperties().getTotalTime();
+            }
+            return -1;
+        }
+        public int getHiddenSlides()  {
+            if (props.getProperties().isSetHiddenSlides()) {
+                return props.getProperties().getHiddenSlides();
+            }
+            return -1;
+        }
+        public int getMMClips() {
+            if (props.getProperties().isSetMMClips()) {
+                return props.getProperties().getMMClips();
+            }
+            return -1;
+        }
+
+        public String getHyperlinkBase() {
+            if (props.getProperties().isSetHyperlinkBase()) {
+                return props.getProperties().getHyperlinkBase();
+            }
+            return null;
+        }
        }
 
        /**
@@ -371,25 +482,46 @@ public class POIXMLProperties {
                 *
                 * @return next property id starting with 2
                 */
-               protected int nextPid(){
+               @SuppressWarnings("deprecation")
+        protected int nextPid(){
                        int propid = 1;
-                       for(CTProperty p : props.getProperties().getPropertyList()){
+                       for(CTProperty p : props.getProperties().getPropertyArray()){
                                if(p.getPid() > propid) propid = p.getPid();
                        }
                        return propid + 1;
                }
 
-               /**
-                * Check if a property with this name already exists in the collection of custom properties
-                *
-                * @param name the name to check
-                * @return whether a property with the given name exists in the custom properties
-                */
-               public boolean contains(String name){
-                       for(CTProperty p : props.getProperties().getPropertyList()){
-                               if(p.getName().equals(name)) return true;
-                       }
-                       return false;
-               }
-       }
+       /**
+         * Check if a property with this name already exists in the collection of custom properties
+         *
+         * @param name the name to check
+         * @return whether a property with the given name exists in the custom properties
+         */
+        @SuppressWarnings("deprecation")
+        public boolean contains(String name) {
+            for(CTProperty p : props.getProperties().getPropertyArray()){
+                if(p.getName().equals(name)) return true;
+            }
+            return false;
+        }
+        
+        /**
+         * Retrieve the custom property with this name, or null if none exists.
+         *
+         * You will need to test the various isSetX methods to work out
+         *  what the type of the property is, before fetching the 
+         *  appropriate value for it.
+         *
+         * @param name the name of the property to fetch
+         */
+        @SuppressWarnings("deprecation")
+        public CTProperty getProperty(String name) {
+            for(CTProperty p : props.getProperties().getPropertyArray()){
+                if(p.getName().equals(name)) {
+                    return p;
+                }
+            }
+            return null;
+        }
+    }
 }
index 51a4399f3fea7878c90461ba1c3a82567964e5df..ce576439f27c1fe5bb36091acbd543028adaeaf6 100644 (file)
@@ -19,7 +19,6 @@ package org.apache.poi;
 
 import java.math.BigDecimal;
 import java.util.Date;
-import java.util.List;
 
 import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
 import org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty;
@@ -126,13 +125,13 @@ public class POIXMLPropertiesTextExtractor extends POIXMLTextExtractor {
     * Returns the custom document properties, if
     *  there are any
     */
+   @SuppressWarnings("deprecation")
    public String getCustomPropertiesText() {
-      StringBuffer text = new StringBuffer();
+      StringBuilder text = new StringBuilder();
       org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperties
       props = getDocument().getProperties().getCustomProperties().getUnderlyingProperties();
 
-      List<CTProperty> properties = props.getPropertyList();
-      for(CTProperty property : properties) {
+       for(CTProperty property : props.getPropertyArray()) {
          String val = "(not implemented!)";
 
          if (property.isSetLpwstr()) {
index 2732c825eacad5ce3052834f5a54795cacdcb480..08d82fbaab7fea9ae4a2314f5501490ac3090ace 100644 (file)
@@ -24,9 +24,9 @@ import java.util.TreeMap;
 
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
+import org.apache.poi.util.DocumentHelper;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
-import org.apache.poi.util.SAXHelper;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -311,7 +311,7 @@ public final class PackageRelationshipCollection implements
             throws InvalidFormatException {
         try {
             logger.log(POILogger.DEBUG, "Parsing relationship: " + relPart.getPartName());
-            Document xmlRelationshipsDoc = SAXHelper.readSAXDocument(relPart.getInputStream());
+            Document xmlRelationshipsDoc = DocumentHelper.readDocument(relPart.getInputStream());
 
             // Browse default types
             Element root = xmlRelationshipsDoc.getDocumentElement();
index 8aa4b7d1dd6d23606510de12c4f9e3d388bddd9c..59801d3aeeb2cde37634c0118c77bd7d50367360 100644 (file)
@@ -33,7 +33,6 @@ 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.util.DocumentHelper;
-import org.apache.poi.util.SAXHelper;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
@@ -370,7 +369,7 @@ public abstract class ContentTypeManager {
        private void parseContentTypesFile(InputStream in)
                        throws InvalidFormatException {
                try {
-                       Document xmlContentTypetDoc = SAXHelper.readSAXDocument(in);
+                       Document xmlContentTypetDoc = DocumentHelper.readDocument(in);
 
                        // Default content types
                        NodeList defaultTypes = xmlContentTypetDoc.getDocumentElement().getElementsByTagName(DEFAULT_TAG_NAME);
index b4e3e837233354591172d6387095a24da3dda582..eb94f680e6bae58b25dd98ecbece0839259cc5a7 100644 (file)
@@ -31,7 +31,7 @@ import org.apache.poi.openxml4j.opc.ZipPackage;
 import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
 import org.apache.poi.openxml4j.opc.internal.PartUnmarshaller;
 import org.apache.poi.openxml4j.opc.internal.ZipHelper;
-import org.apache.poi.util.SAXHelper;
+import org.apache.poi.util.DocumentHelper;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -105,7 +105,7 @@ public final class PackagePropertiesUnmarshaller implements PartUnmarshaller {
 
                Document xmlDoc;
                try {
-                       xmlDoc = SAXHelper.readSAXDocument(in);
+                       xmlDoc = DocumentHelper.readDocument(in);
 
                        /* Check OPC compliance */
 
index e7eb140e1a9767043800d969b5279a585a7eb308..d5dc363e73dcd2f28ad8337e9426f297939f0447 100644 (file)
@@ -57,9 +57,9 @@ import org.apache.poi.poifs.crypt.HashAlgorithm;
 import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService;\r
 import org.apache.poi.poifs.crypt.dsig.services.XmlSignatureService;\r
 import org.apache.poi.poifs.crypt.dsig.spi.DigestInfo;\r
+import org.apache.poi.util.DocumentHelper;\r
 import org.apache.poi.util.POILogFactory;\r
 import org.apache.poi.util.POILogger;\r
-import org.apache.poi.util.SAXHelper;\r
 import org.apache.xml.security.Init;\r
 import org.apache.xmlbeans.XmlCursor;\r
 import org.apache.xmlbeans.XmlException;\r
@@ -127,7 +127,7 @@ public class SignatureInfo {
     throws NoSuchAlgorithmException, IOException, MarshalException, ParserConfigurationException, XmlException {\r
         XmlSignatureService signatureService = createSignatureService(hashAlgo, pkg);\r
 \r
-        Document document = SAXHelper.getDocumentBuilder().newDocument();\r
+        Document document = DocumentHelper.createDocument();\r
         \r
         // operate\r
         List<X509Certificate> x509Chain = Collections.singletonList(x509);\r
@@ -181,7 +181,7 @@ public class SignatureInfo {
             KeyInfoKeySelector keySelector = new KeyInfoKeySelector();\r
 \r
             try {\r
-                Document doc = SAXHelper.readSAXDocument(signaturePart.getInputStream());\r
+                Document doc = DocumentHelper.readDocument(signaturePart.getInputStream());\r
                 // dummy call to createSignatureService to tweak document afterwards\r
                 createSignatureService(HashAlgorithm.sha1, pkg).registerIds(doc);\r
                 \r
index 22bdd4e0fd2bd2f13639525f7823aeea6c9debf1..0c18b5d0091a347c2e67dd8db340beb1d634e959 100644 (file)
 
 package org.apache.poi.util;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+
 import javax.xml.XMLConstants;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
@@ -25,20 +29,81 @@ import javax.xml.stream.events.Namespace;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
 
-public class DocumentHelper {
+public final class DocumentHelper {
+    private static POILogger logger = POILogFactory.getLogger(DocumentHelper.class);
+    
+    private DocumentHelper() {}
 
-    private static final DocumentBuilder newDocumentBuilder;
-    static {
+    /**
+     * Creates a new document builder, with sensible defaults
+     */
+    public static synchronized DocumentBuilder newDocumentBuilder() {
         try {
-            newDocumentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+            documentBuilder.setEntityResolver(SAXHelper.IGNORING_ENTITY_RESOLVER);
+            return documentBuilder;
         } catch (ParserConfigurationException e) {
             throw new IllegalStateException("cannot create a DocumentBuilder", e);
         }
     }
 
+    private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+    static {
+        documentBuilderFactory.setNamespaceAware(true);
+        documentBuilderFactory.setValidating(false);
+        trySetSAXFeature(documentBuilderFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
+        trySetXercesSecurityManager(documentBuilderFactory);
+    }
+
+    private static void trySetSAXFeature(DocumentBuilderFactory documentBuilderFactory, String feature, boolean enabled) {
+        try {
+            documentBuilderFactory.setFeature(feature, enabled);
+        } catch (Exception e) {
+            logger.log(POILogger.WARN, "SAX Feature unsupported", feature, e);
+        } catch (AbstractMethodError ame) {
+            logger.log(POILogger.WARN, "Cannot set SAX feature because outdated XML parser in classpath", feature, ame);
+        }
+    }
+    
+    private static void trySetXercesSecurityManager(DocumentBuilderFactory documentBuilderFactory) {
+        // Try built-in JVM one first, standalone if not
+        for (String securityManagerClassName : new String[] {
+                "com.sun.org.apache.xerces.internal.util.SecurityManager",
+                "org.apache.xerces.util.SecurityManager"
+        }) {
+            try {
+                Object mgr = Class.forName(securityManagerClassName).newInstance();
+                Method setLimit = mgr.getClass().getMethod("setEntityExpansionLimit", Integer.TYPE);
+                setLimit.invoke(mgr, 4096);
+                documentBuilderFactory.setAttribute("http://apache.org/xml/properties/security-manager", mgr);
+                // Stop once one can be setup without error
+                return;
+            } catch (Exception e) {
+                logger.log(POILogger.WARN, "SAX Security Manager could not be setup", e);
+            }
+        }
+    }
+
+    /**
+     * Parses the given stream via the default (sensible)
+     * DocumentBuilder
+     * @param inp Stream to read the XML data from
+     * @return the parsed Document 
+     */
+    public static Document readDocument(InputStream inp) throws IOException, SAXException {
+        return newDocumentBuilder().parse(inp);
+    }
+
+    // must only be used to create empty documents, do not use it for parsing!
+    private static final DocumentBuilder documentBuilderSingleton = newDocumentBuilder();
+
+    /**
+     * Creates a new DOM Document
+     */
     public static synchronized Document createDocument() {
-        return newDocumentBuilder.newDocument();
+        return documentBuilderSingleton.newDocument();
     }
 
     /**
index 81049a9a2e7028d29c9d189cefd38ea8cfe72cf4..d4d016cb3b05b01b80f788f7f7989dccd37e1032 100644 (file)
 package org.apache.poi.util;
 
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.StringReader;
 import java.lang.reflect.Method;
 
 import javax.xml.XMLConstants;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
 
-import org.w3c.dom.Document;
 import org.xml.sax.EntityResolver;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
 
 
 /**
@@ -39,43 +37,45 @@ import org.xml.sax.SAXException;
 public final class SAXHelper {
     private static POILogger logger = POILogFactory.getLogger(SAXHelper.class);
 
-    private static final EntityResolver IGNORING_ENTITY_RESOLVER = new EntityResolver() {
+    private SAXHelper() {}
+
+    /**
+     * Creates a new SAX XMLReader, with sensible defaults
+     */
+    public static synchronized XMLReader newXMLReader() throws SAXException, ParserConfigurationException {
+        XMLReader xmlReader = saxFactory.newSAXParser().getXMLReader();
+        xmlReader.setEntityResolver(IGNORING_ENTITY_RESOLVER);
+        trySetSAXFeature(xmlReader, XMLConstants.FEATURE_SECURE_PROCESSING, true);
+        trySetXercesSecurityManager(xmlReader);
+        return xmlReader;
+    }
+    
+    static final EntityResolver IGNORING_ENTITY_RESOLVER = new EntityResolver() {
         @Override
         public InputSource resolveEntity(String publicId, String systemId)
                 throws SAXException, IOException {
             return new InputSource(new StringReader(""));
         }
     };
-
-    private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+    
+    private static final SAXParserFactory saxFactory;
     static {
-        documentBuilderFactory.setNamespaceAware(true);
-        documentBuilderFactory.setValidating(false);
-        trySetSAXFeature(documentBuilderFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
-        trySetXercesSecurityManager(documentBuilderFactory);
-    }
-
-    /**
-     * Creates a new document builder, with sensible defaults
-     */
-    public static synchronized DocumentBuilder getDocumentBuilder() {
-        try {
-            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
-            documentBuilder.setEntityResolver(IGNORING_ENTITY_RESOLVER);
-            return documentBuilder;
-        } catch (ParserConfigurationException e) {
-            throw new IllegalStateException("cannot create a DocumentBuilder", e);
-        }
+        saxFactory = SAXParserFactory.newInstance();
+        saxFactory.setValidating(false);
+        saxFactory.setNamespaceAware(true);
     }
-
-    private static void trySetSAXFeature(DocumentBuilderFactory documentBuilderFactory, String feature, boolean enabled) {
+            
+    private static void trySetSAXFeature(XMLReader xmlReader, String feature, boolean enabled) {
         try {
-            documentBuilderFactory.setFeature(feature, enabled);
+            xmlReader.setFeature(feature, enabled);
         } catch (Exception e) {
-            logger.log(POILogger.INFO, "SAX Feature unsupported", feature, e);
+            logger.log(POILogger.WARN, "SAX Feature unsupported", feature, e);
+        } catch (AbstractMethodError ame) {
+            logger.log(POILogger.WARN, "Cannot set SAX feature because outdated XML parser in classpath", feature, ame);
         }
     }
-    private static void trySetXercesSecurityManager(DocumentBuilderFactory documentBuilderFactory) {
+    
+    private static void trySetXercesSecurityManager(XMLReader xmlReader) {
         // Try built-in JVM one first, standalone if not
         for (String securityManagerClassName : new String[] {
                 "com.sun.org.apache.xerces.internal.util.SecurityManager",
@@ -85,22 +85,12 @@ public final class SAXHelper {
                 Object mgr = Class.forName(securityManagerClassName).newInstance();
                 Method setLimit = mgr.getClass().getMethod("setEntityExpansionLimit", Integer.TYPE);
                 setLimit.invoke(mgr, 4096);
-                documentBuilderFactory.setAttribute("http://apache.org/xml/properties/security-manager", mgr);
+                xmlReader.setProperty("http://apache.org/xml/properties/security-manager", mgr);
                 // Stop once one can be setup without error
                 return;
             } catch (Exception e) {
-                logger.log(POILogger.INFO, "SAX Security Manager could not be setup", e);
+                logger.log(POILogger.WARN, "SAX Security Manager could not be setup", e);
             }
         }
     }
-
-    /**
-     * Parses the given stream via the default (sensible)
-     * SAX Reader
-     * @param inp Stream to read the XML data from
-     * @return the SAX processed Document 
-     */
-    public static Document readSAXDocument(InputStream inp) throws IOException, SAXException {
-        return getDocumentBuilder().parse(inp);
-    }
 }
index b6523bedde73034b157199c090a56ef111ee0ea6..7f0f1b773cac7a3f9c534a859a6573b135c4d681 100644 (file)
@@ -31,7 +31,20 @@ import org.apache.poi.util.Internal;
 import org.apache.poi.xslf.usermodel.XMLSlideShow;
 import org.apache.poi.xslf.usermodel.XSLFRelation;
 import org.apache.xmlbeans.XmlException;
-import org.openxmlformats.schemas.presentationml.x2006.main.*;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTCommentList;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesSlide;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTPresentation;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdList;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMaster;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdList;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdListEntry;
+import org.openxmlformats.schemas.presentationml.x2006.main.CmLstDocument;
+import org.openxmlformats.schemas.presentationml.x2006.main.NotesDocument;
+import org.openxmlformats.schemas.presentationml.x2006.main.PresentationDocument;
+import org.openxmlformats.schemas.presentationml.x2006.main.SldDocument;
+import org.openxmlformats.schemas.presentationml.x2006.main.SldMasterDocument;
 
 /**
  * Experimental class to do low level processing of pptx files.
@@ -53,6 +66,7 @@ public class XSLFSlideShow extends POIXMLDocument {
      */
     private List<PackagePart> embedds;
 
+    @SuppressWarnings("deprecation")
        public XSLFSlideShow(OPCPackage container) throws OpenXML4JException, IOException, XmlException {
                super(container);
                
@@ -64,7 +78,7 @@ public class XSLFSlideShow extends POIXMLDocument {
                        PresentationDocument.Factory.parse(getCorePart().getInputStream());
                
       embedds = new LinkedList<PackagePart>();
-      for (CTSlideIdListEntry ctSlide : getSlideReferences().getSldIdList()) {
+      for (CTSlideIdListEntry ctSlide : getSlideReferences().getSldIdArray()) {
              PackagePart corePart = getCorePart();
                  PackagePart slidePart = corePart.getRelatedPart(
                        corePart.getRelationship(ctSlide.getId2()));
index 4c3693d3e582f4b690e079cd8916ec9e68410377..67f1067b71f2cc8472625861127926204903e4fd 100644 (file)
@@ -118,6 +118,7 @@ public class XSLFPowerPointExtractor extends POIXMLTextExtractor {
     * @param notesText Should we retrieve text from notes?
     * @param masterText Should we retrieve text from master slides?
     */
+   @SuppressWarnings("deprecation")
    public String getText(boolean slideText, boolean notesText, boolean masterText) {
       StringBuffer text = new StringBuffer();
 
@@ -150,7 +151,7 @@ public class XSLFPowerPointExtractor extends POIXMLTextExtractor {
 
                // If the slide has comments, do those too
                if (comments != null) {
-                  for (CTComment comment : comments.getCTCommentsList().getCmList()) {
+                  for (CTComment comment : comments.getCTCommentsList().getCmArray()) {
                      // Do the author if we can
                      if (commentAuthors != null) {
                         CTCommentAuthor author = commentAuthors.getAuthorById(comment.getAuthorId());
index 5a81c307a5f269caab81a06357264a0a5c753960..4e30ac90d9e438f2b31b06611a4617f017202701 100644 (file)
 
 package org.apache.poi.xslf.model.geom;
 
-import org.openxmlformats.schemas.drawingml.x2006.main.*;
-
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
+import org.openxmlformats.schemas.drawingml.x2006.main.CTCustomGeometry2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuide;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuideList;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomRect;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPath2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPath2DList;
+
 /**
  * Definition of a custom geometric shape
  *
@@ -36,19 +41,20 @@ public class CustomGeometry implements Iterable<Path>{
     List<Path> paths = new ArrayList<Path>();
     Path textBounds;
 
+    @SuppressWarnings("deprecation")
     public CustomGeometry(CTCustomGeometry2D geom) {
         CTGeomGuideList avLst = geom.getAvLst();
-        if(avLst != null) for(CTGeomGuide gd : avLst.getGdList()){
+        if(avLst != null) for(CTGeomGuide gd : avLst.getGdArray()){
             adjusts.add(new AdjustValue(gd));
         }
 
         CTGeomGuideList gdLst = geom.getGdLst();
-        if(gdLst != null) for(CTGeomGuide gd : gdLst.getGdList()){
+        if(gdLst != null) for(CTGeomGuide gd : gdLst.getGdArray()){
             guides.add(new Guide(gd));
         }
 
         CTPath2DList pathLst = geom.getPathLst();
-        if(pathLst != null) for(CTPath2D spPath : pathLst.getPathList()){
+        if(pathLst != null) for(CTPath2D spPath : pathLst.getPathArray()){
             paths.add(new Path(spPath));
         }
 
index c6d7da9f2b20e086d674172f73f1c166c0aa8ef4..2cc7724c79bcd1a624b4356523da76375d623a9b 100644 (file)
@@ -20,8 +20,6 @@ package org.apache.poi.xslf.usermodel;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTable;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow;
 
-import java.util.List;
-
 public class DrawingTable {
     private final CTTable table;
 
@@ -29,12 +27,13 @@ public class DrawingTable {
         this.table = table;
     }
 
+    @SuppressWarnings("deprecation")
     public DrawingTableRow[] getRows() {
-        List<CTTableRow> ctTableRows = table.getTrList();
-        DrawingTableRow[] o = new DrawingTableRow[ctTableRows.size()];
+        CTTableRow[] ctTableRows = table.getTrArray();
+        DrawingTableRow[] o = new DrawingTableRow[ctTableRows.length];
 
         for (int i=0; i<o.length; i++) {
-            o[i] = new DrawingTableRow(ctTableRows.get(i));
+            o[i] = new DrawingTableRow(ctTableRows[i]);
         }
 
         return o;
index 27b79ea33e1db67bb4aeacf03cb45dcef2aa0d76..0858d2be8ef8d1df71ff158b74403945eb6e9ad1 100644 (file)
@@ -20,8 +20,6 @@ package org.apache.poi.xslf.usermodel;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow;
 
-import java.util.List;
-
 public class DrawingTableRow {
     private final CTTableRow row;
 
@@ -29,12 +27,13 @@ public class DrawingTableRow {
         this.row = row;
     }
 
+    @SuppressWarnings("deprecation")
     public DrawingTableCell[] getCells() {
-        List<CTTableCell> ctTableCells = row.getTcList();
-        DrawingTableCell[] o = new DrawingTableCell[ctTableCells.size()];
+        CTTableCell[] ctTableCells = row.getTcArray();
+        DrawingTableCell[] o = new DrawingTableCell[ctTableCells.length];
 
         for (int i=0; i<o.length; i++) {
-            o[i] = new DrawingTableCell(ctTableCells.get(i));
+            o[i] = new DrawingTableCell(ctTableCells[i]);
         }
 
         return o;
index 626dbff215310f9aeb7d0f6123ba34582fefe6ed..88171f38eb54de576d89d9669ac2f53789c87334 100644 (file)
@@ -20,8 +20,6 @@ package org.apache.poi.xslf.usermodel;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
 
-import java.util.List;
-
 public class DrawingTextBody {
     private final CTTextBody textBody;
 
@@ -29,12 +27,13 @@ public class DrawingTextBody {
        this.textBody = textBody;
     }
 
+    @SuppressWarnings("deprecation")
     public DrawingParagraph[] getParagraphs() {
-        List<CTTextParagraph> paragraphs = textBody.getPList();
-        DrawingParagraph[] o = new DrawingParagraph[paragraphs.size()];
+        CTTextParagraph[] paragraphs = textBody.getPArray();
+        DrawingParagraph[] o = new DrawingParagraph[paragraphs.length];
 
         for (int i=0; i<o.length; i++) {
-            o[i] = new DrawingParagraph(paragraphs.get(i));
+            o[i] = new DrawingParagraph(paragraphs[i]);
         }
 
         return o;
index 462ce3ee29c21808d2e0be09b29e804ffed42147..053ccd491dd6ca093bfa3609a78aa047941b5737 100644 (file)
 \r
 package org.apache.poi.xslf.usermodel;\r
 \r
+import java.awt.AlphaComposite;\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.GradientPaint;\r
+import java.awt.Graphics2D;\r
+import java.awt.Paint;\r
+import java.awt.Shape;\r
+import java.awt.Stroke;\r
+import java.awt.TexturePaint;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Point2D;\r
+import java.awt.geom.Rectangle2D;\r
+import java.awt.image.BufferedImage;\r
+import java.lang.reflect.Constructor;\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.Collection;\r
+import java.util.Comparator;\r
+\r
 import org.apache.poi.openxml4j.opc.PackagePart;\r
 import org.apache.poi.openxml4j.opc.PackageRelationship;\r
 import org.apache.poi.util.Internal;\r
@@ -47,25 +66,6 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillPropertie
 import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STPathShadeType;\r
 \r
-import java.awt.AlphaComposite;\r
-import java.awt.BasicStroke;\r
-import java.awt.Color;\r
-import java.awt.GradientPaint;\r
-import java.awt.Graphics2D;\r
-import java.awt.Paint;\r
-import java.awt.Shape;\r
-import java.awt.Stroke;\r
-import java.awt.TexturePaint;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.Point2D;\r
-import java.awt.geom.Rectangle2D;\r
-import java.awt.image.BufferedImage;\r
-import java.lang.reflect.Constructor;\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.Collection;\r
-import java.util.Comparator;\r
-\r
 /**\r
  * Encapsulates logic to translate DrawingML objects to Java2D\r
  */\r
@@ -548,6 +548,7 @@ class RenderableShape {
         }\r
     }\r
 \r
+    @SuppressWarnings("deprecation")\r
     private Collection<Outline> computeOutlines(Graphics2D graphics) {\r
 \r
         Collection<Outline> lst = new ArrayList<Outline>();\r
@@ -576,7 +577,7 @@ class RenderableShape {
                 public Guide getAdjustValue(String name) {\r
                     CTPresetGeometry2D prst = _shape.getSpPr().getPrstGeom();\r
                     if (prst.isSetAvLst()) {\r
-                        for (CTGeomGuide g : prst.getAvLst().getGdList()) {\r
+                        for (CTGeomGuide g : prst.getAvLst().getGdArray()) {\r
                             if (g.getName().equals(name)) {\r
                                 return new Guide(g);\r
                             }\r
index de31fb2fd633ff76a53ffe1c9ef802d7e8cb8914..69dc02952357165a25bd9f21f27d05f79649cc0e 100644 (file)
@@ -115,6 +115,7 @@ public class XMLSlideShow  extends POIXMLDocument {
     }
 
     @Override
+    @SuppressWarnings("deprecation")
     protected void onDocumentRead() throws IOException {
         try {
             PresentationDocument doc =
@@ -140,8 +141,7 @@ public class XMLSlideShow  extends POIXMLDocument {
 
             _slides = new ArrayList<XSLFSlide>();
             if (_presentation.isSetSldIdLst()) {
-                List<CTSlideIdListEntry> slideIds = _presentation.getSldIdLst().getSldIdList();
-                for (CTSlideIdListEntry slId : slideIds) {
+                for (CTSlideIdListEntry slId : _presentation.getSldIdLst().getSldIdArray()) {
                     XSLFSlide sh = shIdMap.get(slId.getId2());
                     if (sh == null) {
                         _logger.log(POILogger.WARN, "Slide with r:id " + slId.getId() + " was defined, but didn't exist in package, skipping");
@@ -201,13 +201,14 @@ public class XMLSlideShow  extends POIXMLDocument {
      * @param layout
      * @return created slide
      */
+    @SuppressWarnings("deprecation")
     public XSLFSlide createSlide(XSLFSlideLayout layout) {
         int slideNumber = 256, cnt = 1;
         CTSlideIdList slideList;
         if (!_presentation.isSetSldIdLst()) slideList = _presentation.addNewSldIdLst();
         else {
             slideList = _presentation.getSldIdLst();
-            for(CTSlideIdListEntry slideId : slideList.getSldIdList()){
+            for(CTSlideIdListEntry slideId : slideList.getSldIdArray()){
                 slideNumber = (int)Math.max(slideId.getId() + 1, slideNumber);
                 cnt++;
             }
@@ -283,16 +284,16 @@ public class XMLSlideShow  extends POIXMLDocument {
         _slides.add(newIndex, _slides.remove(oldIndex));
 
         // fix ordering in the low-level xml
-        List<CTSlideIdListEntry> slideIds = _presentation.getSldIdLst().getSldIdList();
-        CTSlideIdListEntry oldEntry = slideIds.get(oldIndex);
-        slideIds.add(newIndex, oldEntry);
-        slideIds.remove(oldEntry);
+        CTSlideIdList sldIdLst = _presentation.getSldIdLst();
+        CTSlideIdListEntry oldEntry = sldIdLst.getSldIdArray(oldIndex);
+        sldIdLst.insertNewSldId(newIndex).set(oldEntry);
+        sldIdLst.removeSldId(oldIndex);
     }
 
     public XSLFSlide removeSlide(int index){
         XSLFSlide slide = _slides.remove(index);
         removeRelation(slide);
-         _presentation.getSldIdLst().getSldIdList().remove(index);
+         _presentation.getSldIdLst().removeSldId(index);
         return slide;
     }
     
index 23ddb4d534ebad53518a41442b8162263f87a48c..e52b9ec6511f2e55af7c110fcf0a9fe48c34e4c4 100644 (file)
@@ -17,6 +17,8 @@
 
 package org.apache.poi.xslf.usermodel;
 
+import java.io.IOException;
+
 import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
@@ -26,8 +28,6 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTCommentAuthor;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTCommentAuthorList;
 import org.openxmlformats.schemas.presentationml.x2006.main.CmAuthorLstDocument;
 
-import java.io.IOException;
-
 @Beta
 public class XSLFCommentAuthors extends POIXMLDocumentPart {
     private final CTCommentAuthorList _authors;
@@ -61,9 +61,10 @@ public class XSLFCommentAuthors extends POIXMLDocumentPart {
        return _authors;
     }
     
+    @SuppressWarnings("deprecation")
     public CTCommentAuthor getAuthorById(long id) {
        // TODO Have a map
-       for (CTCommentAuthor author : _authors.getCmAuthorList()) {
+       for (CTCommentAuthor author : _authors.getCmAuthorArray()) {
           if (author.getId() == id) {
              return author;
           }
index 9eed7ec7e043ce2df1d90913b4698145160f6a69..df3ca7ad05d082947109a7bae651df3396718b4a 100644 (file)
@@ -66,6 +66,6 @@ public class XSLFComments extends POIXMLDocumentPart {
     }
     
     public CTComment getCommentAt(int pos) {
-       return _comments.getCmList().get(pos);
+       return _comments.getCmArray(pos);
     }
 }
index b099b64571e114d1735e0f34911f57834fb99352..0033665aa5f7ee794c825f09a73f193962cc3085 100644 (file)
 
 package org.apache.poi.xslf.usermodel;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
 import org.apache.poi.POIXMLException;
 import org.apache.poi.util.Beta;
 import org.apache.xmlbeans.XmlCursor;
@@ -32,10 +36,6 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFra
 import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 @Beta
 public class XSLFCommonSlideData {
     private final CTCommonSlideData data;
@@ -44,6 +44,7 @@ public class XSLFCommonSlideData {
         this.data = data;
     }
     
+    @SuppressWarnings("deprecation")
     public List<DrawingTextBody> getDrawingText() {
         CTGroupShape gs = data.getSpTree();
 
@@ -51,11 +52,11 @@ public class XSLFCommonSlideData {
 
         processShape(gs, out);
 
-        for (CTGroupShape shape : gs.getGrpSpList()) {
+        for (CTGroupShape shape : gs.getGrpSpArray()) {
             processShape(shape, out);
         }
 
-        for (CTGraphicalObjectFrame frame: gs.getGraphicFrameList()) {
+        for (CTGraphicalObjectFrame frame: gs.getGraphicFrameArray()) {
             CTGraphicalObjectData data = frame.getGraphic().getGraphicData();
             XmlCursor c = data.newCursor();
             c.selectPath("declare namespace pic='"+CTTable.type.getName().getNamespaceURI()+"' .//pic:tbl");
@@ -97,9 +98,9 @@ public class XSLFCommonSlideData {
        return paragraphs;
     }
 
+    @SuppressWarnings("deprecation")
     private void processShape(CTGroupShape gs, List<DrawingTextBody> out) {
-        List<CTShape> shapes = gs.getSpList();
-        for (CTShape shape : shapes) {
+        for (CTShape shape : gs.getSpArray()) {
             CTTextBody ctTextBody = shape.getTxBody();
             if (ctTextBody==null) {
                 continue;
index 36afac5f8c55bf258dd000b8a798d82d7bfa6fbe..a95e0bbb92c1d0a556da0b8cb2da610273271182 100644 (file)
 \r
 package org.apache.poi.xslf.usermodel;\r
 \r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.GeneralPath;\r
+import java.awt.geom.PathIterator;\r
+import java.awt.geom.Rectangle2D;\r
+\r
 import org.apache.poi.util.Beta;\r
 import org.apache.poi.util.Units;\r
 import org.apache.xmlbeans.XmlObject;\r
@@ -35,11 +40,6 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual;\r
 \r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.GeneralPath;\r
-import java.awt.geom.PathIterator;\r
-import java.awt.geom.Rectangle2D;\r
-\r
 /**\r
  * Represents a custom geometric shape.\r
  * This shape will consist of a series of lines and curves described within a creation path.\r
@@ -120,12 +120,13 @@ public class XSLFFreeformShape extends XSLFAutoShape {
      *\r
      * @return the path\r
      */\r
+    @SuppressWarnings("deprecation")\r
     public GeneralPath getPath() {\r
         GeneralPath path = new GeneralPath();\r
         Rectangle2D bounds = getAnchor();\r
 \r
         CTCustomGeometry2D geom = getSpPr().getCustGeom();\r
-        for(CTPath2D spPath : geom.getPathLst().getPathList()){\r
+        for(CTPath2D spPath : geom.getPathLst().getPathArray()){\r
             double scaleW = bounds.getWidth() / Units.toPoints(spPath.getW());\r
             double scaleH = bounds.getHeight() / Units.toPoints(spPath.getH());\r
             for(XmlObject ch : spPath.selectPath("*")){\r
index 6d6e631b523188b4631cb2b214596f8b37c20e65..43d151c66d56716260c4bdd93b965cf4a06c201a 100644 (file)
@@ -213,7 +213,7 @@ public class XSLFPictureShape extends XSLFSimpleShape {
         if(blip.isSetExtLst()) {\r
 \r
             CTOfficeArtExtensionList extLst = blip.getExtLst();\r
-            for(CTOfficeArtExtension ext : extLst.getExtList()){\r
+            for(CTOfficeArtExtension ext : extLst.getExtArray()){\r
                 String xpath = "declare namespace a14='http://schemas.microsoft.com/office/drawing/2010/main' $this//a14:imgProps/a14:imgLayer";\r
                 XmlObject[] obj = ext.selectPath(xpath);\r
                 if(obj != null && obj.length == 1){\r
index b8b269050954e3e4c69a2f97bac53f101b957635..a6ec8bcfe774d4a033be21e94a52fdeee1b4ed39 100644 (file)
@@ -51,6 +51,7 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
     private CTTable _table;\r
     private List<XSLFTableRow> _rows;\r
 \r
+    @SuppressWarnings("deprecation")\r
     /*package*/ XSLFTable(CTGraphicalObjectFrame shape, XSLFSheet sheet){\r
         super(shape, sheet);\r
 \r
@@ -71,8 +72,9 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
         }\r
 \r
         _table = (CTTable) rs[0];\r
-        _rows = new ArrayList<XSLFTableRow>(_table.sizeOfTrArray());\r
-        for(CTTableRow row : _table.getTrList()) _rows.add(new XSLFTableRow(row, this));\r
+        CTTableRow[] trArray = _table.getTrArray();\r
+        _rows = new ArrayList<XSLFTableRow>(trArray.length);\r
+        for(CTTableRow row : trArray) _rows.add(new XSLFTableRow(row, this));\r
     }\r
 \r
     @Internal\r
index c0067e9c75f39dbe4b0f38056ec6491820f4bd7a..04e9742aa3ec0adb3c785ef4f1f7c8f475dbc301 100644 (file)
 \r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import org.apache.poi.util.Units;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow;\r
-\r
 import java.util.ArrayList;\r
 import java.util.Collections;\r
 import java.util.Iterator;\r
 import java.util.List;\r
 \r
+import org.apache.poi.util.Units;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow;\r
+\r
 /**\r
  * Represents a table in a .pptx presentation\r
  *\r
@@ -38,11 +38,13 @@ public class XSLFTableRow implements Iterable<XSLFTableCell> {
     private List<XSLFTableCell> _cells;\r
     private XSLFTable _table;\r
 \r
+    @SuppressWarnings("deprecation")\r
     /*package*/ XSLFTableRow(CTTableRow row, XSLFTable table){\r
         _row = row;\r
         _table = table;\r
-        _cells = new ArrayList<XSLFTableCell>(_row.sizeOfTcArray());\r
-        for(CTTableCell cell : _row.getTcList()) {\r
+        CTTableCell[] tcArray = _row.getTcArray();\r
+        _cells = new ArrayList<XSLFTableCell>(tcArray.length);\r
+        for(CTTableCell cell : tcArray) {\r
             _cells.add(new XSLFTableCell(cell, table.getSheet()));\r
         }\r
     }\r
index 4ab67e2de5ee8e0d6056d56fdb390c68cdbc3095..245bbaae9da457c0a55617005081b4e57feae30a 100644 (file)
 ==================================================================== */
 package org.apache.poi.xslf.usermodel;
 
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
 import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
@@ -24,12 +30,6 @@ import org.apache.xmlbeans.XmlException;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTableStyle;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTableStyleList;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
 @Beta
 public class XSLFTableStyles extends POIXMLDocumentPart implements Iterable<XSLFTableStyle>{
     private CTTableStyleList _tblStyleLst;
@@ -39,12 +39,14 @@ public class XSLFTableStyles extends POIXMLDocumentPart implements Iterable<XSLF
         super();
     }
 
+    @SuppressWarnings("deprecation")
     public XSLFTableStyles(PackagePart part, PackageRelationship rel) throws IOException, XmlException {
         super(part, rel);
 
         _tblStyleLst = CTTableStyleList.Factory.parse(getPackagePart().getInputStream());
-        _styles = new ArrayList<XSLFTableStyle>(_tblStyleLst.sizeOfTblStyleArray());
-        for(CTTableStyle c : _tblStyleLst.getTblStyleList()){
+        CTTableStyle[] tblStyleArray = _tblStyleLst.getTblStyleArray();
+        _styles = new ArrayList<XSLFTableStyle>(tblStyleArray.length);
+        for(CTTableStyle c : tblStyleArray){
             _styles.add(new XSLFTableStyle(c));
         }
     }
index af1c174c6a6b4fb9e97b9e9610532d73cfbcbe3c..d5ae1a252742c3c10c749e7b21187c27c97aeb56 100644 (file)
 
 package org.apache.poi.xslf.usermodel;
 
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
 import org.apache.poi.POIXMLException;
 import org.apache.poi.util.Beta;
 import org.apache.poi.util.Units;
@@ -36,14 +44,6 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
 import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
 
-import java.awt.Graphics2D;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
 /**
  * Represents a shape that can hold text.
  *
@@ -58,13 +58,14 @@ public abstract class XSLFTextShape extends XSLFSimpleShape implements Iterable<
      */
     private boolean _isTextBroken;
 
+    @SuppressWarnings("deprecation")
     /*package*/ XSLFTextShape(XmlObject shape, XSLFSheet sheet) {
         super(shape, sheet);
 
         _paragraphs = new ArrayList<XSLFTextParagraph>();
         CTTextBody txBody = getTextBody(false);
         if (txBody != null) {
-            for (CTTextParagraph p : txBody.getPList()) {
+            for (CTTextParagraph p : txBody.getPArray()) {
                 _paragraphs.add(new XSLFTextParagraph(p, this));
             }
         }
index a8973dd32e0488504bfe7ff38a78fb29fea277f6..5263473bcacf6c03a83d647c438a248d3e1a5cec 100644 (file)
@@ -22,12 +22,11 @@ import java.util.ArrayList;
 import java.util.List;
 
 import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
 
 import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.util.SAXHelper;
 import org.apache.poi.xssf.usermodel.XSSFRelation;
 import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
@@ -134,10 +133,8 @@ public class ReadOnlySharedStringsTable extends DefaultHandler {
      */
     public void readFrom(InputStream is) throws IOException, SAXException {
         InputSource sheetSource = new InputSource(is);
-        SAXParserFactory saxFactory = SAXParserFactory.newInstance();
         try {
-           SAXParser saxParser = saxFactory.newSAXParser();
-           XMLReader sheetParser = saxParser.getXMLReader();
+           XMLReader sheetParser = SAXHelper.newXMLReader();
            sheetParser.setContentHandler(this);
            sheetParser.parse(sheetSource);
         } catch(ParserConfigurationException e) {
index baaac30406fb3a75a04da103db26facc1fb8d2a7..767742687613de6812f84757a2b99a7f6af9b29c 100644 (file)
@@ -18,7 +18,6 @@ package org.apache.poi.xssf.eventusermodel;
 
 import java.util.Comparator;
 import java.util.LinkedList;
-import java.util.List;
 import java.util.Queue;
 
 import org.apache.poi.ss.usermodel.BuiltinFormats;
@@ -159,11 +158,11 @@ public class XSSFSheetXMLHandler extends DefaultHandler {
        this(styles, strings, sheetContentsHandler, new DataFormatter(), formulasNotResults);
    }
    
+   @SuppressWarnings("deprecation")
    private void init() {
        if (commentsTable != null) {
            commentCellRefs = new LinkedList<CellReference>();
-           List<CTComment> commentList = commentsTable.getCTComments().getCommentList().getCommentList();
-           for (CTComment comment : commentList) {
+           for (CTComment comment : commentsTable.getCTComments().getCommentList().getCommentArray()) {
                commentCellRefs.add(new CellReference(comment.getRef()));
            }
        }   
@@ -187,6 +186,7 @@ public class XSSFSheetXMLHandler extends DefaultHandler {
    }
    
    @Override
+   @SuppressWarnings("unused")
    public void startElement(String uri, String localName, String name,
                             Attributes attributes) throws SAXException {
 
index b70c4abb34150b00dfc626e9be8423a364c13244..c52bed687d33dd3bb18b0fe3b857bc460657c0ae 100644 (file)
@@ -24,8 +24,6 @@ import java.util.Locale;
 import java.util.Map;
 
 import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
 
 import org.apache.poi.POIXMLProperties;
 import org.apache.poi.POIXMLProperties.CoreProperties;
@@ -35,6 +33,7 @@ import org.apache.poi.POIXMLTextExtractor;
 import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
 import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.ss.usermodel.DataFormatter;
+import org.apache.poi.util.SAXHelper;
 import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
 import org.apache.poi.xssf.eventusermodel.XSSFReader;
 import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
@@ -174,10 +173,8 @@ public class XSSFEventBasedExcelExtractor extends POIXMLTextExtractor
        }
       
        InputSource sheetSource = new InputSource(sheetInputStream);
-       SAXParserFactory saxFactory = SAXParserFactory.newInstance();
        try {
-          SAXParser saxParser = saxFactory.newSAXParser();
-          XMLReader sheetParser = saxParser.getXMLReader();
+          XMLReader sheetParser = SAXHelper.newXMLReader();
           ContentHandler handler = new XSSFSheetXMLHandler(
                 styles, comments, strings, sheetContentsExtractor, formatter, formulasNotResults);
           sheetParser.setContentHandler(handler);
index e9b75e53650db6a1c2d16d1cd5bbe614f57ac119..d608f961570d4985a7d47c20e1ecc48df26c19b5 100644 (file)
@@ -28,8 +28,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Vector;
 
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Source;
@@ -45,7 +43,7 @@ import javax.xml.validation.Validator;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.DateUtil;
-import org.apache.poi.util.XMLHelper;
+import org.apache.poi.util.DocumentHelper;
 import org.apache.poi.xssf.usermodel.XSSFCell;
 import org.apache.poi.xssf.usermodel.XSSFMap;
 import org.apache.poi.xssf.usermodel.XSSFRow;
@@ -106,15 +104,6 @@ public class XSSFExportToXml implements Comparator<String>{
         exportToXML(os, "UTF-8", validate);
     }
 
-    private Document getEmptyDocument() throws ParserConfigurationException{
-
-        DocumentBuilderFactory dbfac = XMLHelper.getDocumentBuilderFactory();
-        DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
-        Document doc = docBuilder.newDocument();
-
-        return doc;
-    }
-
     /**
      * Exports the data in an XML stream
      *
@@ -132,7 +121,7 @@ public class XSSFExportToXml implements Comparator<String>{
 
         String rootElement = map.getCtMap().getRootElement();
 
-        Document doc = getEmptyDocument();
+        Document doc = DocumentHelper.createDocument();
 
         Element root = null;
 
@@ -459,8 +448,8 @@ public class XSSFExportToXml implements Comparator<String>{
             Node node = list.item(i);
             if (node instanceof Element) {
                 if (node.getLocalName().equals("element")) {
-                    Node nameAttribute  = node.getAttributes().getNamedItem("name");
-                    if (nameAttribute.getNodeValue().equals(removeNamespace(elementName))) {
+                    Node element = getNameOrRefElement(node);
+                    if (element.getNodeValue().equals(removeNamespace(elementName))) {
                         indexOf = i;
                         break;
                     }
@@ -471,6 +460,15 @@ public class XSSFExportToXml implements Comparator<String>{
         return indexOf;
     }
 
+       private Node getNameOrRefElement(Node node) {
+               Node returnNode = node.getAttributes().getNamedItem("name");
+        if(returnNode != null) {
+            return returnNode;
+               }
+               
+        return node.getAttributes().getNamedItem("ref");
+       }
+
     private Node getComplexTypeForElement(String elementName,Node xmlSchema,Node localComplexTypeRootNode) {
         String elementNameWithoutNamespace = removeNamespace(elementName);
 
@@ -494,7 +492,7 @@ public class XSSFExportToXml implements Comparator<String>{
             Node node = list.item(i);
             if ( node instanceof Element) {
                 if (node.getLocalName().equals("element")) {
-                    Node nameAttribute  = node.getAttributes().getNamedItem("name");
+                    Node nameAttribute = getNameOrRefElement(node);
                     if (nameAttribute.getNodeValue().equals(elementNameWithoutNamespace)) {
                         Node complexTypeAttribute = node.getAttributes().getNamedItem("type");
                         if (complexTypeAttribute!=null) {
@@ -515,7 +513,7 @@ public class XSSFExportToXml implements Comparator<String>{
             Node node = complexTypeList.item(i);
             if ( node instanceof Element) {
                 if (node.getLocalName().equals("complexType")) {
-                    Node nameAttribute  = node.getAttributes().getNamedItem("name");
+                    Node nameAttribute = getNameOrRefElement(node);
                     if (nameAttribute.getNodeValue().equals(complexTypeName)) {
 
                         NodeList complexTypeChildList  =node.getChildNodes();
index 945f1677ca8df8542f4c9f0e1653ffe668635283..534ef0d83ee5aeae3e372f4b37162eb2a5c31ce0 100644 (file)
@@ -24,16 +24,15 @@ import java.util.List;
 
 import javax.xml.namespace.NamespaceContext;
 import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.xpath.XPath;
 import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathExpressionException;
 import javax.xml.xpath.XPathFactory;
 
+import org.apache.poi.util.DocumentHelper;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
-import org.apache.poi.util.XMLHelper;
 import org.apache.poi.xssf.usermodel.XSSFCell;
 import org.apache.poi.xssf.usermodel.XSSFMap;
 import org.apache.poi.xssf.usermodel.XSSFRow;
@@ -76,11 +75,9 @@ public class XSSFImportFromXML {
      * @throws ParserConfigurationException if there are problems with XML parser configuration
      * @throws IOException  if there are problems reading the input string
      */
-    public void importFromXML(String xmlInputString) throws SAXException, XPathExpressionException, ParserConfigurationException, IOException {
+    public void importFromXML(String xmlInputString) throws SAXException, XPathExpressionException, IOException {
 
-        DocumentBuilderFactory factory = XMLHelper.getDocumentBuilderFactory();
-        factory.setNamespaceAware(true);
-        DocumentBuilder builder = factory.newDocumentBuilder();
+        DocumentBuilder builder = DocumentHelper.newDocumentBuilder();
 
         Document doc = builder.parse(new InputSource(new StringReader(xmlInputString.trim())));
 
index f3799ab24e1e69636547de948764e728f574062a..95bbf2907cd40e341e4cd7e18fad0ca299e4f255 100644 (file)
@@ -98,9 +98,11 @@ public class CommentsTable extends POIXMLDocumentPart {
         return comments.getAuthors().getAuthorArray((int)authorId);
     }
 
+    @SuppressWarnings("deprecation")
     public int findAuthor(String author) {
-        for (int i = 0 ; i < comments.getAuthors().sizeOfAuthorArray() ; i++) {
-            if (comments.getAuthors().getAuthorArray(i).equals(author)) {
+        String[] authorArray = comments.getAuthors().getAuthorArray();
+        for (int i = 0 ; i < authorArray.length; i++) {
+            if (authorArray[i].equals(author)) {
                 return i;
             }
         }
@@ -149,15 +151,18 @@ public class CommentsTable extends POIXMLDocumentPart {
 
     public boolean removeComment(String cellRef) {
         CTCommentList lst = comments.getCommentList();
-        if(lst != null) for(int i=0; i < lst.sizeOfCommentArray(); i++) {
-            CTComment comment = lst.getCommentArray(i);
-            if (cellRef.equals(comment.getRef())) {
-                lst.removeComment(i);
-                
-                if(commentRefs != null) {
-                   commentRefs.remove(cellRef);
+        if(lst != null) {
+            CTComment[] commentArray = lst.getCommentArray();
+            for (int i = 0; i < commentArray.length; i++) {
+                CTComment comment = commentArray[i];
+                if (cellRef.equals(comment.getRef())) {
+                    lst.removeComment(i);
+
+                    if(commentRefs != null) {
+                       commentRefs.remove(cellRef);
+                    }
+                    return true;
                 }
-                return true;
             }
         }
         return false;
index f664f6bbc0d6242a8ab6f94e07d8f4f65705f6bf..33c161b4c318198da1f36ebf407d2165559fc007 100644 (file)
@@ -24,7 +24,6 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 
-
 import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
@@ -66,13 +65,14 @@ public class MapInfo extends POIXMLDocumentPart {
                readFrom(part.getInputStream());
        }
 
+    @SuppressWarnings("deprecation")
        public void readFrom(InputStream is) throws IOException {
                try {
                        MapInfoDocument doc = MapInfoDocument.Factory.parse(is);
                        mapInfo = doc.getMapInfo();
 
             maps= new HashMap<Integer, XSSFMap>();
-            for(CTMap map :mapInfo.getMapList()){
+            for(CTMap map :mapInfo.getMapArray()){
                 maps.put((int)map.getID(), new XSSFMap(map,this));
             }
 
@@ -104,10 +104,11 @@ public class MapInfo extends POIXMLDocumentPart {
         * @param schemaId the schema ID
         * @return CTSchema by it's ID
         */
+    @SuppressWarnings("deprecation")
        public CTSchema getCTSchemaById(String schemaId){
                CTSchema xmlSchema = null;
 
-               for(CTSchema schema: mapInfo.getSchemaList()){
+               for(CTSchema schema: mapInfo.getSchemaArray()){
                        if(schema.getID().equals(schemaId)){
                                xmlSchema = schema;
                                break;
index 63c514b1309d46d4095c408c57fdde295ebb2709..cb1542e87be631a172c9224735ae8d19bef78598 100644 (file)
@@ -94,10 +94,11 @@ public class SingleXmlCells extends POIXMLDocumentPart {
         * 
         * @return all the SimpleXmlCell contained in this SingleXmlCells element
         */
+    @SuppressWarnings("deprecation")
        public List<XSSFSingleXmlCell> getAllSimpleXmlCell(){
                List<XSSFSingleXmlCell> list = new Vector<XSSFSingleXmlCell>();
                
-               for(CTSingleXmlCell singleXmlCell: singleXMLCells.getSingleXmlCellList()){                      
+               for(CTSingleXmlCell singleXmlCell: singleXMLCells.getSingleXmlCellArray()){
                        list.add(new XSSFSingleXmlCell(singleXmlCell,this));
                }               
                return list;
index 3bd00f4a2fc75dd7aa94aed68d4b96d648c7e09c..0e8f906339e7df5c8c68ff6c575e8570d6df7334 100644 (file)
@@ -23,20 +23,22 @@ import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.apache.poi.xssf.usermodel.XSSFColor;
 import org.apache.xmlbeans.XmlException;
-import org.apache.xmlbeans.XmlObject;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTColorScheme;
 import org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
 
 /**
  * Class that represents theme of XLSX document. The theme includes specific
  * colors and fonts.
- * 
- * @author Petr Udalau(Petr.Udalau at exigenservices.com) - theme colors
  */
 public class ThemesTable extends POIXMLDocumentPart {
     private ThemeDocument theme;
 
+    /**
+     * Construct a ThemesTable.
+     * @param part A PackagePart.
+     * @param rel A PackageRelationship.
+     */
     public ThemesTable(PackagePart part, PackageRelationship rel) throws IOException {
         super(part, rel);
         
@@ -47,38 +49,56 @@ public class ThemesTable extends POIXMLDocumentPart {
         }
     }
 
+    /**
+     * Construct a ThemesTable from an existing ThemeDocument.
+     * @param theme A ThemeDocument.
+     */
     public ThemesTable(ThemeDocument theme) {
         this.theme = theme;
     }
 
+    /**
+     * Convert a theme "index" into a color.
+     * @param idx A theme "index"
+     * @return The mapped XSSFColor, or null if not mapped.
+     */
     public XSSFColor getThemeColor(int idx) {
+        // Theme color references are NOT positional indices into the color scheme,
+        // i.e. these keys are NOT the same as the order in which theme colors appear
+        // in theme1.xml. They are keys to a mapped color.
         CTColorScheme colorScheme = theme.getTheme().getThemeElements().getClrScheme();
-        CTColor ctColor = null;
-        int cnt = 0;
-        for (XmlObject obj : colorScheme.selectPath("./*")) {
-            if (obj instanceof org.openxmlformats.schemas.drawingml.x2006.main.CTColor) {
-                if (cnt == idx) {
-                    ctColor = (org.openxmlformats.schemas.drawingml.x2006.main.CTColor) obj;
-                    
-                    byte[] rgb = null;
-                    if (ctColor.getSrgbClr() != null) {
-                       // Colour is a regular one 
-                       rgb = ctColor.getSrgbClr().getVal();
-                    } else if (ctColor.getSysClr() != null) {
-                       // Colour is a tint of white or black
-                       rgb = ctColor.getSysClr().getLastClr();
-                    }
+        CTColor ctColor;
+        switch (idx) {
+            case  0: ctColor = colorScheme.getLt1(); break;
+            case  1: ctColor = colorScheme.getDk1(); break;
+            case  2: ctColor = colorScheme.getLt2(); break;
+            case  3: ctColor = colorScheme.getDk2(); break;
+            case  4: ctColor = colorScheme.getAccent1(); break;
+            case  5: ctColor = colorScheme.getAccent2(); break;
+            case  6: ctColor = colorScheme.getAccent3(); break;
+            case  7: ctColor = colorScheme.getAccent4(); break;
+            case  8: ctColor = colorScheme.getAccent5(); break;
+            case  9: ctColor = colorScheme.getAccent6(); break;
+            case 10: ctColor = colorScheme.getHlink(); break;
+            case 11: ctColor = colorScheme.getFolHlink(); break;
+            default: return null;
+        }
 
-                    return new XSSFColor(rgb);
-                }
-                cnt++;
-            }
+        byte[] rgb = null;
+        if (ctColor.isSetSrgbClr()) {
+            // Color is a regular one
+            rgb = ctColor.getSrgbClr().getVal();
+        } else if (ctColor.isSetSysClr()) {
+            // Color is a tint of white or black
+            rgb = ctColor.getSysClr().getLastClr();
+        } else {
+            return null;
         }
-        return null;
+        return new XSSFColor(rgb);        
     }
     
     /**
-     * If the colour is based on a theme, then inherit 
+     * If the colour is based on a theme, then inherit
      *  information (currently just colours) from it as
      *  required.
      */
@@ -91,13 +111,13 @@ public class ThemesTable extends POIXMLDocumentPart {
           // No theme set, nothing to do
           return;
        }
-       
+
        // Get the theme colour
        XSSFColor themeColor = getThemeColor(color.getTheme());
        // Set the raw colour, not the adjusted one
        // Do a raw set, no adjusting at the XSSFColor layer either
        color.getCTColor().setRgb(themeColor.getCTColor().getRgb());
-       
+
        // All done
     }
 }
index bc5c6707dd22c60796f2c5cdbe5d0cc01173f1a5..41038114f6b0f7379e39f19284bb3e4f63ce6d6e 100644 (file)
@@ -19,40 +19,40 @@ package org.apache.poi.xssf.usermodel;
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Map;
 import java.util.List;
-import java.util.ArrayList;
+import java.util.Map;
 
 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.util.Internal;
 import org.apache.poi.ss.usermodel.Chart;
+import org.apache.poi.ss.usermodel.charts.AxisPosition;
 import org.apache.poi.ss.usermodel.charts.ChartAxis;
 import org.apache.poi.ss.usermodel.charts.ChartAxisFactory;
+import org.apache.poi.ss.usermodel.charts.ChartData;
+import org.apache.poi.util.Internal;
 import org.apache.poi.xssf.usermodel.charts.XSSFCategoryAxis;
-import org.apache.poi.xssf.usermodel.charts.XSSFChartDataFactory;
 import org.apache.poi.xssf.usermodel.charts.XSSFChartAxis;
-import org.apache.poi.xssf.usermodel.charts.XSSFValueAxis;
-import org.apache.poi.xssf.usermodel.charts.XSSFManualLayout;
+import org.apache.poi.xssf.usermodel.charts.XSSFChartDataFactory;
 import org.apache.poi.xssf.usermodel.charts.XSSFChartLegend;
-import org.apache.poi.ss.usermodel.charts.ChartData;
-import org.apache.poi.ss.usermodel.charts.AxisPosition;
+import org.apache.poi.xssf.usermodel.charts.XSSFManualLayout;
+import org.apache.poi.xssf.usermodel.charts.XSSFValueAxis;
 import org.apache.xmlbeans.XmlException;
 import org.apache.xmlbeans.XmlObject;
 import org.apache.xmlbeans.XmlOptions;
 import org.openxmlformats.schemas.drawingml.x2006.chart.CTCatAx;
 import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
 import org.openxmlformats.schemas.drawingml.x2006.chart.CTChartSpace;
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTTitle;
-import org.openxmlformats.schemas.drawingml.x2006.chart.ChartSpaceDocument;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTPageMargins;
 import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea;
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx;
 import org.openxmlformats.schemas.drawingml.x2006.chart.CTPrintSettings;
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTPageMargins;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTTitle;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx;
+import org.openxmlformats.schemas.drawingml.x2006.chart.ChartSpaceDocument;
 import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
 import org.w3c.dom.NodeList;
 import org.w3c.dom.Text;
@@ -306,14 +306,16 @@ public final class XSSFChart extends POIXMLDocumentPart implements Chart, ChartA
                parseValueAxis();
        }
 
+    @SuppressWarnings("deprecation")
        private void parseCategoryAxis() {
-               for (CTCatAx catAx : chart.getPlotArea().getCatAxList()) {
+               for (CTCatAx catAx : chart.getPlotArea().getCatAxArray()) {
                        axis.add(new XSSFCategoryAxis(this, catAx));
                }
        }
 
+    @SuppressWarnings("deprecation")
        private void parseValueAxis() {
-               for (CTValAx valAx : chart.getPlotArea().getValAxList()) {
+               for (CTValAx valAx : chart.getPlotArea().getValAxArray()) {
                        axis.add(new XSSFValueAxis(this, valAx));
                }
        }
index b15eaa55bab9f7652b340ed7d6151aa0d45249f1..3082e53878c5611a0ae7e73fa4db724ccea3c533 100644 (file)
@@ -25,16 +25,16 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor;
  * Represents a color in SpreadsheetML
  */
 public class XSSFColor implements Color {
-       
-       private CTColor ctColor;
+
+    private CTColor ctColor;
 
     /**
      * Create an instance of XSSFColor from the supplied XML bean
      */
     public XSSFColor(CTColor color) {
-               this.ctColor = color;
-       }
-       
+        this.ctColor = color;
+    }
+
     /**
      * Create an new instance of XSSFColor
      */
@@ -56,50 +56,29 @@ public class XSSFColor implements Color {
      * A boolean value indicating the ctColor is automatic and system ctColor dependent.
      */
     public boolean isAuto() {
-               return ctColor.getAuto();
-       }
-       
+        return ctColor.getAuto();
+    }
+
     /**
      * A boolean value indicating the ctColor is automatic and system ctColor dependent.
      */
-       public void setAuto(boolean auto) {
-               ctColor.setAuto(auto);
-       }
+    public void setAuto(boolean auto) {
+        ctColor.setAuto(auto);
+    }
 
     /**
      * Indexed ctColor value. Only used for backwards compatibility. References a ctColor in indexedColors.
      */
     public short getIndexed() {
-               return (short)ctColor.getIndexed();
-       }
-       
+        return (short)ctColor.getIndexed();
+    }
+
     /**
      * Indexed ctColor value. Only used for backwards compatibility. References a ctColor in indexedColors.
      */
-       public void setIndexed(int indexed) {
-               ctColor.setIndexed(indexed);
-       }
-       
-       /**
-    * For RGB colours, but not ARGB (we think...)
-    * Excel gets black and white the wrong way around, so switch them 
-        */
-       private byte[] correctRGB(byte[] rgb) {
-          if(rgb.length == 4) {
-             // Excel doesn't appear to get these wrong
-             // Nothing to change
-             return rgb;
-          } else {
-         // Excel gets black and white the wrong way around, so switch them 
-         if (rgb[0] == 0 && rgb[1] == 0 && rgb[2] == 0) {
-            rgb = new byte[] {-1, -1, -1};
-         }
-         else if (rgb[0] == -1 && rgb[1] == -1 && rgb[2] == -1) {
-            rgb = new byte[] {0, 0, 0};
-         }
-         return rgb;
-          }
-       }
+    public void setIndexed(int indexed) {
+        ctColor.setIndexed(indexed);
+    }
 
    /**
     * Standard Red Green Blue ctColor value (RGB).
@@ -108,7 +87,7 @@ public class XSSFColor implements Color {
    public byte[] getRgb() {
       byte[] rgb = getRGBOrARGB();
       if(rgb == null) return null;
-      
+
       if(rgb.length == 4) {
          // Need to trim off the alpha
          byte[] tmp = new byte[3];
@@ -125,7 +104,7 @@ public class XSSFColor implements Color {
    public byte[] getARgb() {
       byte[] rgb = getRGBOrARGB();
       if(rgb == null) return null;
-      
+
       if(rgb.length == 3) {
          // Pad with the default Alpha
          byte[] tmp = new byte[4];
@@ -136,7 +115,7 @@ public class XSSFColor implements Color {
          return rgb;
       }
    }
-   
+
    private byte[] getRGBOrARGB() {
         byte[] rgb = null;
 
@@ -150,7 +129,7 @@ public class XSSFColor implements Color {
                return rgb;
             }
          }
-        
+
          if (!ctColor.isSetRgb()) {
             // No colour is available, sorry
             return null;
@@ -158,9 +137,7 @@ public class XSSFColor implements Color {
 
          // Grab the colour
          rgb = ctColor.getRgb();
-
-         // Correct it as needed, and return
-         return correctRGB(rgb);
+         return rgb;
     }
 
     /**
@@ -181,64 +158,63 @@ public class XSSFColor implements Color {
         }
         return rgb;
     }
-       
+
     /**
      * Return the ARGB value in hex format, eg FF00FF00.
-     * Works for both regular and indexed colours. 
+     * Works for both regular and indexed colours.
      */
-       public String getARGBHex() {
-          StringBuffer sb = new StringBuffer();
-          byte[] rgb = getARgb();
-          if(rgb == null) {
-             return null;
-          }
-          for(byte c : rgb) {
-             int i = (int)c;
-             if(i < 0) {
-                i += 256;
-             }
-             String cs = Integer.toHexString(i);
-             if(cs.length() == 1) {
-                sb.append('0');
-             }
-             sb.append(cs);
-          }
-          return sb.toString().toUpperCase();
-       }
-
-       private static byte applyTint(int lum, double tint){
-               if(tint > 0){
-                       return (byte)(lum * (1.0-tint) + (255 - 255 * (1.0-tint)));
-               } else if (tint < 0){
-                       return (byte)(lum*(1+tint));
-               } else {
-                       return (byte)lum;
-               }
-       }
+    public String getARGBHex() {
+       StringBuffer sb = new StringBuffer();
+       byte[] rgb = getARgb();
+       if(rgb == null) {
+          return null;
+       }
+       for(byte c : rgb) {
+          int i = (int)c;
+          if(i < 0) {
+             i += 256;
+          }
+          String cs = Integer.toHexString(i);
+          if(cs.length() == 1) {
+             sb.append('0');
+          }
+          sb.append(cs);
+       }
+       return sb.toString().toUpperCase();
+    }
+
+    private static byte applyTint(int lum, double tint){
+        if(tint > 0){
+            return (byte)(lum * (1.0-tint) + (255 - 255 * (1.0-tint)));
+        } else if (tint < 0){
+            return (byte)(lum*(1+tint));
+        } else {
+            return (byte)lum;
+        }
+    }
 
     /**
      * Standard Alpha Red Green Blue ctColor value (ARGB).
      */
-       public void setRgb(byte[] rgb) {
-          // Correct it and save
-               ctColor.setRgb(correctRGB(rgb));
-       }
-       
+    public void setRgb(byte[] rgb) {
+       ctColor.setRgb(rgb);
+    }
+
     /**
      * Index into the <clrScheme> collection, referencing a particular <sysClr> or
      *  <srgbClr> value expressed in the Theme part.
      */
    public int getTheme() {
       return (int)ctColor.getTheme();
-       }
-       
+    }
+
     /**
      * Index into the <clrScheme> collection, referencing a particular <sysClr> or
      *  <srgbClr> value expressed in the Theme part.
      */
-       public void setTheme(int theme) {
-               ctColor.setTheme(theme);
-       }
+    public void setTheme(int theme) {
+        ctColor.setTheme(theme);
+    }
 
     /**
      * Specifies the tint value applied to the ctColor.
@@ -282,9 +258,9 @@ public class XSSFColor implements Color {
      * @return the tint value
      */
     public double getTint() {
-               return ctColor.getTint();
-       }
-       
+        return ctColor.getTint();
+    }
+
     /**
      * Specifies the tint value applied to the ctColor.
      *
@@ -326,9 +302,9 @@ public class XSSFColor implements Color {
      *
      * @param tint the tint value
      */
-       public void setTint(double tint) {
-               ctColor.setTint(tint);
-       }
+    public void setTint(double tint) {
+        ctColor.setTint(tint);
+    }
 
     /**
      * Returns the underlying XML bean
@@ -339,7 +315,7 @@ public class XSSFColor implements Color {
     public CTColor getCTColor(){
         return ctColor;
     }
-    
+
     public int hashCode(){
         return ctColor.toString().hashCode();
     }
index e80dc7ee6d9536db8e666e895bc34ac763a1048b..d63a18588d2c54dd2635fad0edbb8907c4d31d6e 100644 (file)
@@ -127,7 +127,7 @@ public class XSSFPivotCacheDefinition extends POIXMLDocumentPart{
         for(int i=columnStart; i<=columnEnd; i++) {
             CTCacheField cf = cFields.addNewCacheField();
             if(i==columnEnd){
-                cFields.setCount(cFields.getCacheFieldList().size());
+                cFields.setCount(cFields.sizeOfCacheFieldArray());
             }
             //General number format
             cf.setNumFmtId(0);
index d31ae3f68ae54fbec1019386a301fe6a015b8685..278e66e3d31266567dad4a3051dbc92e488089b1 100644 (file)
@@ -240,7 +240,6 @@ public class XSSFPivotTable extends POIXMLDocumentPart {
         }
         CTPivotFields pivotFields = pivotTableDefinition.getPivotFields();
 
-        List<CTPivotField> pivotFieldList = pivotTableDefinition.getPivotFields().getPivotFieldList();
         CTPivotField pivotField = CTPivotField.Factory.newInstance();
         CTItems items = pivotField.addNewItems();
 
@@ -249,10 +248,8 @@ public class XSSFPivotTable extends POIXMLDocumentPart {
         for(int i = 0; i <= lastRowIndex; i++) {
             items.addNewItem().setT(STItemType.DEFAULT);
         }
-        items.setCount(items.getItemList().size());
-        pivotFieldList.set(columnIndex, pivotField);
-
-        pivotFields.setPivotFieldArray(pivotFieldList.toArray(new CTPivotField[pivotFieldList.size()]));
+        items.setCount(items.sizeOfItemArray());
+        pivotFields.setPivotFieldArray(columnIndex, pivotField);
 
         CTRowFields rowFields;
         if(pivotTableDefinition.getRowFields() != null) {
@@ -262,7 +259,7 @@ public class XSSFPivotTable extends POIXMLDocumentPart {
         }
 
         rowFields.addNewField().setX(columnIndex);
-        rowFields.setCount(rowFields.getFieldList().size());
+        rowFields.setCount(rowFields.sizeOfFieldArray());
     }
     
     @Beta
@@ -307,7 +304,7 @@ public class XSSFPivotTable extends POIXMLDocumentPart {
                 colFields = pivotTableDefinition.addNewColFields();
             }
             colFields.addNewField().setX(-2);
-            colFields.setCount(colFields.getFieldList().size());
+            colFields.setCount(colFields.sizeOfFieldArray());
         }
     }
 
@@ -338,7 +335,7 @@ public class XSSFPivotTable extends POIXMLDocumentPart {
         cell.setCellType(Cell.CELL_TYPE_STRING);
         dataField.setName(function.getName());
         dataField.setFld(columnIndex);
-        dataFields.setCount(dataFields.getDataFieldList().size());
+        dataFields.setCount(dataFields.sizeOfDataFieldArray());
     }
 
     /**
@@ -354,13 +351,11 @@ public class XSSFPivotTable extends POIXMLDocumentPart {
             throw new IndexOutOfBoundsException();
         }
         CTPivotFields pivotFields = pivotTableDefinition.getPivotFields();
-        List<CTPivotField> pivotFieldList = pivotFields.getPivotFieldList();
         CTPivotField pivotField = CTPivotField.Factory.newInstance();
 
         pivotField.setDataField(isDataField);
         pivotField.setShowAll(false);
-        pivotFieldList.set(columnIndex, pivotField);
-        pivotFields.setPivotFieldArray(pivotFieldList.toArray(new CTPivotField[pivotFieldList.size()]));
+        pivotFields.setPivotFieldArray(columnIndex, pivotField);
     }
 
     /**
@@ -378,7 +373,6 @@ public class XSSFPivotTable extends POIXMLDocumentPart {
         }
         CTPivotFields pivotFields = pivotTableDefinition.getPivotFields();
 
-        List<CTPivotField> pivotFieldList = pivotTableDefinition.getPivotFields().getPivotFieldList();
         CTPivotField pivotField = CTPivotField.Factory.newInstance();
         CTItems items = pivotField.addNewItems();
 
@@ -387,8 +381,8 @@ public class XSSFPivotTable extends POIXMLDocumentPart {
         for(int i = 0; i <= lastRowIndex; i++) {
             items.addNewItem().setT(STItemType.DEFAULT);
         }
-        items.setCount(items.getItemList().size());
-        pivotFieldList.set(columnIndex, pivotField);
+        items.setCount(items.sizeOfItemArray());
+        pivotFields.setPivotFieldArray(columnIndex, pivotField);
 
         CTPageFields pageFields;
         if (pivotTableDefinition.getPageFields()!= null) {
@@ -402,7 +396,7 @@ public class XSSFPivotTable extends POIXMLDocumentPart {
         pageField.setHier(-1);
         pageField.setFld(columnIndex);
 
-        pageFields.setCount(pageFields.getPageFieldList().size());
+        pageFields.setCount(pageFields.sizeOfPageFieldArray());
         pivotTableDefinition.getLocation().setColPageCount(pageFields.getCount());
     }
 
@@ -459,6 +453,6 @@ public class XSSFPivotTable extends POIXMLDocumentPart {
             pivotField.setDataField(false);
             pivotField.setShowAll(false);
         }
-        pivotFields.setCount(pivotFields.getPivotFieldList().size());
+        pivotFields.setCount(pivotFields.sizeOfPivotFieldArray());
     }
 }
index f21b1aa6d241aa541893def9b8c9dc3ae4407fb7..44070b1b559e1bbed2dd3ff3b96f8347060c9f83 100644 (file)
@@ -439,16 +439,18 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
      *
      * @see org.apache.poi.xssf.usermodel.XSSFSheet#write(java.io.OutputStream) ()
      */
+    @SuppressWarnings("deprecation")
     protected void onDocumentWrite(){
         // check if cells in the CTRow are ordered
         boolean isOrdered = true;
-        if(_row.sizeOfCArray() != _cells.size()) {
+        CTCell[] cArray = _row.getCArray();
+        if (cArray.length != _cells.size()) {
             isOrdered = false;
         } else {
             int i = 0;
             for (XSSFCell cell : _cells.values()) {
                 CTCell c1 = cell.getCTCell();
-                CTCell c2 = _row.getCArray(i++); 
+                CTCell c2 = cArray[i++];
 
                 String r1 = c1.getR();
                 String r2 = c2.getR();
@@ -460,17 +462,17 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
         }
 
         if(!isOrdered){
-            CTCell[] cArray = new CTCell[_cells.size()];
+            cArray = new CTCell[_cells.size()];
             int i = 0;
-            for (Map.Entry<Integer, XSSFCell> entry : _cells.entrySet()) {
-                cArray[i] = (CTCell) entry.getValue().getCTCell().copy();
+            for (XSSFCell xssfCell : _cells.values()) {
+                cArray[i] = (CTCell) xssfCell.getCTCell().copy();
                 
                 // we have to copy and re-create the XSSFCell here because the 
                 // elements as otherwise setCArray below invalidates all the columns!
                 // see Bug 56170, XMLBeans seems to always release previous objects
                 // in the CArray, so we need to provide completely new ones here!
                 //_cells.put(entry.getKey(), new XSSFCell(this, cArray[i]));
-                entry.getValue().setCTCell(cArray[i]);
+                xssfCell.setCTCell(cArray[i]);
                 i++;
             }
 
index fb5c6ef6011f6de2b4472fa32f9ca9f009ae0edc..e625d83963d1524913e8c2dc6d347d44bc60d582 100644 (file)
@@ -17,6 +17,9 @@
 
 package org.apache.poi.xssf.usermodel;
 
+import static org.apache.poi.xssf.usermodel.helpers.XSSFPaswordHelper.setPassword;
+import static org.apache.poi.xssf.usermodel.helpers.XSSFPaswordHelper.validatePassword;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -26,13 +29,13 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.TreeMap;
 
 import javax.xml.namespace.QName;
 
 import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.POIXMLException;
-import org.apache.poi.hssf.record.PasswordRecord;
 import org.apache.poi.hssf.util.PaneInformation;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.exceptions.PartAlreadyExistsException;
@@ -40,6 +43,7 @@ import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
 import org.apache.poi.openxml4j.opc.TargetMode;
+import org.apache.poi.poifs.crypt.HashAlgorithm;
 import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.ss.formula.FormulaShifter;
 import org.apache.poi.ss.formula.SheetNameFormatter;
@@ -60,7 +64,6 @@ import org.apache.poi.ss.util.CellReference;
 import org.apache.poi.ss.util.SSCellRange;
 import org.apache.poi.ss.util.SheetUtil;
 import org.apache.poi.util.Beta;
-import org.apache.poi.util.HexDump;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
@@ -110,7 +113,6 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCalcMode;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPane;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPaneState;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnsignedShortHex;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument;
 
 /**
@@ -649,6 +651,28 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         return null;
     }
 
+    @SuppressWarnings("deprecation")
+    private int[] getBreaks(CTPageBreak ctPageBreak) {
+        CTBreak[] brkArray = ctPageBreak.getBrkArray();
+        int[] breaks = new int[brkArray.length];
+        for (int i = 0 ; i < brkArray.length ; i++) {
+            breaks[i] = (int) brkArray[i].getId() - 1;
+        }
+        return breaks;
+    }
+
+    @SuppressWarnings("deprecation")
+    private void removeBreak(int index, CTPageBreak ctPageBreak) {
+        int index1 = index + 1;
+        CTBreak[] brkArray = ctPageBreak.getBrkArray();
+        for (int i = 0 ; i < brkArray.length ; i++) {
+            if (brkArray[i].getId() == index1) {
+                ctPageBreak.removeBrk(i);
+                // TODO: check if we can break here, i.e. if a page can have more than 1 break on the same id
+            }
+        }
+    }
+
     /**
      * Vertical page break information used for print layout view, page layout view, drawing print breaks
      * in normal view, and for printing the worksheet.
@@ -656,20 +680,8 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      * @return column indexes of all the vertical page breaks, never <code>null</code>
      */
     @Override
-    @SuppressWarnings("deprecation") //YK: getXYZArray() array accessors are deprecated in xmlbeans with JDK 1.5 support
     public int[] getColumnBreaks() {
-        if (!worksheet.isSetColBreaks() || worksheet.getColBreaks().sizeOfBrkArray() == 0) {
-            return new int[0];
-        }
-
-        CTBreak[] brkArray = worksheet.getColBreaks().getBrkArray();
-
-        int[] breaks = new int[brkArray.length];
-        for (int i = 0 ; i < brkArray.length ; i++) {
-            CTBreak brk = brkArray[i];
-            breaks[i] = (int)brk.getId() - 1;
-        }
-        return breaks;
+        return worksheet.isSetColBreaks() ? getBreaks(worksheet.getColBreaks()) : new int[0];
     }
 
     /**
@@ -752,8 +764,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      * @param value true for right to left, false otherwise.
      */
     @Override
-    public void setRightToLeft(boolean value)
-    {
+    public void setRightToLeft(boolean value) {
        CTSheetView view = getDefaultSheetView();
        view.setRightToLeft(value);
     }
@@ -764,10 +775,9 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      * @return whether the text is displayed in right-to-left mode in the window
      */
     @Override
-    public boolean isRightToLeft()
-    {
+    public boolean isRightToLeft() {
        CTSheetView view = getDefaultSheetView();
-       return view == null ? false : view.getRightToLeft();
+       return view != null && view.getRightToLeft();
     }
 
     /**
@@ -804,7 +814,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
     @Override
     public boolean isDisplayZeros(){
         CTSheetView view = getDefaultSheetView();
-        return view == null ? true : view.getShowZeros();
+        return view == null || view.getShowZeros();
     }
 
     /**
@@ -826,7 +836,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      */
     @Override
     public int getFirstRowNum() {
-        return _rows.size() == 0 ? 0 : _rows.firstKey();
+        return _rows.isEmpty() ? 0 : _rows.firstKey();
     }
 
     /**
@@ -944,7 +954,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
 
     @Override
     public int getLastRowNum() {
-        return _rows.size() == 0 ? 0 : _rows.lastKey();
+        return _rows.isEmpty() ? 0 : _rows.lastKey();
     }
 
     @Override
@@ -1079,9 +1089,9 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
     }
 
     /**
-     * Returns the number of phsyically defined rows (NOT the number of rows in the sheet)
+     * Returns the number of physically defined rows (NOT the number of rows in the sheet)
      *
-     * @return the number of phsyically defined rows
+     * @return the number of physically defined rows
      */
     @Override
     public int getPhysicalNumberOfRows() {
@@ -1105,7 +1115,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      */
     @Override
     public boolean getProtect() {
-        return worksheet.isSetSheetProtection() && sheetProtectionEnabled();
+        return isSheetLocked();
     }
 
     /**
@@ -1117,10 +1127,9 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      */
     @Override
     public void protectSheet(String password) {
-
-        if(password != null) {
-            CTSheetProtection sheetProtection = worksheet.addNewSheetProtection();
-            sheetProtection.xsetPassword(stringToExcelPassword(password));
+        if (password != null) {
+            CTSheetProtection sheetProtection = safeGetProtectionField();
+            setSheetPassword(password, null); // defaults to xor password
             sheetProtection.setSheet(true);
             sheetProtection.setScenarios(true);
             sheetProtection.setObjects(true);
@@ -1130,18 +1139,27 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
     }
 
     /**
-     * Converts a String to a {@link STUnsignedShortHex} value that contains the {@link PasswordRecord#hashPassword(String)}
-     * value in hexadecimal format
-     *
-     * @param password the password string you wish convert to an {@link STUnsignedShortHex}
-     * @return {@link STUnsignedShortHex} that contains Excel hashed password in Hex format
+     * Sets the sheet password. 
+     * 
+     * @param password if null, the password will be removed
+     * @param hashAlgo if null, the password will be set as XOR password (Excel 2010 and earlier)
+     *  otherwise the given algorithm is used for calculating the hash password (Excel 2013)
      */
-    private STUnsignedShortHex stringToExcelPassword(String password) {
-        STUnsignedShortHex hexPassword = STUnsignedShortHex.Factory.newInstance();
-        hexPassword.setStringValue(String.valueOf(HexDump.shortToHex(PasswordRecord.hashPassword(password))).substring(2));
-        return hexPassword;
+    public void setSheetPassword(String password, HashAlgorithm hashAlgo) {
+        if (password == null && !isSheetProtectionEnabled()) return;
+        setPassword(safeGetProtectionField(), password, hashAlgo, null);
     }
 
+    /**
+     * Validate the password against the stored hash, the hashing method will be determined
+     *  by the existing password attributes
+     * @return true, if the hashes match (... though original password may differ ...)
+     */
+    public boolean validateSheetPassword(String password) {
+        if (!isSheetProtectionEnabled()) return (password == null);
+        return validatePassword(safeGetProtectionField(), password, null);
+    }
+    
     /**
      * Returns the logical row ( 0-based).  If you ask for a row that is not
      * defined you get a null.  This is to say row 4 represents the fifth row on a sheet.
@@ -1161,19 +1179,9 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      * @return row indexes of all the horizontal page breaks, never <code>null</code>
      */
     @Override
-    @SuppressWarnings("deprecation") //YK: getXYZArray() array accessors are deprecated in xmlbeans with JDK 1.5 support
     public int[] getRowBreaks() {
-        if (!worksheet.isSetRowBreaks() || worksheet.getRowBreaks().sizeOfBrkArray() == 0) {
-            return new int[0];
-        }
+        return worksheet.isSetRowBreaks() ? getBreaks(worksheet.getRowBreaks()) : new int[0];
 
-        CTBreak[] brkArray = worksheet.getRowBreaks().getBrkArray();
-        int[] breaks = new int[brkArray.length];
-        for (int i = 0 ; i < brkArray.length ; i++) {
-            CTBreak brk = brkArray[i];
-            breaks[i] = (int)brk.getId() - 1;
-        }
-        return breaks;
     }
 
     /**
@@ -1342,8 +1350,9 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
     /**
      * Do not leave the width attribute undefined (see #52186).
      */
+    @SuppressWarnings("deprecation")
     private void setColWidthAttribute(CTCols ctCols) {
-        for (CTCol col : ctCols.getColList()) {
+        for (CTCol col : ctCols.getColArray()) {
             if (!col.isSetWidth()) {
                 col.setWidth(getDefaultColumnWidth());
                 col.setCustomWidth(false);
@@ -1372,21 +1381,22 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
     }
 
     private short getMaxOutlineLevelRows(){
-        short outlineLevel=0;
-        for(XSSFRow xrow : _rows.values()){
-            outlineLevel=xrow.getCTRow().getOutlineLevel()>outlineLevel? xrow.getCTRow().getOutlineLevel(): outlineLevel;
+        int outlineLevel = 0;
+        for (XSSFRow xrow : _rows.values()) {
+            outlineLevel = Math.max(outlineLevel, xrow.getCTRow().getOutlineLevel());
         }
-        return outlineLevel;
+        return (short) outlineLevel;
     }
 
 
+    @SuppressWarnings("deprecation")
     private short getMaxOutlineLevelCols() {
         CTCols ctCols = worksheet.getColsArray(0);
-        short outlineLevel = 0;
-        for (CTCol col : ctCols.getColList()) {
-            outlineLevel = col.getOutlineLevel() > outlineLevel ? col.getOutlineLevel() : outlineLevel;
+        int outlineLevel = 0;
+        for (CTCol col : ctCols.getColArray()) {
+            outlineLevel = Math.max(outlineLevel, col.getOutlineLevel());
         }
-        return outlineLevel;
+        return (short) outlineLevel;
     }
 
     /**
@@ -1394,8 +1404,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      */
     @Override
     public boolean isColumnBroken(int column) {
-        int[] colBreaks = getColumnBreaks();
-        for (int colBreak : colBreaks) {
+        for (int colBreak : getColumnBreaks()) {
             if (colBreak == column) {
                 return true;
             }
@@ -1514,8 +1523,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      */
     @Override
     public boolean isRowBroken(int row) {
-        int[] rowBreaks = getRowBreaks();
-        for (int rowBreak : rowBreaks) {
+        for (int rowBreak : getRowBreaks()) {
             if (rowBreak == row) {
                 return true;
             }
@@ -1523,6 +1531,17 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         return false;
     }
 
+    private void setBreak(int id, CTPageBreak ctPgBreak, int lastIndex) {
+        CTBreak brk = ctPgBreak.addNewBrk();
+        brk.setId(id + 1); // this is id of the element which is 1-based: <row r="1" ... >
+        brk.setMan(true);
+        brk.setMax(lastIndex); //end column of the break
+
+        int nPageBreaks = ctPgBreak.sizeOfBrkArray();
+        ctPgBreak.setCount(nPageBreaks);
+        ctPgBreak.setManualBreakCount(nPageBreaks);
+    }
+
     /**
      * Sets a page break at the indicated row
      * Breaks occur above the specified row and left of the specified column inclusive.
@@ -1536,15 +1555,9 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      */
     @Override
     public void setRowBreak(int row) {
-        CTPageBreak pgBreak = worksheet.isSetRowBreaks() ? worksheet.getRowBreaks() : worksheet.addNewRowBreaks();
-        if (! isRowBroken(row)) {
-            CTBreak brk = pgBreak.addNewBrk();
-            brk.setId(row + 1); // this is id of the row element which is 1-based: <row r="1" ... >
-            brk.setMan(true);
-            brk.setMax(SpreadsheetVersion.EXCEL2007.getLastColumnIndex()); //end column of the break
-
-            pgBreak.setCount(pgBreak.sizeOfBrkArray());
-            pgBreak.setManualBreakCount(pgBreak.sizeOfBrkArray());
+        if (!isRowBroken(row)) {
+            CTPageBreak pgBreak = worksheet.isSetRowBreaks() ? worksheet.getRowBreaks() : worksheet.addNewRowBreaks();
+            setBreak(row, pgBreak, SpreadsheetVersion.EXCEL2007.getLastColumnIndex());
         }
     }
 
@@ -1552,20 +1565,10 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      * Removes a page break at the indicated column
      */
     @Override
-    @SuppressWarnings("deprecation") //YK: getXYZArray() array accessors are deprecated in xmlbeans with JDK 1.5 support
     public void removeColumnBreak(int column) {
-        if (!worksheet.isSetColBreaks()) {
-            // no breaks
-            return;
-        }
-
-        CTPageBreak pgBreak = worksheet.getColBreaks();
-        CTBreak[] brkArray = pgBreak.getBrkArray();
-        for (int i = 0 ; i < brkArray.length ; i++) {
-            if (brkArray[i].getId() == (column + 1)) {
-                pgBreak.removeBrk(i);
-            }
-        }
+        if (worksheet.isSetColBreaks()) {
+            removeBreak(column, worksheet.getColBreaks());
+        } // else no breaks
     }
 
     /**
@@ -1574,22 +1577,46 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      * @param index of the region to unmerge
      */
     @Override
+    @SuppressWarnings("deprecation")
     public void removeMergedRegion(int index) {
+        if (!worksheet.isSetMergeCells()) return;
+        
         CTMergeCells ctMergeCells = worksheet.getMergeCells();
+        int size = ctMergeCells.sizeOfMergeCellArray();
+        assert(0 <= index && index < size);
+        if (size > 1) {
+            ctMergeCells.removeMergeCell(index);
+        } else {
+            worksheet.unsetMergeCells();
+        }
+    }
 
-        CTMergeCell[] mergeCellsArray = new CTMergeCell[ctMergeCells.sizeOfMergeCellArray() - 1];
-        for (int i = 0 ; i < ctMergeCells.sizeOfMergeCellArray() ; i++) {
-            if (i < index) {
-                mergeCellsArray[i] = ctMergeCells.getMergeCellArray(i);
-            }
-            else if (i > index) {
-                mergeCellsArray[i - 1] = ctMergeCells.getMergeCellArray(i);
-            }
+    /**
+     * Removes a number of merged regions of cells (hence letting them free)
+     *
+     * This method can be used to bulk-remove merged regions in a way
+     * much faster than calling removeMergedRegion() for every single
+     * merged region.
+     *
+     * @param indices A set of the regions to unmerge
+     */
+    @SuppressWarnings("deprecation")
+    public void removeMergedRegions(Set<Integer> indices) {
+        if (!worksheet.isSetMergeCells()) return;
+        
+        CTMergeCells ctMergeCells = worksheet.getMergeCells();
+        List<CTMergeCell> newMergeCells = new ArrayList<CTMergeCell>(ctMergeCells.sizeOfMergeCellArray());
+
+        int idx = 0;
+        for (CTMergeCell mc : ctMergeCells.getMergeCellArray()) {
+            if (!indices.contains(idx++)) newMergeCells.add(mc);
         }
-        if(mergeCellsArray.length > 0){
-            ctMergeCells.setMergeCellArray(mergeCellsArray);
-        } else{
+        
+        if (newMergeCells.isEmpty()) {
             worksheet.unsetMergeCells();
+        } else{
+            CTMergeCell[] newMergeCellsArray = new CTMergeCell[newMergeCells.size()];
+            ctMergeCells.setMergeCellArray(newMergeCells.toArray(newMergeCellsArray));
         }
     }
 
@@ -1618,18 +1645,10 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      * Removes the page break at the indicated row
      */
     @Override
-    @SuppressWarnings("deprecation") //YK: getXYZArray() array accessors are deprecated in xmlbeans with JDK 1.5 support
     public void removeRowBreak(int row) {
-        if(!worksheet.isSetRowBreaks()) {
-            return;
-        }
-        CTPageBreak pgBreak = worksheet.getRowBreaks();
-        CTBreak[] brkArray = pgBreak.getBrkArray();
-        for (int i = 0 ; i < brkArray.length ; i++) {
-            if (brkArray[i].getId() == (row + 1)) {
-                pgBreak.removeBrk(i);
-            }
-        }
+        if (worksheet.isSetRowBreaks()) {
+            removeBreak(row, worksheet.getRowBreaks());
+        } // else no breaks
     }
 
     /**
@@ -1743,15 +1762,9 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      */
     @Override
     public void setColumnBreak(int column) {
-        if (! isColumnBroken(column)) {
+        if (!isColumnBroken(column)) {
             CTPageBreak pgBreak = worksheet.isSetColBreaks() ? worksheet.getColBreaks() : worksheet.addNewColBreaks();
-            CTBreak brk = pgBreak.addNewBrk();
-            brk.setId(column + 1);  // this is id of the row element which is 1-based: <row r="1" ... >
-            brk.setMan(true);
-            brk.setMax(SpreadsheetVersion.EXCEL2007.getLastRowIndex()); //end row of the break
-
-            pgBreak.setCount(pgBreak.sizeOfBrkArray());
-            pgBreak.setManualBreakCount(pgBreak.sizeOfBrkArray());
+            setBreak(column, pgBreak, SpreadsheetVersion.EXCEL2007.getLastRowIndex());
         }
     }
 
@@ -1781,23 +1794,23 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
                 .getOutlineLevel(), true);
 
         // write collapse field
-        setColumn(lastColMax + 1, null, 0, null, null, Boolean.TRUE);
+        setColumn(lastColMax + 1, 0, null, null, Boolean.TRUE);
 
     }
 
-    private void setColumn(int targetColumnIx, Short xfIndex, Integer style,
-            Integer level, Boolean hidden, Boolean collapsed) {
+    @SuppressWarnings("deprecation")
+    private void setColumn(int targetColumnIx, Integer style,
+                           Integer level, Boolean hidden, Boolean collapsed) {
         CTCols cols = worksheet.getColsArray(0);
         CTCol ci = null;
-        int k = 0;
-        for (k = 0; k < cols.sizeOfColArray(); k++) {
-            CTCol tci = cols.getColArray(k);
-            if (tci.getMin() >= targetColumnIx
-                    && tci.getMax() <= targetColumnIx) {
+        for (CTCol tci : cols.getColArray()) {
+            long tciMin = tci.getMin();
+            long tciMax = tci.getMax();
+            if (tciMin >= targetColumnIx && tciMax <= targetColumnIx) {
                 ci = tci;
                 break;
             }
-            if (tci.getMin() > targetColumnIx) {
+            if (tciMin > targetColumnIx) {
                 // call column infos after k are for later columns
                 break; // exit now so k will be the correct insert pos
             }
@@ -1814,36 +1827,32 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
             return;
         }
 
-        boolean styleChanged = style != null
-        && ci.getStyle() != style;
-        boolean levelChanged = level != null
-        && ci.getOutlineLevel() != level;
-        boolean hiddenChanged = hidden != null
-        && ci.getHidden() != hidden;
-        boolean collapsedChanged = collapsed != null
-        && ci.getCollapsed() != collapsed;
-        boolean columnChanged = levelChanged || hiddenChanged
-        || collapsedChanged || styleChanged;
+        boolean styleChanged = style != null && ci.getStyle() != style;
+        boolean levelChanged = level != null && ci.getOutlineLevel() != level;
+        boolean hiddenChanged = hidden != null && ci.getHidden() != hidden;
+        boolean collapsedChanged = collapsed != null && ci.getCollapsed() != collapsed;
+        boolean columnChanged = levelChanged || hiddenChanged || collapsedChanged || styleChanged;
         if (!columnChanged) {
             // do nothing...nothing changed.
             return;
         }
 
-        if (ci.getMin() == targetColumnIx && ci.getMax() == targetColumnIx) {
+        long ciMin = ci.getMin();
+        long ciMax = ci.getMax();
+        if (ciMin == targetColumnIx && ciMax == targetColumnIx) {
             // ColumnInfo ci for a single column, the target column
             unsetCollapsed(collapsed, ci);
             return;
         }
 
-        if (ci.getMin() == targetColumnIx || ci.getMax() == targetColumnIx) {
+        if (ciMin == targetColumnIx || ciMax == targetColumnIx) {
             // The target column is at either end of the multi-column ColumnInfo
             // ci
             // we'll just divide the info and create a new one
-            if (ci.getMin() == targetColumnIx) {
+            if (ciMin == targetColumnIx) {
                 ci.setMin(targetColumnIx + 1);
             } else {
                 ci.setMax(targetColumnIx - 1);
-                k++; // adjust insert pos to insert after
             }
             CTCol nci = columnHelper.cloneCol(cols, ci);
             nci.setMin(targetColumnIx);
@@ -1852,12 +1861,11 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
 
         } else {
             // split to 3 records
-            CTCol ciStart = ci;
             CTCol ciMid = columnHelper.cloneCol(cols, ci);
             CTCol ciEnd = columnHelper.cloneCol(cols, ci);
-            int lastcolumn = (int) ci.getMax();
+            int lastcolumn = (int) ciMax;
 
-            ciStart.setMax(targetColumnIx - 1);
+            ci.setMax(targetColumnIx - 1);
 
             ciMid.setMin(targetColumnIx);
             ciMid.setMax(targetColumnIx);
@@ -1886,14 +1894,16 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      *                the col info index of the start of the outline group
      * @return the column index of the last column in the outline group
      */
+    @SuppressWarnings("deprecation")
     private int setGroupHidden(int pIdx, int level, boolean hidden) {
         CTCols cols = worksheet.getColsArray(0);
         int idx = pIdx;
-        CTCol columnInfo = cols.getColArray(idx);
-        while (idx < cols.sizeOfColArray()) {
+        CTCol[] colArray = cols.getColArray();
+        CTCol columnInfo = colArray[idx];
+        while (idx < colArray.length) {
             columnInfo.setHidden(hidden);
-            if (idx + 1 < cols.sizeOfColArray()) {
-                CTCol nextColumnInfo = cols.getColArray(idx + 1);
+            if (idx + 1 < colArray.length) {
+                CTCol nextColumnInfo = colArray[idx + 1];
 
                 if (!isAdjacentBefore(columnInfo, nextColumnInfo)) {
                     break;
@@ -1910,17 +1920,19 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
     }
 
     private boolean isAdjacentBefore(CTCol col, CTCol other_col) {
-        return (col.getMax() == (other_col.getMin() - 1));
+        return col.getMax() == other_col.getMin() - 1;
     }
 
+    @SuppressWarnings("deprecation")
     private int findStartOfColumnOutlineGroup(int pIdx) {
         // Find the start of the group.
         CTCols cols = worksheet.getColsArray(0);
-        CTCol columnInfo = cols.getColArray(pIdx);
+        CTCol[] colArray = cols.getColArray();
+        CTCol columnInfo = colArray[pIdx];
         int level = columnInfo.getOutlineLevel();
         int idx = pIdx;
         while (idx != 0) {
-            CTCol prevColumnInfo = cols.getColArray(idx - 1);
+            CTCol prevColumnInfo = colArray[idx - 1];
             if (!isAdjacentBefore(prevColumnInfo, columnInfo)) {
                 break;
             }
@@ -1933,14 +1945,17 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         return idx;
     }
 
+    @SuppressWarnings("deprecation")
     private int findEndOfColumnOutlineGroup(int colInfoIndex) {
         CTCols cols = worksheet.getColsArray(0);
         // Find the end of the group.
-        CTCol columnInfo = cols.getColArray(colInfoIndex);
+        CTCol[] colArray = cols.getColArray();
+        CTCol columnInfo = colArray[colInfoIndex];
         int level = columnInfo.getOutlineLevel();
         int idx = colInfoIndex;
-        while (idx < cols.sizeOfColArray() - 1) {
-            CTCol nextColumnInfo = cols.getColArray(idx + 1);
+        int lastIdx = colArray.length - 1;
+        while (idx < lastIdx) {
+            CTCol nextColumnInfo = colArray[idx + 1];
             if (!isAdjacentBefore(columnInfo, nextColumnInfo)) {
                 break;
             }
@@ -1953,6 +1968,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         return idx;
     }
 
+    @SuppressWarnings("deprecation")
     private void expandColumn(int columnIndex) {
         CTCols cols = worksheet.getColsArray(0);
         CTCol col = columnHelper.getColumn(columnIndex, false);
@@ -1983,12 +1999,13 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         // is the enclosing group
         // hidden bit only is altered for this outline level. ie. don't
         // uncollapse contained groups
-        CTCol columnInfo = cols.getColArray(endIdx);
+        CTCol[] colArray = cols.getColArray();
+        CTCol columnInfo = colArray[endIdx];
         if (!isColumnGroupHiddenByParent(idx)) {
-            int outlineLevel = columnInfo.getOutlineLevel();
+            short outlineLevel = columnInfo.getOutlineLevel();
             boolean nestedGroup = false;
             for (int i = startIdx; i <= endIdx; i++) {
-                CTCol ci = cols.getColArray(i);
+                CTCol ci = colArray[i];
                 if (outlineLevel == ci.getOutlineLevel()) {
                     ci.unsetHidden();
                     if (nestedGroup) {
@@ -2002,20 +2019,21 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         }
         // Write collapse flag (stored in a single col info record after this
         // outline group)
-        setColumn((int) columnInfo.getMax() + 1, null, null, null,
+        setColumn((int) columnInfo.getMax() + 1, null, null,
                 Boolean.FALSE, Boolean.FALSE);
     }
 
+    @SuppressWarnings("deprecation")
     private boolean isColumnGroupHiddenByParent(int idx) {
         CTCols cols = worksheet.getColsArray(0);
         // Look out outline details of end
         int endLevel = 0;
         boolean endHidden = false;
         int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup(idx);
-        if (endOfOutlineGroupIdx < cols.sizeOfColArray()) {
-            CTCol nextInfo = cols.getColArray(endOfOutlineGroupIdx + 1);
-            if (isAdjacentBefore(cols.getColArray(endOfOutlineGroupIdx),
-                    nextInfo)) {
+        CTCol[] colArray = cols.getColArray();
+        if (endOfOutlineGroupIdx < colArray.length) {
+            CTCol nextInfo = colArray[endOfOutlineGroupIdx + 1];
+            if (isAdjacentBefore(colArray[endOfOutlineGroupIdx], nextInfo)) {
                 endLevel = nextInfo.getOutlineLevel();
                 endHidden = nextInfo.getHidden();
             }
@@ -2025,10 +2043,9 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         boolean startHidden = false;
         int startOfOutlineGroupIdx = findStartOfColumnOutlineGroup(idx);
         if (startOfOutlineGroupIdx > 0) {
-            CTCol prevInfo = cols.getColArray(startOfOutlineGroupIdx - 1);
+            CTCol prevInfo = colArray[startOfOutlineGroupIdx - 1];
 
-            if (isAdjacentBefore(prevInfo, cols
-                    .getColArray(startOfOutlineGroupIdx))) {
+            if (isAdjacentBefore(prevInfo, colArray[startOfOutlineGroupIdx])) {
                 startLevel = prevInfo.getOutlineLevel();
                 startHidden = prevInfo.getHidden();
             }
@@ -2040,6 +2057,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         return startHidden;
     }
 
+    @SuppressWarnings("deprecation")
     private int findColInfoIdx(int columnValue, int fromColInfoIdx) {
         CTCols cols = worksheet.getColsArray(0);
 
@@ -2052,8 +2070,9 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
                     "fromIdx parameter out of range: " + fromColInfoIdx);
         }
 
-        for (int k = fromColInfoIdx; k < cols.sizeOfColArray(); k++) {
-            CTCol ci = cols.getColArray(k);
+        CTCol[] colArray = cols.getColArray();
+        for (int k = fromColInfoIdx; k < colArray.length; k++) {
+            CTCol ci = colArray[k];
 
             if (containsColumn(ci, columnValue)) {
                 return k;
@@ -2078,16 +2097,18 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      * @param idx
      * @return a boolean represented if the column is collapsed
      */
+    @SuppressWarnings("deprecation")
     private boolean isColumnGroupCollapsed(int idx) {
         CTCols cols = worksheet.getColsArray(0);
+        CTCol[] colArray = cols.getColArray();
         int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup(idx);
         int nextColInfoIx = endOfOutlineGroupIdx + 1;
-        if (nextColInfoIx >= cols.sizeOfColArray()) {
+        if (nextColInfoIx >= colArray.length) {
             return false;
         }
-        CTCol nextColInfo = cols.getColArray(nextColInfoIx);
+        CTCol nextColInfo = colArray[nextColInfoIx];
 
-        CTCol col = cols.getColArray(endOfOutlineGroupIdx);
+        CTCol col = colArray[endOfOutlineGroupIdx];
         if (!isAdjacentBefore(col, nextColInfo)) {
             return false;
         }
@@ -2294,7 +2315,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      */
     private int findStartOfRowOutlineGroup(int rowIndex) {
         // Find the start of the group.
-        int level = getRow(rowIndex).getCTRow().getOutlineLevel();
+        short level = getRow(rowIndex).getCTRow().getOutlineLevel();
         int currentRow = rowIndex;
         while (getRow(currentRow) != null) {
             if (getRow(currentRow).getCTRow().getOutlineLevel() < level)
@@ -2305,7 +2326,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
     }
 
     private int writeHidden(XSSFRow xRow, int rowIndex, boolean hidden) {
-        int level = xRow.getCTRow().getOutlineLevel();
+        short level = xRow.getCTRow().getOutlineLevel();
         for (Iterator<Row> it = rowIterator(); it.hasNext();) {
             xRow = (XSSFRow) it.next();
 
@@ -2352,10 +2373,10 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         // is the enclosing group
         // hidden bit only is altered for this outline level. ie. don't
         // un-collapse contained groups
+        short level = row.getCTRow().getOutlineLevel();
         if (!isRowGroupHiddenByParent(rowNumber)) {
             for (int i = startIdx; i < endIdx; i++) {
-                if (row.getCTRow().getOutlineLevel() == getRow(i).getCTRow()
-                        .getOutlineLevel()) {
+                if (level == getRow(i).getCTRow().getOutlineLevel()) {
                     getRow(i).getCTRow().unsetHidden();
                 } else if (!isRowGroupCollapsed(i)) {
                     getRow(i).getCTRow().unsetHidden();
@@ -2374,7 +2395,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      * @param row the zero based row index to find from
      */
     public int findEndOfRowOutlineGroup(int row) {
-        int level = getRow(row).getCTRow().getOutlineLevel();
+        short level = getRow(row).getCTRow().getOutlineLevel();
         int currentRow;
         for (currentRow = row; currentRow < getLastRowNum(); currentRow++) {
             if (getRow(currentRow) == null
@@ -2630,11 +2651,11 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         for (int i = fromRow; i <= toRow; i++) {
             XSSFRow xrow = getRow(i);
             if (xrow != null) {
-                CTRow ctrow = xrow.getCTRow();
-                short outlinelevel = ctrow.getOutlineLevel();
-                ctrow.setOutlineLevel((short) (outlinelevel - 1));
+                CTRow ctRow = xrow.getCTRow();
+                int outlineLevel = ctRow.getOutlineLevel();
+                ctRow.setOutlineLevel((short) (outlineLevel - 1));
                 //remove a row only if the row has no cell and if the outline level is 0
-                if (ctrow.getOutlineLevel() == 0 && xrow.getFirstCellNum() == -1) {
+                if (outlineLevel == 1 && xrow.getFirstCellNum() == -1) {
                     removeRow(xrow);
                 }
             }
@@ -2746,13 +2767,11 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      *  so we can decide about writing it to disk or not
      */
     public boolean hasComments() {
-        if(sheetComments == null) { return false; }
-        return (sheetComments.getNumberOfComments() > 0);
+        return sheetComments != null && sheetComments.getNumberOfComments() > 0;
     }
 
     protected int getNumberOfComments() {
-        if(sheetComments == null) { return 0; }
-        return sheetComments.getNumberOfComments();
+        return sheetComments == null ? 0 : sheetComments.getNumberOfComments();
     }
 
     private CTSelection getSheetTypeSelection() {
@@ -2851,7 +2870,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
             CTCellFormula sf = (CTCellFormula)f.copy();
             CellRangeAddress sfRef = CellRangeAddress.valueOf(sf.getRef());
             CellReference cellRef = new CellReference(cell);
-            // If the shared formula range preceeds the master cell then the preceding  part is discarded, e.g.
+            // If the shared formula range precedes the master cell then the preceding  part is discarded, e.g.
             // if the cell is E60 and the shared formula range is C60:M85 then the effective range is E60:M85
             // see more details in https://issues.apache.org/bugzilla/show_bug.cgi?id=51710
             if(cellRef.getCol() > sfRef.getFirstColumn() || cellRef.getRow() > sfRef.getFirstRow()){
@@ -2929,304 +2948,392 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      * @return true when Autofilters are locked and the sheet is protected.
      */
     public boolean isAutoFilterLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && worksheet.getSheetProtection().getAutoFilter();
+        return isSheetLocked() && safeGetProtectionField().getAutoFilter();
     }
 
     /**
      * @return true when Deleting columns is locked and the sheet is protected.
      */
     public boolean isDeleteColumnsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && worksheet.getSheetProtection().getDeleteColumns();
+        return isSheetLocked() && safeGetProtectionField().getDeleteColumns();
     }
 
     /**
      * @return true when Deleting rows is locked and the sheet is protected.
      */
     public boolean isDeleteRowsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && worksheet.getSheetProtection().getDeleteRows();
+        return isSheetLocked() && safeGetProtectionField().getDeleteRows();
     }
 
     /**
      * @return true when Formatting cells is locked and the sheet is protected.
      */
     public boolean isFormatCellsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && worksheet.getSheetProtection().getFormatCells();
+        return isSheetLocked() && safeGetProtectionField().getFormatCells();
     }
 
     /**
      * @return true when Formatting columns is locked and the sheet is protected.
      */
     public boolean isFormatColumnsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && worksheet.getSheetProtection().getFormatColumns();
+        return isSheetLocked() && safeGetProtectionField().getFormatColumns();
     }
 
     /**
      * @return true when Formatting rows is locked and the sheet is protected.
      */
     public boolean isFormatRowsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && worksheet.getSheetProtection().getFormatRows();
+        return isSheetLocked() && safeGetProtectionField().getFormatRows();
     }
 
     /**
      * @return true when Inserting columns is locked and the sheet is protected.
      */
     public boolean isInsertColumnsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && worksheet.getSheetProtection().getInsertColumns();
+        return isSheetLocked() && safeGetProtectionField().getInsertColumns();
     }
 
     /**
      * @return true when Inserting hyperlinks is locked and the sheet is protected.
      */
     public boolean isInsertHyperlinksLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && worksheet.getSheetProtection().getInsertHyperlinks();
+        return isSheetLocked() && safeGetProtectionField().getInsertHyperlinks();
     }
 
     /**
      * @return true when Inserting rows is locked and the sheet is protected.
      */
     public boolean isInsertRowsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && worksheet.getSheetProtection().getInsertRows();
+        return isSheetLocked() && safeGetProtectionField().getInsertRows();
     }
 
     /**
      * @return true when Pivot tables are locked and the sheet is protected.
      */
     public boolean isPivotTablesLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && worksheet.getSheetProtection().getPivotTables();
+        return isSheetLocked() && safeGetProtectionField().getPivotTables();
     }
 
     /**
      * @return true when Sorting is locked and the sheet is protected.
      */
     public boolean isSortLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && worksheet.getSheetProtection().getSort();
+        return isSheetLocked() && safeGetProtectionField().getSort();
     }
 
     /**
      * @return true when Objects are locked and the sheet is protected.
      */
     public boolean isObjectsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && worksheet.getSheetProtection().getObjects();
+        return isSheetLocked() && safeGetProtectionField().getObjects();
     }
 
     /**
      * @return true when Scenarios are locked and the sheet is protected.
      */
     public boolean isScenariosLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && worksheet.getSheetProtection().getScenarios();
+        return isSheetLocked() && safeGetProtectionField().getScenarios();
     }
 
     /**
      * @return true when Selection of locked cells is locked and the sheet is protected.
      */
     public boolean isSelectLockedCellsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && worksheet.getSheetProtection().getSelectLockedCells();
+        return isSheetLocked() && safeGetProtectionField().getSelectLockedCells();
     }
 
     /**
      * @return true when Selection of unlocked cells is locked and the sheet is protected.
      */
     public boolean isSelectUnlockedCellsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && worksheet.getSheetProtection().getSelectUnlockedCells();
+        return isSheetLocked() && safeGetProtectionField().getSelectUnlockedCells();
     }
 
     /**
      * @return true when Sheet is Protected.
      */
     public boolean isSheetLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && worksheet.getSheetProtection().getSheet();
+        return worksheet.isSetSheetProtection() && safeGetProtectionField().getSheet();
     }
 
     /**
      * Enable sheet protection
      */
     public void enableLocking() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setSheet(true);
+        safeGetProtectionField().setSheet(true);
     }
 
     /**
      * Disable sheet protection
      */
     public void disableLocking() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setSheet(false);
+        safeGetProtectionField().setSheet(false);
     }
 
     /**
      * Enable Autofilters locking.
-     * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * @deprecated use {@link #lockAutoFilter(boolean)}
      */
     public void lockAutoFilter() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setAutoFilter(true);
+        lockAutoFilter(true);
     }
 
     /**
-     * Enable Deleting columns locking.
+     * Enable or disable Autofilters locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link #enableLocking()}
+     */
+    public void lockAutoFilter(boolean enabled) {
+        safeGetProtectionField().setAutoFilter(enabled);
+    }
+
+    /**
+     * Enable Deleting columns locking.
+     * @deprecated use {@link #lockDeleteColumns(boolean)}
      */
     public void lockDeleteColumns() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setDeleteColumns(true);
+        lockDeleteColumns(true);
     }
 
     /**
-     * Enable Deleting rows locking.
+     * Enable or disable Deleting columns locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link #enableLocking()}
+     */
+    public void lockDeleteColumns(boolean enabled) {
+        safeGetProtectionField().setDeleteColumns(enabled);
+    }
+
+    /**
+     * Enable Deleting rows locking.
+     * @deprecated use {@link #lockDeleteRows(boolean)}
      */
     public void lockDeleteRows() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setDeleteRows(true);
+        lockDeleteRows(true);
     }
 
     /**
-     * Enable Formatting cells locking.
+     * Enable or disable Deleting rows locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link #enableLocking()}
+     */
+    public void lockDeleteRows(boolean enabled) {
+        safeGetProtectionField().setDeleteRows(enabled);
+    }
+
+    /**
+     * Enable Formatting cells locking.
+     * @deprecated use {@link #lockFormatCells(boolean)}
      */
     public void lockFormatCells() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setDeleteColumns(true);
+        lockFormatCells(true);
     }
 
     /**
-     * Enable Formatting columns locking.
+     * Enable or disable Formatting cells locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link #enableLocking()}
+     */
+    public void lockFormatCells(boolean enabled) {
+        safeGetProtectionField().setFormatCells(enabled);
+    }
+
+    /**
+     * Enable Formatting columns locking.
+     * @deprecated use {@link #lockFormatColumns(boolean)}
      */
     public void lockFormatColumns() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setFormatColumns(true);
+        lockFormatColumns(true);
     }
 
     /**
-     * Enable Formatting rows locking.
+     * Enable or disable Formatting columns locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link #enableLocking()}
+     */
+    public void lockFormatColumns(boolean enabled) {
+        safeGetProtectionField().setFormatColumns(enabled);
+    }
+
+    /**
+     * Enable Formatting rows locking.
+     * @deprecated use {@link #lockFormatRows(boolean)}
      */
     public void lockFormatRows() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setFormatRows(true);
+        lockFormatRows(true);
     }
 
     /**
-     * Enable Inserting columns locking.
+     * Enable or disable Formatting rows locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link #enableLocking()}
+     */
+    public void lockFormatRows(boolean enabled) {
+        safeGetProtectionField().setFormatRows(enabled);
+    }
+
+    /**
+     * Enable Inserting columns locking.
+     * @deprecated use {@link #lockInsertColumns(boolean)}
      */
     public void lockInsertColumns() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setInsertColumns(true);
+        lockInsertColumns(true);
     }
 
     /**
-     * Enable Inserting hyperlinks locking.
+     * Enable or disable Inserting columns locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link #enableLocking()}
+     */
+    public void lockInsertColumns(boolean enabled) {
+        safeGetProtectionField().setInsertColumns(enabled);
+    }
+
+    /**
+     * Enable Inserting hyperlinks locking.
+     * @deprecated use {@link #lockInsertHyperlinks(boolean)}
      */
     public void lockInsertHyperlinks() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setInsertHyperlinks(true);
+        lockInsertHyperlinks(true);
     }
 
     /**
-     * Enable Inserting rows locking.
+     * Enable or disable Inserting hyperlinks locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link #enableLocking()}
+     */
+    public void lockInsertHyperlinks(boolean enabled) {
+        safeGetProtectionField().setInsertHyperlinks(enabled);
+    }
+
+    /**
+     * Enable Inserting rows locking.
+     * @deprecated use {@link #lockInsertRows(boolean)}
      */
     public void lockInsertRows() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setInsertRows(true);
+        lockInsertRows(true);
     }
 
     /**
-     * Enable Pivot Tables locking.
+     * Enable or disable Inserting rows locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link #enableLocking()}
+     */
+    public void lockInsertRows(boolean enabled) {
+        safeGetProtectionField().setInsertRows(enabled);
+    }
+
+    /**
+     * Enable Pivot Tables locking.
+     * @deprecated use {@link #lockPivotTables(boolean)}
      */
     public void lockPivotTables() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setPivotTables(true);
+        lockPivotTables(true);
     }
 
     /**
-     * Enable Sort locking.
+     * Enable or disable Pivot Tables locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link #enableLocking()}
+     */
+    public void lockPivotTables(boolean enabled) {
+        safeGetProtectionField().setPivotTables(enabled);
+    }
+
+    /**
+     * Enable Sort locking.
+     * @deprecated use {@link #lockSort(boolean)}
      */
     public void lockSort() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setSort(true);
+        lockSort(true);
     }
 
     /**
-     * Enable Objects locking.
+     * Enable or disable Sort locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link #enableLocking()}
+     */
+    public void lockSort(boolean enabled) {
+        safeGetProtectionField().setSort(enabled);
+    }
+
+    /**
+     * Enable Objects locking.
+     * @deprecated use {@link #lockObjects(boolean)}
      */
     public void lockObjects() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setObjects(true);
+        lockObjects(true);
     }
 
     /**
-     * Enable Scenarios locking.
+     * Enable or disable Objects locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link #enableLocking()}
+     */
+    public void lockObjects(boolean enabled) {
+        safeGetProtectionField().setObjects(enabled);
+    }
+
+    /**
+     * Enable Scenarios locking.
+     * @deprecated use {@link #lockScenarios(boolean)}
      */
     public void lockScenarios() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setScenarios(true);
+        lockScenarios(true);
     }
 
     /**
-     * Enable Selection of locked cells locking.
+     * Enable or disable Scenarios locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link #enableLocking()}
+     */
+    public void lockScenarios(boolean enabled) {
+        safeGetProtectionField().setScenarios(enabled);
+    }
+
+    /**
+     * Enable Selection of locked cells locking.
+     * @deprecated use {@link #lockSelectLockedCells(boolean)}
      */
     public void lockSelectLockedCells() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setSelectLockedCells(true);
+        lockSelectLockedCells(true);
     }
 
     /**
-     * Enable Selection of unlocked cells locking.
+     * Enable or disable Selection of locked cells locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link #enableLocking()}
+     */
+    public void lockSelectLockedCells(boolean enabled) {
+        safeGetProtectionField().setSelectLockedCells(enabled);
+    }
+
+    /**
+     * Enable Selection of unlocked cells locking.
+     * @deprecated use {@link #lockSelectUnlockedCells(boolean)}
      */
     public void lockSelectUnlockedCells() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setSelectUnlockedCells(true);
+        lockSelectUnlockedCells(true);
     }
 
-    private void createProtectionFieldIfNotPresent() {
-        if (worksheet.getSheetProtection() == null) {
-            worksheet.setSheetProtection(CTSheetProtection.Factory.newInstance());
+    /**
+     * Enable or disable Selection of unlocked cells locking.
+     * This does not modify sheet protection status.
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link #enableLocking()}
+     */
+    public void lockSelectUnlockedCells(boolean enabled) {
+        safeGetProtectionField().setSelectUnlockedCells(enabled);
+    }
+
+    private CTSheetProtection safeGetProtectionField() {
+        if (!isSheetProtectionEnabled()) {
+            return worksheet.addNewSheetProtection();
         }
+        return worksheet.getSheetProtection();
     }
 
-    private boolean sheetProtectionEnabled() {
-        return worksheet.getSheetProtection().getSheet();
+    /* package */ boolean isSheetProtectionEnabled() {
+        return (worksheet.isSetSheetProtection());
     }
 
     /* package */ boolean isCellInArrayFormulaContext(XSSFCell cell) {
@@ -3403,10 +3510,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      * Returns any tables associated with this Sheet
      */
     public List<XSSFTable> getTables() {
-       List<XSSFTable> tableList = new ArrayList<XSSFTable>(
-             tables.values()
-       );
-       return tableList;
+        return new ArrayList<XSSFTable>(tables.values());
     }
 
     @Override
@@ -3529,21 +3633,20 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         String c = "";
         String r = "";
 
-        if(startC == -1 && endC == -1) {
-        } else {
+        if (startC != -1 || endC != -1) {
           c = escapedName + "!$" + colRef.getCellRefParts()[2]
               + ":$" + colRef2.getCellRefParts()[2];
         }
 
-        if (startR == -1 && endR == -1) {
-
-        } else if (!rowRef.getCellRefParts()[1].equals("0")
-            && !rowRef2.getCellRefParts()[1].equals("0")) {
-           r = escapedName + "!$" + rowRef.getCellRefParts()[1]
-                 + ":$" + rowRef2.getCellRefParts()[1];
+        if (startR != -1 || endR != -1) {
+            if (!rowRef.getCellRefParts()[1].equals("0")
+                && !rowRef2.getCellRefParts()[1].equals("0")) {
+               r = escapedName + "!$" + rowRef.getCellRefParts()[1]
+                     + ":$" + rowRef2.getCellRefParts()[1];
+            }
         }
 
-        StringBuffer rng = new StringBuffer();
+        StringBuilder rng = new StringBuilder();
         rng.append(c);
         if(rng.length() > 0 && r.length() > 0) {
           rng.append(',');
index be812c3dbf6a7e93f24da354c684b6b54a7e867b..8c83f6f164e3b21c93f48bcd1f453e4ea9e8cd85 100644 (file)
 \r
 package org.apache.poi.xssf.usermodel;\r
 \r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.apache.poi.hssf.record.cf.CellRangeUtil;\r
+import org.apache.poi.ss.SpreadsheetVersion;\r
+import org.apache.poi.ss.usermodel.ComparisonOperator;\r
 import org.apache.poi.ss.usermodel.ConditionalFormatting;\r
 import org.apache.poi.ss.usermodel.ConditionalFormattingRule;\r
 import org.apache.poi.ss.usermodel.SheetConditionalFormatting;\r
-import org.apache.poi.ss.usermodel.ComparisonOperator;\r
 import org.apache.poi.ss.util.CellRangeAddress;\r
-import org.apache.poi.ss.SpreadsheetVersion;\r
-import org.apache.poi.hssf.record.cf.CellRangeUtil;\r
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfRule;\r
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCfType;\r
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTConditionalFormatting;\r
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.STConditionalFormattingOperator;\r
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;\r
-\r
-import java.util.List;\r
-import java.util.ArrayList;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCfType;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STConditionalFormattingOperator;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
@@ -115,6 +115,7 @@ public class XSSFSheetConditionalFormatting implements SheetConditionalFormattin
         return rule;\r
     }\r
 \r
+    @SuppressWarnings("deprecation")\r
     public int addConditionalFormatting(CellRangeAddress[] regions, ConditionalFormattingRule[] cfRules) {\r
         if (regions == null) {\r
             throw new IllegalArgumentException("regions must not be null");\r
@@ -130,21 +131,15 @@ public class XSSFSheetConditionalFormatting implements SheetConditionalFormattin
         if (cfRules.length > 3) {\r
             throw new IllegalArgumentException("Number of rules must not exceed 3");\r
         }\r
-        XSSFConditionalFormattingRule[] hfRules;\r
-        if(cfRules instanceof XSSFConditionalFormattingRule[]) hfRules = (XSSFConditionalFormattingRule[])cfRules;\r
-        else {\r
-            hfRules = new XSSFConditionalFormattingRule[cfRules.length];\r
-            System.arraycopy(cfRules, 0, hfRules, 0, hfRules.length);\r
-        }\r
+\r
         CellRangeAddress[] mergeCellRanges = CellRangeUtil.mergeCellRanges(regions);\r
         CTConditionalFormatting cf = _sheet.getCTWorksheet().addNewConditionalFormatting();\r
         List<String> refs = new ArrayList<String>();\r
         for(CellRangeAddress a : mergeCellRanges) refs.add(a.formatAsString());\r
         cf.setSqref(refs);\r
 \r
-\r
         int priority = 1;\r
-        for(CTConditionalFormatting c : _sheet.getCTWorksheet().getConditionalFormattingList()){\r
+        for(CTConditionalFormatting c : _sheet.getCTWorksheet().getConditionalFormattingArray()){\r
             priority += c.sizeOfCfRuleArray();\r
         }\r
 \r
@@ -220,7 +215,7 @@ public class XSSFSheetConditionalFormatting implements SheetConditionalFormattin
     */\r
     public void removeConditionalFormatting(int index) {\r
         checkIndex(index);\r
-        _sheet.getCTWorksheet().getConditionalFormattingList().remove(index);\r
+        _sheet.getCTWorksheet().removeConditionalFormatting(index);\r
     }\r
 \r
     private void checkIndex(int index) {\r
index ed1d9a27c54d909349b3f1b247c2070e3818e420..d228cf9519e3466e63e3fd235c8dd0a8f0582cba 100644 (file)
@@ -128,13 +128,14 @@ public class XSSFTable extends POIXMLDocumentPart {
         * 
         * @return the xpath of the table's root element
         */
+    @SuppressWarnings("deprecation")
        public String getCommonXpath() {
                
                if(commonXPath == null){
                
                String[] commonTokens ={};
                
-               for(CTTableColumn column :ctTable.getTableColumns().getTableColumnList()){
+               for(CTTableColumn column :ctTable.getTableColumns().getTableColumnArray()){
                        if(column.getXmlColumnPr()!=null){
                                String xpath = column.getXmlColumnPr().getXpath();
                                String[] tokens =  xpath.split("/");
@@ -173,11 +174,12 @@ public class XSSFTable extends POIXMLDocumentPart {
        }
 
        
+    @SuppressWarnings("deprecation")
        public List<XSSFXmlColumnPr> getXmlColumnPrs() {
                
                if(xmlColumnPr==null){
                        xmlColumnPr = new ArrayList<XSSFXmlColumnPr>();
-                       for (CTTableColumn column:ctTable.getTableColumns().getTableColumnList()){
+                       for (CTTableColumn column:ctTable.getTableColumns().getTableColumnArray()){
                                if (column.getXmlColumnPr()!=null){
                                        XSSFXmlColumnPr columnPr = new XSSFXmlColumnPr(this,column,column.getXmlColumnPr());
                                        xmlColumnPr.add(columnPr);
@@ -285,6 +287,7 @@ public class XSSFTable extends POIXMLDocumentPart {
      * Headers <em>must</em> be in sync, otherwise Excel will display a
      * "Found unreadable content" message on startup.
      */
+    @SuppressWarnings("deprecation")
     public void updateHeaders(){
         XSSFSheet sheet = (XSSFSheet)getParent();
         CellReference ref = getStartCellReference();
@@ -296,7 +299,7 @@ public class XSSFTable extends POIXMLDocumentPart {
 
         if (row != null && row.getCTRow().validate()) {
             int cellnum = firstHeaderColumn;
-            for (CTTableColumn col : getCTTable().getTableColumns().getTableColumnList()) {
+            for (CTTableColumn col : getCTTable().getTableColumns().getTableColumnArray()) {
                 XSSFCell cell = row.getCell(cellnum);
                 if (cell != null) {
                     col.setName(cell.getStringCellValue());
index 60e1ea415ebd696e5615baa0a9bf3d44bf911764..a51b40675f064740211e58e7b2e25a344baccff6 100644 (file)
@@ -17,6 +17,9 @@
 
 package org.apache.poi.xssf.usermodel;
 
+import static org.apache.poi.xssf.usermodel.helpers.XSSFPaswordHelper.setPassword;
+import static org.apache.poi.xssf.usermodel.helpers.XSSFPaswordHelper.validatePassword;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -47,6 +50,7 @@ import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
 import org.apache.poi.openxml4j.opc.PackagingURIHelper;
 import org.apache.poi.openxml4j.opc.TargetMode;
+import org.apache.poi.poifs.crypt.HashAlgorithm;
 import org.apache.poi.ss.formula.SheetNameFormatter;
 import org.apache.poi.ss.formula.udf.IndexedUDFFinder;
 import org.apache.poi.ss.formula.udf.UDFFinder;
@@ -1366,6 +1370,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
      * @param pos the position that we want to insert the sheet into (0 based)
      */
     @Override
+    @SuppressWarnings("deprecation")
     public void setSheetOrder(String sheetname, int pos) {
         int idx = getSheetIndex(sheetname);
         sheets.add(pos, sheets.remove(idx));
@@ -1377,8 +1382,9 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
         newcts.set(cts);
 
         //notify sheets
-        for(int i=0; i < sheets.size(); i++) {
-            sheets.get(i).sheet = ct.getSheetArray(i);
+        CTSheet[] sheetArray = ct.getSheetArray();
+        for(int i=0; i < sheetArray.length; i++) {
+            sheets.get(i).sheet = sheetArray[i];
         }
     }
 
@@ -1410,10 +1416,11 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
         }
     }
     
+    @SuppressWarnings("deprecation")
     private void reprocessNamedRanges() {
         namedRanges = new ArrayList<XSSFName>();
         if(workbook.isSetDefinedNames()) {
-            for(CTDefinedName ctName : workbook.getDefinedNames().getDefinedNameList()) {
+            for(CTDefinedName ctName : workbook.getDefinedNames().getDefinedNameArray()) {
                 namedRanges.add(new XSSFName(ctName, this));
             }
         }
@@ -1735,60 +1742,108 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
         * Locks the structure of workbook.
         */
        public void lockStructure() {
-               createProtectionFieldIfNotPresent();
-               workbook.getWorkbookProtection().setLockStructure(true);
+           safeGetWorkbookProtection().setLockStructure(true);
        }
 
        /**
         * Unlocks the structure of workbook.
         */
        public void unLockStructure() {
-               createProtectionFieldIfNotPresent();
-               workbook.getWorkbookProtection().setLockStructure(false);
+           safeGetWorkbookProtection().setLockStructure(false);
        }
 
        /**
         * Locks the windows that comprise the workbook.
         */
        public void lockWindows() {
-               createProtectionFieldIfNotPresent();
-               workbook.getWorkbookProtection().setLockWindows(true);
+           safeGetWorkbookProtection().setLockWindows(true);
        }
 
        /**
         * Unlocks the windows that comprise the workbook.
         */
        public void unLockWindows() {
-               createProtectionFieldIfNotPresent();
-               workbook.getWorkbookProtection().setLockWindows(false);
+           safeGetWorkbookProtection().setLockWindows(false);
        }
 
        /**
         * Locks the workbook for revisions.
         */
        public void lockRevision() {
-               createProtectionFieldIfNotPresent();
-               workbook.getWorkbookProtection().setLockRevision(true);
+           safeGetWorkbookProtection().setLockRevision(true);
        }
 
        /**
         * Unlocks the workbook for revisions.
         */
        public void unLockRevision() {
-               createProtectionFieldIfNotPresent();
-               workbook.getWorkbookProtection().setLockRevision(false);
+           safeGetWorkbookProtection().setLockRevision(false);
        }
 
-       private boolean workbookProtectionPresent() {
-               return workbook.getWorkbookProtection() != null;
+       /**
+        * Sets the workbook password. 
+        * 
+        * @param password if null, the password will be removed
+        * @param hashAlgo if null, the password will be set as XOR password (Excel 2010 and earlier)
+        *  otherwise the given algorithm is used for calculating the hash password (Excel 2013)
+        */
+       public void setWorkbookPassword(String password, HashAlgorithm hashAlgo) {
+        if (password == null && !workbookProtectionPresent()) return;
+        setPassword(safeGetWorkbookProtection(), password, hashAlgo, "workbook");
        }
 
-       private void createProtectionFieldIfNotPresent() {
-               if (workbook.getWorkbookProtection() == null){
-                       workbook.setWorkbookProtection(CTWorkbookProtection.Factory.newInstance());
-               }
+    /**
+     * Validate the password against the stored hash, the hashing method will be determined
+     *  by the existing password attributes
+     * @return true, if the hashes match (... though original password may differ ...)
+     */
+    public boolean validateWorkbookPassword(String password) {
+        if (!workbookProtectionPresent()) return (password == null);
+        return validatePassword(safeGetWorkbookProtection(), password, "workbook");
+    }
+
+    /**
+     * Sets the revisions password.
+     * 
+     * @param password if null, the password will be removed
+     * @param hashAlgo if null, the password will be set as XOR password (Excel 2010 and earlier)
+     *  otherwise the given algorithm is used for calculating the hash password (Excel 2013)
+     */
+    public void setRevisionsPassword(String password, HashAlgorithm hashAlgo) {
+        if (password == null && !workbookProtectionPresent()) return;
+        setPassword(safeGetWorkbookProtection(), password, hashAlgo, "revisions");
+    }
+
+    /**
+     * Validate the password against the stored hash, the hashing method will be determined
+     *  by the existing password attributes
+     * @return true if the hashes match (... though original password may differ ...)
+     */
+    public boolean validateRevisionsPassword(String password) {
+        if (!workbookProtectionPresent()) return (password == null);
+        return validatePassword(safeGetWorkbookProtection(), password, "revisions");
+    }
+    
+    /**
+     * Removes the workbook protection settings
+     */
+    public void unLock() {
+        if (workbookProtectionPresent()) {
+            workbook.unsetWorkbookProtection();
+        }
+    }
+    
+       private boolean workbookProtectionPresent() {
+               return workbook.isSetWorkbookProtection();
        }
 
+    private CTWorkbookProtection safeGetWorkbookProtection() {
+        if (!workbookProtectionPresent()){
+            return workbook.addNewWorkbookProtection();
+        }
+        return workbook.getWorkbookProtection();
+    }
+       
     /**
      *
      * Returns the locator of user-defined functions.
index 41beb6f2593adc8ece5bc8b80210552d96a85920..74d9ef3994eb89bac1f3e90e787aaa5bbecb513b 100644 (file)
@@ -19,7 +19,6 @@ package org.apache.poi.xssf.usermodel.helpers;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -50,52 +49,39 @@ public class ColumnHelper {
         cleanColumns();
     }
     
+    @SuppressWarnings("deprecation")
     public void cleanColumns() {
         this.newCols = CTCols.Factory.newInstance();
 
         CTCols aggregateCols = CTCols.Factory.newInstance();
-        List<CTCols> colsList = worksheet.getColsList();
-        assert(colsList != null);
+        CTCols[] colsArray = worksheet.getColsArray();
+        assert(colsArray != null);
         
-        for (CTCols cols : colsList) {
-            for (CTCol col : cols.getColList()) {
+        for (CTCols cols : colsArray) {
+            for (CTCol col : cols.getColArray()) {
                 cloneCol(aggregateCols, col);
             }
         }
         
         sortColumns(aggregateCols);
         
-        CTCol[] colArray = new CTCol[aggregateCols.getColList().size()];
-        aggregateCols.getColList().toArray(colArray);
+        CTCol[] colArray = aggregateCols.getColArray();
         sweepCleanColumns(newCols, colArray, null);
         
-        int i = colsList.size();
+        int i = colsArray.length;
         for (int y = i - 1; y >= 0; y--) {
             worksheet.removeCols(y);
         }
         worksheet.addNewCols();
         worksheet.setColsArray(0, newCols);
     }
-    
-    private static class CTColByMaxComparator implements Comparator<CTCol> {
-
-        public int compare(CTCol arg0, CTCol arg1) {
-            if (arg0.getMax() < arg1.getMax()) {
-                return -1;
-            } else {
-                if (arg0.getMax() > arg1.getMax()) return 1;
-                else return 0;
-            }
-        }
-        
-    }
 
     /**
      * @see <a href="http://en.wikipedia.org/wiki/Sweep_line_algorithm">Sweep line algorithm</a>
      */
     private void sweepCleanColumns(CTCols cols, CTCol[] flattenedColsArray, CTCol overrideColumn) {
         List<CTCol> flattenedCols = new ArrayList<CTCol>(Arrays.asList(flattenedColsArray));
-        TreeSet<CTCol> currentElements = new TreeSet<CTCol>(new CTColByMaxComparator());
+        TreeSet<CTCol> currentElements = new TreeSet<CTCol>(CTColComparator.BY_MAX);
         ListIterator<CTCol> flIter = flattenedCols.listIterator();
         CTCol haveOverrideColumn = null;
         long lastMaxIndex = 0;
@@ -103,7 +89,8 @@ public class ColumnHelper {
         while (flIter.hasNext()) {
             CTCol col = flIter.next();
             long currentIndex = col.getMin();
-            long nextIndex = (col.getMax() > currentMax) ? col.getMax() : currentMax;
+            long colMax = col.getMax();
+            long nextIndex = (colMax > currentMax) ? colMax : currentMax;
             if (flIter.hasNext()) {
                 nextIndex = flIter.next().getMin();
                 flIter.previous();
@@ -116,10 +103,10 @@ public class ColumnHelper {
             }
             if (!currentElements.isEmpty() && lastMaxIndex < currentIndex) {
                 // we need to process previous elements first
-                insertCol(cols, lastMaxIndex, currentIndex - 1, currentElements.toArray(new CTCol[]{}), true, haveOverrideColumn);
+                insertCol(cols, lastMaxIndex, currentIndex - 1, currentElements.toArray(new CTCol[currentElements.size()]), true, haveOverrideColumn);
             }
             currentElements.add(col);
-            if (col.getMax() > currentMax) currentMax = col.getMax();
+            if (colMax > currentMax) currentMax = colMax;
             if (col.equals(overrideColumn)) haveOverrideColumn = overrideColumn;
             while (currentIndex <= nextIndex && !currentElements.isEmpty()) {
                 Set<CTCol> currentIndexElements = new HashSet<CTCol>();
@@ -130,26 +117,21 @@ public class ColumnHelper {
                     CTCol currentElem = currentElements.first();
                     currentElemIndex = currentElem.getMax();
                     currentIndexElements.add(currentElem);
-                    
-                    for (CTCol cc : currentElements.tailSet(currentElem)) {
-                        if (cc == null || cc.getMax() == currentElemIndex) break;
-                        currentIndexElements.add(cc);
-                        if (col.getMax() > currentMax) currentMax = col.getMax();
+
+                    while (true) {
+                        CTCol higherElem = currentElements.higher(currentElem);
+                        if (higherElem == null || higherElem.getMax() != currentElemIndex)
+                            break;
+                        currentElem = higherElem;
+                        currentIndexElements.add(currentElem);
+                        if (colMax > currentMax) currentMax = colMax;
                         if (col.equals(overrideColumn)) haveOverrideColumn = overrideColumn;
                     }
-
-                    // JDK 6 code
-                    // while (currentElements.higher(currentElem) != null && currentElements.higher(currentElem).getMax() == currentElemIndex) {
-                    //     currentElem = currentElements.higher(currentElem);
-                    //     currentIndexElements.add(currentElem);
-                    //     if (col.getMax() > currentMax) currentMax = col.getMax();
-                    //     if (col.equals(overrideColumn)) haveOverrideColumn = overrideColumn;
-                    // }
                 }
                 
                 
                 if (currentElemIndex < nextIndex || !flIter.hasNext()) {
-                    insertCol(cols, currentIndex, currentElemIndex, currentElements.toArray(new CTCol[]{}), true, haveOverrideColumn);
+                    insertCol(cols, currentIndex, currentElemIndex, currentElements.toArray(new CTCol[currentElements.size()]), true, haveOverrideColumn);
                     if (flIter.hasNext()) {
                         if (nextIndex > currentElemIndex) {
                             currentElements.removeAll(currentIndexElements);
@@ -170,10 +152,10 @@ public class ColumnHelper {
         sortColumns(cols);
     }
 
+    @SuppressWarnings("deprecation")
     public static void sortColumns(CTCols newCols) {
-        CTCol[] colArray = new CTCol[newCols.getColList().size()];
-        newCols.getColList().toArray(colArray);
-        Arrays.sort(colArray, new CTColComparator());
+        CTCol[] colArray = newCols.getColArray();
+        Arrays.sort(colArray, CTColComparator.BY_MIN_MAX);
         newCols.setColArray(colArray);
     }
 
@@ -198,46 +180,46 @@ public class ColumnHelper {
      *  as 1 based.
      */
     public CTCol getColumn1Based(long index1, boolean splitColumns) {
-        CTCols colsArray = worksheet.getColsArray(0);
+        CTCols cols = worksheet.getColsArray(0);
         
         // Fetching the array is quicker than working on the new style
         //  list, assuming we need to read many of them (which we often do),
         //  and assuming we're not making many changes (which we're not)
         @SuppressWarnings("deprecation")
-        CTCol[] cols = colsArray.getColArray();
-        
-        for (int i = 0; i < cols.length; i++) {
-            CTCol colArray = cols[i];
-            if (colArray.getMin() <= index1 && colArray.getMax() >= index1) {
+        CTCol[] colArray = cols.getColArray();
+
+        for (CTCol col : colArray) {
+            long colMin = col.getMin();
+            long colMax = col.getMax();
+            if (colMin <= index1 && colMax >= index1) {
                 if (splitColumns) {
-                    if (colArray.getMin() < index1) {
-                        insertCol(colsArray, colArray.getMin(), (index1 - 1), new CTCol[]{colArray});
+                    if (colMin < index1) {
+                        insertCol(cols, colMin, (index1 - 1), new CTCol[]{col});
                     }
-                    if (colArray.getMax() > index1) {
-                        insertCol(colsArray, (index1 + 1), colArray.getMax(), new CTCol[]{colArray});
+                    if (colMax > index1) {
+                        insertCol(cols, (index1 + 1), colMax, new CTCol[]{col});
                     }
-                    colArray.setMin(index1);
-                    colArray.setMax(index1);
+                    col.setMin(index1);
+                    col.setMax(index1);
                 }
-                return colArray;
+                return col;
             }
         }
         return null;
     }
-    
+
+    @SuppressWarnings("deprecation")
     public CTCols addCleanColIntoCols(CTCols cols, CTCol col) {
         CTCols newCols = CTCols.Factory.newInstance();
-        for (CTCol c : cols.getColList()) {
+        for (CTCol c : cols.getColArray()) {
             cloneCol(newCols, c);
         }
         cloneCol(newCols, col);
         sortColumns(newCols);
-        CTCol[] colArray = new CTCol[newCols.getColList().size()];
-        newCols.getColList().toArray(colArray);
+        CTCol[] colArray = newCols.getColArray();
         CTCols returnCols = CTCols.Factory.newInstance();
         sweepCleanColumns(returnCols, colArray, col);
-        colArray = new CTCol[returnCols.getColList().size()];
-        returnCols.getColList().toArray(colArray);
+        colArray = returnCols.getColArray();
         cols.setColArray(colArray);
         return returnCols;
     }
@@ -272,9 +254,11 @@ public class ColumnHelper {
     public boolean columnExists(CTCols cols, long index) {
         return columnExists1Based(cols, index+1);
     }
+
+    @SuppressWarnings("deprecation")
     private boolean columnExists1Based(CTCols cols, long index1) {
-        for (int i = 0; i < cols.sizeOfColArray(); i++) {
-            if (cols.getColArray(i).getMin() == index1) {
+        for (CTCol col : cols.getColArray()) {
+            if (col.getMin() == index1) {
                 return true;
             }
         }
@@ -343,20 +327,24 @@ public class ColumnHelper {
         return -1;
     }
 
+    @SuppressWarnings("deprecation")
     private boolean columnExists(CTCols cols, long min, long max) {
-        for (int i = 0; i < cols.sizeOfColArray(); i++) {
-            if (cols.getColArray(i).getMin() == min && cols.getColArray(i).getMax() == max) {
+        for (CTCol col : cols.getColArray()) {
+            if (col.getMin() == min && col.getMax() == max) {
                 return true;
             }
         }
         return false;
     }
-    
-    public int getIndexOfColumn(CTCols cols, CTCol col) {
-        for (int i = 0; i < cols.sizeOfColArray(); i++) {
-            if (cols.getColArray(i).getMin() == col.getMin() && cols.getColArray(i).getMax() == col.getMax()) {
+
+    @SuppressWarnings("deprecation")
+    public int getIndexOfColumn(CTCols cols, CTCol searchCol) {
+        int i = 0;
+        for (CTCol col : cols.getColArray()) {
+            if (col.getMin() == searchCol.getMin() && col.getMax() == searchCol.getMax()) {
                 return i;
             }
+            i++;
         }
         return -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
new file mode 100644 (file)
index 0000000..c887129
--- /dev/null
@@ -0,0 +1,128 @@
+/*\r
+ *  ====================================================================\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ====================================================================\r
+ */\r
+\r
+package org.apache.poi.xssf.usermodel.helpers;\r
+\r
+import java.security.SecureRandom;\r
+import java.util.Arrays;\r
+\r
+import javax.xml.bind.DatatypeConverter;\r
+import javax.xml.namespace.QName;\r
+\r
+import org.apache.poi.poifs.crypt.CryptoFunctions;\r
+import org.apache.poi.poifs.crypt.HashAlgorithm;\r
+import org.apache.xmlbeans.XmlCursor;\r
+import org.apache.xmlbeans.XmlObject;\r
+\r
+public class XSSFPaswordHelper {\r
+    /**\r
+     * Sets the XORed or hashed password \r
+     *\r
+     * @param xobj the xmlbeans object which contains the password attributes\r
+     * @param password the password, if null, the password attributes will be removed\r
+     * @param hashAlgo the hash algorithm, if null the password will be XORed\r
+     * @param prefix the prefix of the password attributes, may be null\r
+     */\r
+    public static void setPassword(XmlObject xobj, String password, HashAlgorithm hashAlgo, String prefix) {\r
+        XmlCursor cur = xobj.newCursor();\r
+\r
+        if (password == null) {\r
+            cur.removeAttribute(getAttrName(prefix, "password"));\r
+            cur.removeAttribute(getAttrName(prefix, "algorithmName"));\r
+            cur.removeAttribute(getAttrName(prefix, "hashValue"));\r
+            cur.removeAttribute(getAttrName(prefix, "saltValue"));\r
+            cur.removeAttribute(getAttrName(prefix, "spinCount"));\r
+            return;\r
+        } \r
+        \r
+        cur.toFirstContentToken();\r
+        if (hashAlgo == null) {\r
+            int hash = CryptoFunctions.createXorVerifier1(password);\r
+            cur.insertAttributeWithValue(getAttrName(prefix, "password"), Integer.toHexString(hash).toUpperCase());\r
+        } else {\r
+            SecureRandom random = new SecureRandom(); \r
+            byte salt[] = random.generateSeed(16);\r
+    \r
+            // Iterations specifies the number of times the hashing function shall be iteratively run (using each\r
+            // iteration's result as the input for the next iteration).\r
+            int spinCount = 100000;\r
+\r
+            // Implementation Notes List:\r
+            // --> In this third stage, the reversed byte order legacy hash from the second stage shall\r
+            //     be converted to Unicode hex string representation\r
+            byte hash[] = CryptoFunctions.hashPassword(password, hashAlgo, salt, spinCount, false);\r
+            \r
+            cur.insertAttributeWithValue(getAttrName(prefix, "algorithmName"), hashAlgo.jceId); \r
+            cur.insertAttributeWithValue(getAttrName(prefix, "hashValue"), DatatypeConverter.printBase64Binary(hash));\r
+            cur.insertAttributeWithValue(getAttrName(prefix, "saltValue"), DatatypeConverter.printBase64Binary(salt));\r
+            cur.insertAttributeWithValue(getAttrName(prefix, "spinCount"), ""+spinCount);\r
+        }\r
+        cur.dispose();\r
+    }\r
+\r
+    /**\r
+     * Validates the password, i.e.\r
+     * calculates the hash of the given password and compares it against the stored hash\r
+     *\r
+     * @param xobj the xmlbeans object which contains the password attributes\r
+     * @param password the password, if null the method will always return false,\r
+     *  even if there's no password set\r
+     * @param prefix the prefix of the password attributes, may be null\r
+     * \r
+     * @return true, if the hashes match\r
+     */\r
+    public static boolean validatePassword(XmlObject xobj, String password, String prefix) {\r
+        // TODO: is "velvetSweatshop" the default password?\r
+        if (password == null) return false;\r
+        \r
+        XmlCursor cur = xobj.newCursor();\r
+        String xorHashVal = cur.getAttributeText(getAttrName(prefix, "password"));\r
+        String algoName = cur.getAttributeText(getAttrName(prefix, "algorithmName"));\r
+        String hashVal = cur.getAttributeText(getAttrName(prefix, "hashValue"));\r
+        String saltVal = cur.getAttributeText(getAttrName(prefix, "saltValue"));\r
+        String spinCount = cur.getAttributeText(getAttrName(prefix, "spinCount"));\r
+        cur.dispose();\r
+\r
+        if (xorHashVal != null) {\r
+            int hash1 = Integer.parseInt(xorHashVal, 16);\r
+            int hash2 = CryptoFunctions.createXorVerifier1(password);\r
+            return hash1 == hash2;\r
+        } else {\r
+            if (hashVal == null || algoName == null || saltVal == null || spinCount == null) {\r
+                return false;\r
+            }\r
+            \r
+            byte hash1[] = DatatypeConverter.parseBase64Binary(hashVal);\r
+            HashAlgorithm hashAlgo = HashAlgorithm.fromString(algoName);\r
+            byte salt[] = DatatypeConverter.parseBase64Binary(saltVal);\r
+            int spinCnt = Integer.parseInt(spinCount);\r
+            byte hash2[] = CryptoFunctions.hashPassword(password, hashAlgo, salt, spinCnt, false);\r
+            return Arrays.equals(hash1, hash2);\r
+        }\r
+    }\r
+    \r
+    \r
+    private static QName getAttrName(String prefix, String name) {\r
+        if (prefix == null || "".equals(prefix)) {\r
+            return new QName(name);\r
+        } else {\r
+            return new QName(prefix+Character.toUpperCase(name.charAt(0))+name.substring(1));\r
+        }\r
+    }\r
+}\r
index 1b51568867c0ade9983c0da6ec16451387988814..cfa0a77771ae8e2ad6729b8df30b0528ee9f1ef9 100644 (file)
@@ -18,7 +18,9 @@
 package org.apache.poi.xssf.usermodel.helpers;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.poi.ss.formula.FormulaParseException;
 import org.apache.poi.ss.formula.FormulaParser;
@@ -43,6 +45,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfRule;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTConditionalFormatting;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType;
 
 /**
@@ -66,8 +69,10 @@ public final class XSSFRowShifter {
      */
     public List<CellRangeAddress> shiftMerged(int startRow, int endRow, int n) {
         List<CellRangeAddress> shiftedRegions = new ArrayList<CellRangeAddress>();
+        Set<Integer> removedIndices = new HashSet<Integer>();
         //move merged regions completely if they fall within the new region boundaries when they are shifted
-        for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
+        int size = sheet.getNumMergedRegions();
+        for (int i = 0; i < size; i++) {
             CellRangeAddress merged = sheet.getMergedRegion(i);
 
             boolean inStart = (merged.getFirstRow() >= startRow || merged.getLastRow() >= startRow);
@@ -84,10 +89,13 @@ public final class XSSFRowShifter {
                 merged.setLastRow(merged.getLastRow() + n);
                 //have to remove/add it back
                 shiftedRegions.add(merged);
-                sheet.removeMergedRegion(i);
-                i = i - 1; // we have to back up now since we removed one
+                removedIndices.add(i);
             }
         }
+        
+        if(!removedIndices.isEmpty()) {
+            sheet.removeMergedRegions(removedIndices);
+        }
 
         //read so it doesn't get shifted again
         for (CellRangeAddress region : shiftedRegions) {
@@ -213,28 +221,29 @@ public final class XSSFRowShifter {
         }
     }
 
+    @SuppressWarnings("deprecation")
     public void updateConditionalFormatting(FormulaShifter shifter) {
         XSSFWorkbook wb = sheet.getWorkbook();
         int sheetIndex = wb.getSheetIndex(sheet);
 
-
         XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
-        List<CTConditionalFormatting> cfList = sheet.getCTWorksheet().getConditionalFormattingList();
-        for(int j = 0; j< cfList.size(); j++){
-            CTConditionalFormatting cf = cfList.get(j);
+        CTWorksheet ctWorksheet = sheet.getCTWorksheet();
+        CTConditionalFormatting[] conditionalFormattingArray = ctWorksheet.getConditionalFormattingArray();
+        // iterate backwards due to possible calls to ctWorksheet.removeConditionalFormatting(j)
+        for (int j = conditionalFormattingArray.length - 1; j >= 0; j--) {
+            CTConditionalFormatting cf = conditionalFormattingArray[j];
 
             ArrayList<CellRangeAddress> cellRanges = new ArrayList<CellRangeAddress>();
             for (Object stRef : cf.getSqref()) {
                 String[] regions = stRef.toString().split(" ");
-                for (int i = 0; i < regions.length; i++) {
-                    cellRanges.add(CellRangeAddress.valueOf(regions[i]));
+                for (String region : regions) {
+                    cellRanges.add(CellRangeAddress.valueOf(region));
                 }
             }
 
             boolean changed = false;
             List<CellRangeAddress> temp = new ArrayList<CellRangeAddress>();
-            for (int i = 0; i < cellRanges.size(); i++) {
-                CellRangeAddress craOld = cellRanges.get(i);
+            for (CellRangeAddress craOld : cellRanges) {
                 CellRangeAddress craNew = shiftRange(shifter, craOld, sheetIndex);
                 if (craNew == null) {
                     changed = true;
@@ -249,7 +258,7 @@ public final class XSSFRowShifter {
             if (changed) {
                 int nRanges = temp.size();
                 if (nRanges == 0) {
-                    cfList.remove(j);
+                    ctWorksheet.removeConditionalFormatting(j);
                     continue;
                 }
                 List<String> refs = new ArrayList<String>();
@@ -257,14 +266,14 @@ public final class XSSFRowShifter {
                 cf.setSqref(refs);
             }
 
-            for(CTCfRule cfRule : cf.getCfRuleList()){
-                List<String> formulas = cfRule.getFormulaList();
-                for (int i = 0; i < formulas.size(); i++) {
-                    String formula = formulas.get(i);
+            for(CTCfRule cfRule : cf.getCfRuleArray()){
+                String[] formulaArray = cfRule.getFormulaArray();
+                for (int i = 0; i < formulaArray.length; i++) {
+                    String formula = formulaArray[i];
                     Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex);
                     if (shifter.adjustFormula(ptgs, sheetIndex)) {
                         String shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs);
-                        formulas.set(i, shiftedFmla);
+                        cfRule.setFormulaArray(i, shiftedFmla);
                     }
                 }
             }
index 50d5c8f9f7835ecb170f884de9e92b34dc836c0c..5368eb0e6e931350423b7f488c4f37e8eed91e8f 100644 (file)
@@ -21,26 +21,26 @@ import java.util.Comparator;
 
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol;
 
-public class CTColComparator implements Comparator<CTCol>{
+public class CTColComparator {
 
-    public int compare(CTCol o1, CTCol o2) {
-        if (o1.getMin() < o2.getMin()) {
-            return -1;
-        }
-        else if (o1.getMin() > o2.getMin()) {
-            return 1;
+    private CTColComparator() {}
+
+    public static final Comparator<CTCol> BY_MAX = new Comparator<CTCol>() {
+        @Override
+        public int compare(CTCol col1, CTCol col2) {
+            long col1max = col1.getMax();
+            long col2max = col2.getMax();
+            return col1max < col2max ? -1 : col1max > col2max ? 1 : 0;
         }
-        else {
-            if (o1.getMax() < o2.getMax()) {
-                return -1;
-            }
-            if (o1.getMax() > o2.getMax()) {
-                return 1;
-            }
-            return 0;
+    };
+
+    public static final Comparator<CTCol> BY_MIN_MAX = new Comparator<CTCol>() {
+        @Override
+        public int compare(CTCol col1, CTCol col2) {
+            long col11min = col1.getMin();
+            long col2min = col2.getMin();
+            return col11min < col2min ? -1 : col11min > col2min ? 1 : BY_MAX.compare(col1, col2);
         }
-    }
-    
-    
-    
+    };
+
 }
index be7bf0408e0bcfead42a806bcbdd7b6609816544..502a3b7861fab2caa0916173242a102082831c0a 100644 (file)
@@ -33,13 +33,15 @@ public class XWPFCommentsDecorator extends XWPFParagraphDecorator {
        public XWPFCommentsDecorator(XWPFParagraphDecorator nextDecorator) {
                this(nextDecorator.paragraph, nextDecorator);
        }
+
+       @SuppressWarnings("deprecation")
        public XWPFCommentsDecorator(XWPFParagraph paragraph, XWPFParagraphDecorator nextDecorator) {
                super(paragraph, nextDecorator);
 
                XWPFComment comment;
                commentText = new StringBuffer();
 
-               for(CTMarkupRange anchor : paragraph.getCTP().getCommentRangeStartList())
+               for(CTMarkupRange anchor : paragraph.getCTP().getCommentRangeStartArray())
                {
                        if((comment = paragraph.getDocument().getCommentByID(anchor.getId().toString())) != null)
                                commentText.append("\tComment by " + comment.getAuthor()+": "+comment.getText());
index 628ff37c94de22a8076766d51703ca5f17b31605..d8120340f565138a4b0bd7caa3b53219bda72651 100644 (file)
@@ -52,10 +52,10 @@ public class XWPFHyperlinkDecorator extends XWPFParagraphDecorator {
                hyperlinkText = new StringBuffer();
                
                // loop over hyperlink anchors
-               for(CTHyperlink link : paragraph.getCTP().getHyperlinkList()){
-                       for (CTR r : link.getRList()) {
+               for(CTHyperlink link : paragraph.getCTP().getHyperlinkArray()){
+                       for (CTR r : link.getRArray()) {
                                // Loop over text runs
-                               for (CTText text : r.getTList()){
+                               for (CTText text : r.getTArray()){
                                        hyperlinkText.append(text.getStringValue());
                                }
                        }
index 9c668e8453b2b52e780ec7bb213c3b6cd523cbb9..e69b0244e73b45a568cf9edddb987288a7878dda 100644 (file)
@@ -35,17 +35,18 @@ public abstract class AbstractXWPFSDT implements ISDTContents {
    private final String tag;
    private final IBody part;
 
+   @SuppressWarnings("deprecation")
    public AbstractXWPFSDT(CTSdtPr pr, IBody part){
        
-       List<CTString> aliases = pr.getAliasList();
-       if (aliases != null && aliases.size() > 0){
-          title = aliases.get(0).getVal();
+       CTString[] aliases = pr.getAliasArray();
+       if (aliases != null && aliases.length > 0){
+          title = aliases[0].getVal();
        } else {
           title = "";
        }
-       List<CTString> tags = pr.getTagList();
-       if (tags != null && tags.size() > 0){
-          tag = tags.get(0).getVal();
+       CTString[] tags = pr.getTagArray();
+       if (tags != null && tags.length > 0){
+          tag = tags[0].getVal();
        } else {
           tag = "";
        }
index d193983c7918468209b8561cc08b65cb29aa811a..84ebc36bb1d79b8b7b689fd7d3316ca07ca90efb 100644 (file)
@@ -31,13 +31,14 @@ public class XWPFComment
     protected String author;
     protected StringBuffer text;
     
+    @SuppressWarnings("deprecation")
     public XWPFComment(CTComment comment, XWPFDocument document)
     {
         text = new StringBuffer();
         id = comment.getId().toString();
         author = comment.getAuthor();
         
-        for(CTP ctp : comment.getPList())
+        for(CTP ctp : comment.getPArray())
         {
             XWPFParagraph p = new XWPFParagraph(ctp, document);
             text.append(p.getText());
index 568681dee4ed076c84b3c2d221560440eeca905b..9adc397048c839e08265265ff747aa492e545552 100644 (file)
@@ -184,7 +184,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
                 } else if (relation.equals(XWPFRelation.COMMENT.getRelation())) {
                     // TODO Create according XWPFComment class, extending POIXMLDocumentPart
                     CommentsDocument cmntdoc = CommentsDocument.Factory.parse(p.getPackagePart().getInputStream());
-                    for (CTComment ctcomment : cmntdoc.getComments().getCommentList()) {
+                    for (CTComment ctcomment : cmntdoc.getComments().getCommentArray()) {
                         comments.add(new XWPFComment(ctcomment, this));
                     }
                 } else if (relation.equals(XWPFRelation.SETTINGS.getRelation())) {
@@ -232,6 +232,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
         }
     }
 
+    @SuppressWarnings("deprecation")
     private void initFootnotes() throws XmlException, IOException {
         for(POIXMLDocumentPart p : getRelations()){
             String relation = p.getPackageRelationship().getRelationshipType();
@@ -241,7 +242,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
             } else if (relation.equals(XWPFRelation.ENDNOTE.getRelation())){
                 EndnotesDocument endnotesDocument = EndnotesDocument.Factory.parse(p.getPackagePart().getInputStream());
 
-                for(CTFtnEdn ctFtnEdn : endnotesDocument.getEndnotes().getEndnoteList()) {
+                for(CTFtnEdn ctFtnEdn : endnotesDocument.getEndnotes().getEndnoteArray()) {
                     endnotes.put(ctFtnEdn.getId().intValue(), new XWPFFootnote(this, ctFtnEdn));
                 }
             }
@@ -364,10 +365,8 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
     }
 
     public XWPFHyperlink getHyperlinkByID(String id) {
-        Iterator<XWPFHyperlink> iter = hyperlinks.iterator();
-        while (iter.hasNext()) {
-            XWPFHyperlink link = iter.next();
-            if(link.getId().equals(id))
+        for (XWPFHyperlink link : hyperlinks) {
+            if (link.getId().equals(id))
                 return link;
         }
 
@@ -396,10 +395,8 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
     }
 
     public XWPFComment getCommentByID(String id) {
-        Iterator<XWPFComment> iter = comments.iterator();
-        while (iter.hasNext()) {
-            XWPFComment comment = iter.next();
-            if(comment.getId().equals(id))
+        for (XWPFComment comment : comments) {
+            if (comment.getId().equals(id))
                 return comment;
         }
 
@@ -1187,14 +1184,15 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
      * @param table
      */
     @Override
+    @SuppressWarnings("deprecation")
     public void insertTable(int pos, XWPFTable table) {
         bodyElements.add(pos, table);
-        int i;
-        for (i = 0; i < ctDocument.getBody().getTblList().size(); i++) {
-            CTTbl tbl = ctDocument.getBody().getTblArray(i);
+        int i = 0;
+        for (CTTbl tbl : ctDocument.getBody().getTblArray()) {
             if (tbl == table.getCTTbl()) {
                 break;
             }
+            i++;
         }
         tables.add(i, table);
     }
index 7ecb4d77cd513c48e5db14592723376147701035..5f0367d6bf5f94c38d8819397702cbc742a5060f 100644 (file)
@@ -123,14 +123,15 @@ public class XWPFFootnote implements Iterable<XWPFParagraph>,IBody {
      * @param table
      * @see org.apache.poi.xwpf.usermodel.IBody#insertTable(int pos, XWPFTable table)
      */
+    @SuppressWarnings("deprecation")
     public void insertTable(int pos, XWPFTable table) {
         bodyElements.add(pos, table);
-        int i;
-        for (i = 0; i < ctFtnEdn.getTblList().size(); i++) {
-            CTTbl tbl = ctFtnEdn.getTblArray(i);
+        int i = 0;
+        for (CTTbl tbl : ctFtnEdn.getTblArray()) {
             if(tbl == table.getCTTbl()){
                 break;
             }
+            i++;
         }
         tables.add(i, table);
 
index 74dd12613dd3942c90bf6eeb024055107a72fee7..8647454f28aea23200a9470e9fa36e96cea37211 100644 (file)
@@ -34,7 +34,6 @@ import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.apache.xmlbeans.XmlException;
 import org.apache.xmlbeans.XmlOptions;
-
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFootnotes;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.FootnotesDocument;
@@ -68,6 +67,7 @@ public class XWPFFootnotes extends POIXMLDocumentPart {
      * Read document
      */
     @Override
+    @SuppressWarnings("deprecation")
     protected void onDocumentRead () throws IOException {
         FootnotesDocument notesDoc;
         try {
@@ -79,7 +79,7 @@ public class XWPFFootnotes extends POIXMLDocumentPart {
         }
 
         // Find our footnotes
-        for(CTFtnEdn note : ctFootnotes.getFootnoteList()) {
+        for(CTFtnEdn note : ctFootnotes.getFootnoteArray()) {
             listFootnote.add(new XWPFFootnote(note, this));
         }
     }
index 5fc2fdcd07c055ffcc93bfd63ea7fb85eadf747b..e6dee2fef3dc22c5e3aa492fcb690f2a9f633cf9 100644 (file)
@@ -436,14 +436,15 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBo
      * @param pos
      * @param table
      */
+    @SuppressWarnings("deprecation")
     public void insertTable(int pos, XWPFTable table) {
         bodyElements.add(pos, table);
-        int i;
-        for (i = 0; i < headerFooter.getTblList().size(); i++) {
-            CTTbl tbl = headerFooter.getTblArray(i);
+        int i = 0;
+        for (CTTbl tbl : headerFooter.getTblArray()) {
             if(tbl == table.getCTTbl()){
                 break;
             }
+            i++;
         }
         tables.add(i, table);
 
index a0a586313bd59ccb1ab1f7fc15846b4c847cd240..83b898c1be295e4fab1388deb315f87dbf065ff6 100644 (file)
@@ -38,10 +38,12 @@ public class XWPFLatentStyles {
        /**
         * checks wheter specific LatentStyleID is a latentStyle
        */
+    @SuppressWarnings("deprecation")
        protected boolean isLatentStyle(String latentStyleID){  
-               for ( CTLsdException lsd: latentStyles.getLsdExceptionList()) {
-                       if(lsd.getName().equals(latentStyleID));
+               for ( CTLsdException lsd: latentStyles.getLsdExceptionArray()) {
+                       if(lsd.getName().equals(latentStyleID)) {
                                return true;
+                       }
                }
                return false;           
        }
index 2b4ca7049aa1da15ddd9cd6eb5f5857414cdcbe8..1bc8af5aed7753cb1e0d39b6bdd7f4c01ccdc461 100644 (file)
@@ -71,6 +71,7 @@ public class XWPFNumbering extends POIXMLDocumentPart {
         * read numbering form an existing package
         */
        @Override
+    @SuppressWarnings("deprecation")
        protected void onDocumentRead() throws IOException{
                NumberingDocument numberingDoc = null;
                InputStream is;
@@ -79,10 +80,10 @@ public class XWPFNumbering extends POIXMLDocumentPart {
                        numberingDoc = NumberingDocument.Factory.parse(is);
                        ctNumbering = numberingDoc.getNumbering();
                //get any Nums
-               for(CTNum ctNum : ctNumbering.getNumList()) {
+               for(CTNum ctNum : ctNumbering.getNumArray()) {
                    nums.add(new XWPFNum(ctNum, this));
                }
-               for(CTAbstractNum ctAbstractNum : ctNumbering.getAbstractNumList()){
+               for(CTAbstractNum ctAbstractNum : ctNumbering.getAbstractNumArray()){
                        abstractNums.add(new XWPFAbstractNum(ctAbstractNum, this));
                }
                isNew = false;
@@ -144,7 +145,7 @@ public class XWPFNumbering extends POIXMLDocumentPart {
         */
        public BigInteger addNum(XWPFNum num){
                ctNumbering.addNewNum();
-               int pos = (ctNumbering.getNumList().size()) - 1;
+               int pos = ctNumbering.sizeOfNumArray() - 1;
                ctNumbering.setNumArray(pos, num.getCTNum());
                nums.add(num);
                return num.getCTNum().getNumId();
index 98b9dccc465bc469c16b2831ceb720dca37df2b1..5a4d7b33b7e266f43d3c6b45d43868c74dea1eb7 100644 (file)
@@ -137,7 +137,7 @@ public class XWPFParagraph implements IBodyElement, IRunBody, ISDTContents {
            }
            if (o instanceof CTHyperlink) {
                CTHyperlink link = (CTHyperlink) o;
-               for (CTR r : link.getRList()) {
+               for (CTR r : link.getRArray()) {
                    XWPFHyperlinkRun hr = new XWPFHyperlinkRun(link, r, this);
                    runs.add(hr);
                    iruns.add(hr);
@@ -152,14 +152,14 @@ public class XWPFParagraph implements IBodyElement, IRunBody, ISDTContents {
                iruns.add(cc);
            }
            if (o instanceof CTRunTrackChange) {
-               for (CTR r : ((CTRunTrackChange) o).getRList()) {
+               for (CTR r : ((CTRunTrackChange) o).getRArray()) {
                    XWPFRun cr = new XWPFRun(r, this);
                    runs.add(cr);
                    iruns.add(cr);
                }
            }
            if (o instanceof CTSimpleField) {
-               for (CTR r : ((CTSimpleField) o).getRList()) {
+               for (CTR r : ((CTSimpleField) o).getRArray()) {
                    XWPFRun cr = new XWPFRun(r, this);
                    runs.add(cr);
                    iruns.add(cr);
@@ -1170,7 +1170,7 @@ public class XWPFParagraph implements IBodyElement, IRunBody, ISDTContents {
      */
     protected void addRun(CTR run){
         int pos;
-        pos = paragraph.getRList().size();
+        pos = paragraph.sizeOfRArray();
         paragraph.addNewR();
         paragraph.setRArray(pos, run);
     }
@@ -1230,9 +1230,10 @@ public class XWPFParagraph implements IBodyElement, IRunBody, ISDTContents {
             startChar = startPos.getChar();
         int beginRunPos = 0, candCharPos = 0;
         boolean newList = false;
-        for (int runPos=startRun; runPos<paragraph.getRList().size(); runPos++) {
+        CTR[] rArray = paragraph.getRArray();
+        for (int runPos=startRun; runPos<rArray.length; runPos++) {
             int beginTextPos = 0,beginCharPos = 0, textPos = 0,  charPos = 0;    
-            CTR ctRun = paragraph.getRArray(runPos);
+            CTR ctRun = rArray[runPos];
             XmlCursor c = ctRun.newCursor();
             c.selectPath("./*");
             while(c.toNextSelection()){
@@ -1298,15 +1299,17 @@ public class XWPFParagraph implements IBodyElement, IRunBody, ISDTContents {
         int runEnd = segment.getEndRun();
         int textEnd = segment.getEndText();
         int charEnd    = segment.getEndChar();
-        StringBuffer out = new StringBuffer();
+        StringBuilder out = new StringBuilder();
+        CTR[] rArray = paragraph.getRArray();
         for(int i=runBegin; i<=runEnd;i++){
-            int startText=0, endText = paragraph.getRArray(i).getTList().size()-1;
+            CTText[] tArray = rArray[i].getTArray();
+            int startText=0, endText = tArray.length-1;
             if(i==runBegin)
                 startText=textBegin;
             if(i==runEnd)
                 endText = textEnd;
             for(int j=startText;j<=endText;j++){
-                String tmpText = paragraph.getRArray(i).getTArray(j).getStringValue();
+                String tmpText = tArray[j].getStringValue();
                 int startChar=0, endChar = tmpText.length()-1;
                 if((j==textBegin)&&(i==runBegin))
                     startChar=charBegin;
@@ -1314,7 +1317,6 @@ public class XWPFParagraph implements IBodyElement, IRunBody, ISDTContents {
                     endChar = charEnd;
                 }
                 out.append(tmpText.substring(startChar, endChar+1));
-
             }
         }
         return out.toString();
index b1f9c62863edf46027719d6af28969c00e6b2afa..dc09b43d46c866ff19e6432c5a7f4a2d74d0eaec 100644 (file)
@@ -20,6 +20,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import javax.xml.namespace.QName;
@@ -95,6 +96,7 @@ public class XWPFRun implements ISDTContents, IRunElement{
      * @param r the CTR bean which holds the run attributes
      * @param p the parent paragraph
      */
+    @SuppressWarnings("deprecation")
     public XWPFRun(CTR r, IRunBody p) {
         this.run = r;
         this.parent = p;
@@ -103,16 +105,13 @@ public class XWPFRun implements ISDTContents, IRunElement{
          * reserve already occupied drawing ids, so reserving new ids later will
          * not corrupt the document
          */
-        List<CTDrawing> drawingList = r.getDrawingList();
-        for (CTDrawing ctDrawing : drawingList) {
-            List<CTAnchor> anchorList = ctDrawing.getAnchorList();
-            for (CTAnchor anchor : anchorList) {
+        for (CTDrawing ctDrawing : r.getDrawingArray()) {
+            for (CTAnchor anchor : ctDrawing.getAnchorArray()) {
                 if (anchor.getDocPr() != null) {
                     getDocument().getDrawingIdManager().reserve(anchor.getDocPr().getId());
                 }
             }
-            List<CTInline> inlineList = ctDrawing.getInlineList();
-            for (CTInline inline : inlineList) {
+            for (CTInline inline : ctDrawing.getInlineArray()) {
                 if (inline.getDocPr() != null) {
                     getDocument().getDrawingIdManager().reserve(inline.getDocPr().getId());
                 }
@@ -120,17 +119,17 @@ public class XWPFRun implements ISDTContents, IRunElement{
         }
 
         // Look for any text in any of our pictures or drawings
-        StringBuffer text = new StringBuffer();
+        StringBuilder text = new StringBuilder();
         List<XmlObject> pictTextObjs = new ArrayList<XmlObject>();
-        pictTextObjs.addAll(r.getPictList());
-        pictTextObjs.addAll(drawingList);
+        pictTextObjs.addAll(Arrays.asList(r.getPictArray()));
+        pictTextObjs.addAll(Arrays.asList(r.getDrawingArray()));
         for(XmlObject o : pictTextObjs) {
-            XmlObject[] t = o.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:t");
-            for (int m = 0; m < t.length; m++) {
-                NodeList kids = t[m].getDomNode().getChildNodes();
+            XmlObject[] ts = o.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:t");
+            for (XmlObject t : ts) {
+                NodeList kids = t.getDomNode().getChildNodes();
                 for (int n = 0; n < kids.getLength(); n++) {
                     if (kids.item(n) instanceof Text) {
-                        if(text.length() > 0)
+                        if (text.length() > 0)
                             text.append("\n");
                         text.append(kids.item(n).getNodeValue());
                     }
@@ -317,7 +316,7 @@ public class XWPFRun implements ISDTContents, IRunElement{
      * @param value the literal text which shall be displayed in the document
      */
     public void setText(String value) {
-        setText(value,run.getTList().size());
+        setText(value,run.sizeOfTArray());
     }
 
     /**
index 59a0abba9f93b73a462901bd2f16a01216ccb16d..42c56b3773d589ff26602f26e133d721ee8c5940 100644 (file)
@@ -50,8 +50,8 @@ public class XWPFSDTContent implements ISDTContent {
     private List<ISDTContents> bodyElements = new ArrayList<ISDTContents>();
 
     public XWPFSDTContent(CTSdtContentRun sdtRun, IBody part, IRunBody parent){
-        for (CTR ctr : sdtRun.getRList()){
-            XWPFRun run = new XWPFRun((CTR) ctr, parent);
+        for (CTR ctr : sdtRun.getRArray()){
+            XWPFRun run = new XWPFRun(ctr, parent);
             runs.add(run);
             bodyElements.add(run);
         }
index 35a0c6027e1bffcc808d4f00cf0fb0543000ca0e..359f4ece249ddf389ce4bc2cb7ab3c82b195606e 100644 (file)
@@ -37,7 +37,6 @@ import org.apache.xmlbeans.XmlOptions;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.StylesDocument;
-
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPrDefault;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLanguage;
@@ -74,6 +73,7 @@ public class XWPFStyles extends POIXMLDocumentPart{
     * Read document
     */
    @Override
+   @SuppressWarnings("deprecation")
    protected void onDocumentRead() throws IOException{
       StylesDocument stylesDoc;
       try {
@@ -86,7 +86,7 @@ public class XWPFStyles extends POIXMLDocumentPart{
       }
       
       // Build up all the style objects
-      for(CTStyle style : ctStyles.getStyleList()) {
+      for(CTStyle style : ctStyles.getStyleArray()) {
          listStyle.add(new XWPFStyle(style, this));
       }
    }
@@ -137,7 +137,7 @@ public class XWPFStyles extends POIXMLDocumentPart{
        public void addStyle(XWPFStyle style){
                listStyle.add(style);
                ctStyles.addNewStyle();
-               int pos = (ctStyles.getStyleList().size()) - 1;
+               int pos = ctStyles.sizeOfStyleArray() - 1;
                ctStyles.setStyleArray(pos, style.getCTStyle());
        }
        /**
index 554e7bef2cd7d93f9a7298115a0bcdc37392a579..643d28ffa9644b406270b9919f67e7d949173240 100644 (file)
@@ -93,6 +93,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
         }
     }
 
+    @SuppressWarnings("deprecation")
     public XWPFTable(CTTbl table, IBody part){
         this.part = part;
         this.ctTbl = table;
@@ -103,12 +104,12 @@ public class XWPFTable implements IBodyElement, ISDTContents {
         if (table.sizeOfTrArray() == 0)
             createEmptyTable(table);
 
-        for (CTRow row : table.getTrList()) {
-            StringBuffer rowText = new StringBuffer();
+        for (CTRow row : table.getTrArray()) {
+            StringBuilder rowText = new StringBuilder();
             XWPFTableRow tabRow = new XWPFTableRow(row, this);
             tableRows.add(tabRow);
-            for (CTTc cell : row.getTcList()) {
-                for (CTP ctp : cell.getPList()) {
+            for (CTTc cell : row.getTcArray()) {
+                for (CTP ctp : cell.getPArray()) {
                     XWPFParagraph p = new XWPFParagraph(ctp, part);
                     if (rowText.length() > 0) {
                         rowText.append('\t');
index e1b46fecd2fb68a7bc35a4b1603d8e4765d045c7..c1f0d4f447d37b9b7e669f470c7f7f572fbf5ec3 100644 (file)
@@ -79,7 +79,7 @@ public class XWPFTableCell implements IBody, ICell {
         this.part = part;
         this.tableRow = tableRow;
         // NB: If a table cell does not include at least one block-level element, then this document shall be considered corrupt.
-        if(cell.getPList().size()<1)
+        if(cell.sizeOfPArray()<1)
             cell.addNewP();
         bodyElements = new ArrayList<IBodyElement>();
         paragraphs = new ArrayList<XWPFParagraph>();
@@ -398,16 +398,17 @@ public class XWPFTableCell implements IBody, ICell {
      * inserts an existing XWPFTable to the arrays bodyElements and tables
      * @see org.apache.poi.xwpf.usermodel.IBody#insertTable(int, org.apache.poi.xwpf.usermodel.XWPFTable)
      */
+    @SuppressWarnings("deprecation")
     public void insertTable(int pos, XWPFTable table) {
-       bodyElements.add(pos, table);
-       int i;
-       for (i = 0; i < ctTc.getTblList().size(); i++) {
-           CTTbl tbl = ctTc.getTblArray(i);
-           if(tbl == table.getCTTbl()){
-               break;
-           }
-       }
-       tables.add(i, table);
+        bodyElements.add(pos, table);
+        int i = 0;
+        for (CTTbl tbl : ctTc.getTblArray()) {
+            if (tbl == table.getCTTbl()) {
+                break;
+            }
+            i++;
+        }
+        tables.add(i, table);
     }
 
     public String getText(){
index 56ea38745f59a20c4a6beec9023e00c6de134a3d..627ee3c8d3541d482b516e503ffaad0b0552e440 100644 (file)
@@ -152,10 +152,11 @@ public class XWPFTableRow {
      * who belongs to this row
      * @return a list of {@link XWPFTableCell} 
      */
+    @SuppressWarnings("deprecation")
     public List<XWPFTableCell> getTableCells(){
        if(tableCells == null){
            List<XWPFTableCell> cells = new ArrayList<XWPFTableCell>();
-           for (CTTc tableCell : ctRow.getTcList()) {
+           for (CTTc tableCell : ctRow.getTcArray()) {
                cells.add(new XWPFTableCell(tableCell, this, table.getBody()));
            }
        //TODO: it is possible to have an SDT that contains a cell in within a row
@@ -201,7 +202,7 @@ public class XWPFTableRow {
        boolean isCant = false;
        CTTrPr trpr = getTrPr();
        if (trpr.sizeOfCantSplitArray() > 0) {
-           CTOnOff onoff = trpr.getCantSplitList().get(0);
+           CTOnOff onoff = trpr.getCantSplitArray(0);
            isCant = onoff.getVal().equals(STOnOff.ON);
        }
        return isCant;
@@ -229,7 +230,7 @@ public class XWPFTableRow {
        boolean repeat = false;
        CTTrPr trpr = getTrPr();
        if (trpr.sizeOfTblHeaderArray() > 0) {
-           CTOnOff rpt = trpr.getTblHeaderList().get(0);
+           CTOnOff rpt = trpr.getTblHeaderArray(0);
            repeat = rpt.getVal().equals(STOnOff.ON);
        }
        return repeat;
index c7215a406169c4e41fcdc986d64dae730dc59692..e185543020b59718a489ac0e562b8de27e4fa5c0 100644 (file)
@@ -80,13 +80,14 @@ public final class TestPOIXMLProperties extends TestCase {
                org.apache.poi.POIXMLProperties.ExtendedProperties newProperties =
                                newProps.getExtendedProperties();
 
+        assertEquals(application, newProperties.getApplication());
+        assertEquals(appVersion, newProperties.getAppVersion());
+        
                org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.CTProperties
                                newCtProps = newProperties.getUnderlyingProperties();
 
                assertEquals(application, newCtProps.getApplication());
                assertEquals(appVersion, newCtProps.getAppVersion());
-
-
        }
 
 
index 1c64fd8629094585d5c28bf9a249d9448d1cc303..c42ce63d4397c15edc70a1f346583ea75552add8 100644 (file)
@@ -42,7 +42,6 @@ import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
 import org.apache.poi.util.DocumentHelper;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
-import org.apache.poi.util.SAXHelper;
 import org.apache.poi.util.TempFile;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -218,7 +217,7 @@ public final class TestPackage extends TestCase {
         PackagePartName relName = PackagingURIHelper.createPartName(PackageRelationship.getContainerPartRelationship());
         PackagePart relPart = pkg.getPart(relName);
 
-        Document xmlRelationshipsDoc = SAXHelper.readSAXDocument(relPart.getInputStream());
+        Document xmlRelationshipsDoc = DocumentHelper.readDocument(relPart.getInputStream());
 
         Element root = xmlRelationshipsDoc.getDocumentElement();
         NodeList nodeList = root.getElementsByTagName(PackageRelationship.RELATIONSHIP_TAG_NAME);
index 24d002d27ff41bd830ce071554078ea4743a793b..afd70f08e5e30df4d15788e204ba22ef387de213 100644 (file)
@@ -30,6 +30,7 @@ import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateException;\r
 import java.security.cert.X509CRL;\r
 import java.security.cert.X509Certificate;\r
+import java.security.interfaces.RSAPublicKey;\r
 import java.security.spec.RSAKeyGenParameterSpec;\r
 import java.util.Date;\r
 \r
@@ -45,8 +46,6 @@ import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;\r
 import javax.xml.transform.stream.StreamResult;\r
 \r
-import org.bouncycastle.asn1.ASN1InputStream;\r
-import org.bouncycastle.asn1.ASN1Sequence;\r
 import org.bouncycastle.asn1.DERIA5String;\r
 import org.bouncycastle.asn1.DEROctetString;\r
 import org.bouncycastle.asn1.DERSequence;\r
@@ -69,6 +68,7 @@ import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
 import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;\r
 import org.bouncycastle.cert.X509CRLHolder;\r
 import org.bouncycastle.cert.X509CertificateHolder;\r
+import org.bouncycastle.cert.X509ExtensionUtils;\r
 import org.bouncycastle.cert.X509v2CRLBuilder;\r
 import org.bouncycastle.cert.X509v3CertificateBuilder;\r
 import org.bouncycastle.cert.jcajce.JcaX509CRLConverter;\r
@@ -83,6 +83,8 @@ import org.bouncycastle.cert.ocsp.OCSPResp;
 import org.bouncycastle.cert.ocsp.OCSPRespBuilder;\r
 import org.bouncycastle.cert.ocsp.Req;\r
 import org.bouncycastle.cert.ocsp.RevokedStatus;\r
+import org.bouncycastle.crypto.params.RSAKeyParameters;\r
+import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory;\r
 import org.bouncycastle.operator.ContentSigner;\r
 import org.bouncycastle.operator.DigestCalculator;\r
 import org.bouncycastle.operator.OperatorCreationException;\r
@@ -108,24 +110,6 @@ public class PkiTestUtils {
         return keyPair;\r
     }\r
 \r
-    @SuppressWarnings("resource")\r
-    private static SubjectKeyIdentifier createSubjectKeyId(PublicKey publicKey)\r
-    throws IOException {\r
-        ASN1InputStream asnObj = new ASN1InputStream(publicKey.getEncoded());\r
-        SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(asnObj.readObject());\r
-        SubjectKeyIdentifier keyId = SubjectKeyIdentifier.getInstance(info.getEncoded());\r
-        return keyId;\r
-    }\r
-\r
-    @SuppressWarnings("resource")\r
-    private static AuthorityKeyIdentifier createAuthorityKeyId(PublicKey publicKey)\r
-    throws IOException {\r
-        ASN1InputStream asnObj = new ASN1InputStream(publicKey.getEncoded());\r
-        SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(asnObj.readObject());\r
-        AuthorityKeyIdentifier keyId = AuthorityKeyIdentifier.getInstance(info);\r
-        return keyId;\r
-    }\r
-\r
     static X509Certificate generateCertificate(PublicKey subjectPublicKey,\r
             String subjectDn, Date notBefore, Date notAfter,\r
             X509Certificate issuerCertificate, PrivateKey issuerPrivateKey,\r
@@ -140,9 +124,15 @@ public class PkiTestUtils {
         } else {\r
             issuerName = new X500Name(subjectDn);\r
         }\r
+        \r
+        RSAPublicKey rsaPubKey = (RSAPublicKey)subjectPublicKey;\r
+        RSAKeyParameters rsaSpec = new RSAKeyParameters(false, rsaPubKey.getModulus(), rsaPubKey.getPublicExponent());\r
 \r
-        SubjectPublicKeyInfo subjectPublicKeyInfo = new SubjectPublicKeyInfo(\r
-            ASN1Sequence.getInstance(subjectPublicKey.getEncoded()));\r
+        SubjectPublicKeyInfo subjectPublicKeyInfo = \r
+            SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(rsaSpec);\r
+\r
+        DigestCalculator digestCalc = new JcaDigestCalculatorProviderBuilder()\r
+            .setProvider("BC").build().get(CertificateID.HASH_SHA1);\r
         \r
         X509v3CertificateBuilder certificateGenerator = new X509v3CertificateBuilder(\r
               issuerName\r
@@ -153,8 +143,14 @@ public class PkiTestUtils {
             , subjectPublicKeyInfo\r
         );\r
 \r
-        certificateGenerator.addExtension(Extension.subjectKeyIdentifier, false, createSubjectKeyId(subjectPublicKey));\r
-        certificateGenerator.addExtension(Extension.authorityKeyIdentifier, false, createAuthorityKeyId(subjectPublicKey));\r
+        X509ExtensionUtils exUtils = new X509ExtensionUtils(digestCalc);\r
+        SubjectKeyIdentifier subKeyId = exUtils.createSubjectKeyIdentifier(subjectPublicKeyInfo);\r
+        AuthorityKeyIdentifier autKeyId = (issuerCertificate != null) \r
+            ? exUtils.createAuthorityKeyIdentifier(new X509CertificateHolder(issuerCertificate.getEncoded()))\r
+            : exUtils.createAuthorityKeyIdentifier(subjectPublicKeyInfo);\r
+\r
+        certificateGenerator.addExtension(Extension.subjectKeyIdentifier, false, subKeyId);\r
+        certificateGenerator.addExtension(Extension.authorityKeyIdentifier, false, autKeyId);\r
 \r
         if (caFlag) {\r
             BasicConstraints bc;\r
index 34def89b8b138931298f710c0e8a360bd3bc06fc..fe5e4d30c1647fa229f4ac4faf853270ef0810ae 100644 (file)
@@ -70,10 +70,10 @@ import org.apache.poi.poifs.crypt.dsig.services.TimeStampService;
 import org.apache.poi.poifs.crypt.dsig.services.TimeStampServiceValidator;\r
 import org.apache.poi.poifs.crypt.dsig.services.XmlSignatureService;\r
 import org.apache.poi.poifs.crypt.dsig.spi.DigestInfo;\r
+import org.apache.poi.util.DocumentHelper;\r
 import org.apache.poi.util.IOUtils;\r
 import org.apache.poi.util.POILogFactory;\r
 import org.apache.poi.util.POILogger;\r
-import org.apache.poi.util.SAXHelper;\r
 import org.apache.xmlbeans.XmlObject;\r
 import org.bouncycastle.asn1.x509.KeyUsage;\r
 import org.bouncycastle.cert.ocsp.OCSPResp;\r
@@ -336,7 +336,7 @@ public class TestSignatureInfo {
         signatureService.initFacets(cal.getTime());\r
         initKeyPair(alias, signerDn);\r
 \r
-        Document document = SAXHelper.getDocumentBuilder().newDocument();\r
+        Document document = DocumentHelper.createDocument();\r
 \r
         // operate\r
         List<X509Certificate> x509Chain = Collections.singletonList(x509);\r
index f82ed00ce01dca1b947b4593735009054f8ebd17..b34a0d1c4e82a80eff96357d1c424250e3c9bb86 100644 (file)
@@ -17,6 +17,7 @@
 package org.apache.poi.xslf;
 
 import junit.framework.TestCase;
+
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackagePart;
@@ -61,22 +62,19 @@ public class TestXSLFSlideShow extends TestCase {
                        );
        }
        
+    @SuppressWarnings("deprecation")
        public void testSlideBasics() throws Exception {
                XSLFSlideShow xml = new XSLFSlideShow(pack);
                
                // Should have 1 master
                assertEquals(1, xml.getSlideMasterReferences().sizeOfSldMasterIdArray());
-               assertEquals(1, xml.getSlideMasterReferences().getSldMasterIdList().size());
-               
+
                // Should have three sheets
                assertEquals(2, xml.getSlideReferences().sizeOfSldIdArray());
-               assertEquals(2, xml.getSlideReferences().getSldIdList().size());
-               
+
                // Check they're as expected
-               CTSlideIdListEntry[] slides = new CTSlideIdListEntry[
-                   xml.getSlideReferences().getSldIdList().size()];
-               xml.getSlideReferences().getSldIdList().toArray(slides);
-               
+               CTSlideIdListEntry[] slides = xml.getSlideReferences().getSldIdArray();
+
                assertEquals(256, slides[0].getId());
                assertEquals(257, slides[1].getId());
                assertEquals("rId2", slides[0].getId2());
@@ -91,9 +89,7 @@ public class TestXSLFSlideShow extends TestCase {
                assertNotNull(xml.getNotes(slides[1]));
                
                // And again for the master
-               CTSlideMasterIdListEntry[] masters = new CTSlideMasterIdListEntry[
-                       xml.getSlideMasterReferences().getSldMasterIdList().size()];
-               xml.getSlideMasterReferences().getSldMasterIdList().toArray(masters);
+               CTSlideMasterIdListEntry[] masters = xml.getSlideMasterReferences().getSldMasterIdArray();
                
                assertEquals(2147483648l, masters[0].getId());
                assertEquals("rId1", masters[0].getId2());
index 0fc4b20aaa7f408647df0c850aa5df5f98519650..604f68fffb5e1d1e631c6c4a797e1d2b07f9f9df 100644 (file)
@@ -17,6 +17,7 @@
 package org.apache.poi.xslf.usermodel;
 
 import junit.framework.TestCase;
+
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackagePart;
@@ -58,6 +59,7 @@ public class TestXMLSlideShow extends TestCase {
       assertTrue(xml.getSlideMasters().length > 0);
    }
 
+   @SuppressWarnings("deprecation")
    public void testSlideBasics() throws Exception {
       XMLSlideShow xml = new XMLSlideShow(pack);
 
@@ -68,9 +70,7 @@ public class TestXMLSlideShow extends TestCase {
       assertEquals(2, xml.getSlides().length);
 
       // Check they're as expected
-      CTSlideIdListEntry[] slides = new CTSlideIdListEntry[
-         xml.getCTPresentation().getSldIdLst().getSldIdList().size()];
-      xml.getCTPresentation().getSldIdLst().getSldIdList().toArray(slides);
+      CTSlideIdListEntry[] slides = xml.getCTPresentation().getSldIdLst().getSldIdArray();
 
       assertEquals(256, slides[0].getId());
       assertEquals(257, slides[1].getId());
@@ -86,9 +86,7 @@ public class TestXMLSlideShow extends TestCase {
       assertNotNull(xml.getSlides()[1].getNotes());
 
       // Next up look for the slide master
-      CTSlideMasterIdListEntry[] masters = new CTSlideMasterIdListEntry[
-         xml.getCTPresentation().getSldMasterIdLst().getSldMasterIdList().size()];
-      xml.getCTPresentation().getSldMasterIdLst().getSldMasterIdList().toArray(masters);
+      CTSlideMasterIdListEntry[] masters = xml.getCTPresentation().getSldMasterIdLst().getSldMasterIdArray();
 
       assertEquals(2147483648l, masters[0].getId());
       assertEquals("rId1", masters[0].getId2());
index f0d57241dbf3446d564924480179b70ada9f3bcf..838db8137bfd8db0c2fad9ffb891e7e8be970b4c 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
+import java.awt.Color;\r
+\r
 import junit.framework.TestCase;\r
+\r
 import org.apache.poi.util.Units;\r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.*;\r
-\r
-import java.awt.Color;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleItem;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleList;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
@@ -243,13 +250,14 @@ public class TestXSLFSimpleShape extends TestCase {
 \r
     }\r
 \r
+    @SuppressWarnings({ "deprecation", "unused" })\r
     public void testShadowEffects(){\r
         XMLSlideShow ppt = new XMLSlideShow();\r
         XSLFSlide slide = ppt.createSlide();\r
         CTStyleMatrix styleMatrix = slide.getTheme().getXmlObject().getThemeElements().getFmtScheme();\r
         CTEffectStyleList lst = styleMatrix.getEffectStyleLst();\r
         assertNotNull(lst);\r
-        for(CTEffectStyleItem ef : lst.getEffectStyleList()){\r
+        for(CTEffectStyleItem ef : lst.getEffectStyleArray()){\r
             CTOuterShadowEffect obj = ef.getEffectLst().getOuterShdw();\r
         }\r
     }\r
index 156c0dec4943a104471d051cfc18e82dbd1a513f..f90804fa4ca9601969671a7bbef0c4a2682fa110 100644 (file)
 ==================================================================== */
 package org.apache.poi.xssf;
 
-import org.apache.poi.xssf.usermodel.XSSFSheet;
+import junit.framework.TestCase;
 
+import org.apache.poi.xssf.usermodel.XSSFSheet;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
-import junit.framework.TestCase;
-
 public class TestSheetProtection extends TestCase {
        private XSSFSheet sheet;
        
@@ -75,6 +74,8 @@ public class TestSheetProtection extends TestCase {
                assertFalse(sheet.isAutoFilterLocked());
                sheet.enableLocking();
                assertTrue(sheet.isAutoFilterLocked());
+               sheet.lockAutoFilter(false);
+               assertFalse(sheet.isAutoFilterLocked());
        }
        
        public void testWriteDeleteColumns() throws Exception {
@@ -83,6 +84,8 @@ public class TestSheetProtection extends TestCase {
                assertFalse(sheet.isDeleteColumnsLocked());
                sheet.enableLocking();
                assertTrue(sheet.isDeleteColumnsLocked());
+               sheet.lockDeleteColumns(false);
+               assertFalse(sheet.isDeleteColumnsLocked());
        }
        
        public void testWriteDeleteRows() throws Exception {
@@ -91,6 +94,8 @@ public class TestSheetProtection extends TestCase {
                assertFalse(sheet.isDeleteRowsLocked());
                sheet.enableLocking();
                assertTrue(sheet.isDeleteRowsLocked());
+        sheet.lockDeleteRows(false);
+        assertFalse(sheet.isDeleteRowsLocked());
        }
        
        public void testWriteFormatCells() throws Exception {
@@ -99,6 +104,8 @@ public class TestSheetProtection extends TestCase {
                assertFalse(sheet.isFormatCellsLocked());
                sheet.enableLocking();
                assertTrue(sheet.isFormatCellsLocked());
+        sheet.lockFormatCells(false);
+        assertFalse(sheet.isFormatCellsLocked());
        }
        
        public void testWriteFormatColumns() throws Exception {
@@ -107,6 +114,8 @@ public class TestSheetProtection extends TestCase {
                assertFalse(sheet.isFormatColumnsLocked());
                sheet.enableLocking();
                assertTrue(sheet.isFormatColumnsLocked());
+        sheet.lockFormatColumns(false);
+        assertFalse(sheet.isFormatColumnsLocked());
        }
        
        public void testWriteFormatRows() throws Exception {
@@ -115,6 +124,8 @@ public class TestSheetProtection extends TestCase {
                assertFalse(sheet.isFormatRowsLocked());
                sheet.enableLocking();
                assertTrue(sheet.isFormatRowsLocked());
+        sheet.lockFormatRows(false);
+        assertFalse(sheet.isFormatRowsLocked());
        }
        
        public void testWriteInsertColumns() throws Exception {
@@ -123,6 +134,8 @@ public class TestSheetProtection extends TestCase {
                assertFalse(sheet.isInsertColumnsLocked());
                sheet.enableLocking();
                assertTrue(sheet.isInsertColumnsLocked());
+        sheet.lockInsertColumns(false);
+        assertFalse(sheet.isInsertColumnsLocked());
        }
        
        public void testWriteInsertHyperlinks() throws Exception {
@@ -131,6 +144,8 @@ public class TestSheetProtection extends TestCase {
                assertFalse(sheet.isInsertHyperlinksLocked());
                sheet.enableLocking();
                assertTrue(sheet.isInsertHyperlinksLocked());
+        sheet.lockInsertHyperlinks(false);
+        assertFalse(sheet.isInsertHyperlinksLocked());
        }
        
        public void testWriteInsertRows() throws Exception {
@@ -139,6 +154,8 @@ public class TestSheetProtection extends TestCase {
                assertFalse(sheet.isInsertRowsLocked());
                sheet.enableLocking();
                assertTrue(sheet.isInsertRowsLocked());
+        sheet.lockInsertRows(false);
+        assertFalse(sheet.isInsertRowsLocked());
        }
        
        public void testWritePivotTables() throws Exception {
@@ -147,6 +164,8 @@ public class TestSheetProtection extends TestCase {
                assertFalse(sheet.isPivotTablesLocked());
                sheet.enableLocking();
                assertTrue(sheet.isPivotTablesLocked());
+        sheet.lockPivotTables(false);
+        assertFalse(sheet.isPivotTablesLocked());
        }
        
        public void testWriteSort() throws Exception {
@@ -155,6 +174,8 @@ public class TestSheetProtection extends TestCase {
                assertFalse(sheet.isSortLocked());
                sheet.enableLocking();
                assertTrue(sheet.isSortLocked());
+        sheet.lockSort(false);
+        assertFalse(sheet.isSortLocked());
        }
        
        public void testWriteObjects() throws Exception {
@@ -163,6 +184,8 @@ public class TestSheetProtection extends TestCase {
                assertFalse(sheet.isObjectsLocked());
                sheet.enableLocking();
                assertTrue(sheet.isObjectsLocked());
+        sheet.lockObjects(false);
+        assertFalse(sheet.isObjectsLocked());
        }
        
        public void testWriteScenarios() throws Exception {
@@ -171,6 +194,8 @@ public class TestSheetProtection extends TestCase {
                assertFalse(sheet.isScenariosLocked());
                sheet.enableLocking();
                assertTrue(sheet.isScenariosLocked());
+        sheet.lockScenarios(false);
+        assertFalse(sheet.isScenariosLocked());
        }
        
        public void testWriteSelectLockedCells() throws Exception {
@@ -179,6 +204,8 @@ public class TestSheetProtection extends TestCase {
                assertFalse(sheet.isSelectLockedCellsLocked());
                sheet.enableLocking();
                assertTrue(sheet.isSelectLockedCellsLocked());
+        sheet.lockSelectLockedCells(false);
+        assertFalse(sheet.isSelectLockedCellsLocked());
        }
        
        public void testWriteSelectUnlockedCells() throws Exception {
@@ -187,6 +214,8 @@ public class TestSheetProtection extends TestCase {
                assertFalse(sheet.isSelectUnlockedCellsLocked());
                sheet.enableLocking();
                assertTrue(sheet.isSelectUnlockedCellsLocked());
+        sheet.lockSelectUnlockedCells(false);
+        assertFalse(sheet.isSelectUnlockedCellsLocked());
        }
 
        public void testWriteSelectEnableLocking() throws Exception {
index 642fe30748ec2653d06d01930d30f5e61837fbf3..969061932b48863fef2fd1bcb9b5c160dc336fd0 100644 (file)
 ==================================================================== */
 package org.apache.poi.xssf;
 
-import java.io.File;
-
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-
-import junit.framework.TestCase;
-
-import org.apache.poi.util.TempFile;
+import static org.apache.poi.xssf.XSSFTestDataSamples.openSampleWorkbook;
+import static org.apache.poi.xssf.XSSFTestDataSamples.writeOutAndReadBack;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.poi.poifs.crypt.CryptoFunctions;
+import org.apache.poi.poifs.crypt.HashAlgorithm;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
-
-public class TestWorkbookProtection extends TestCase {
-
-       public void testShouldReadWorkbookProtection() throws Exception {
-               XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("workbookProtection_not_protected.xlsx");
+import org.junit.Test;
+
+public class TestWorkbookProtection {
+
+    @Test
+    public void workbookAndRevisionPassword() throws Exception {
+        XSSFWorkbook workbook;
+        String password = "test";
+        
+        // validate password with an actual office file (Excel 2010)
+        workbook = openSampleWorkbook("workbookProtection-workbook_password_user_range-2010.xlsx");
+        assertTrue(workbook.validateWorkbookPassword(password));
+
+        // validate with another office file (Excel 2013)
+        workbook = openSampleWorkbook("workbookProtection-workbook_password-2013.xlsx");
+        assertTrue(workbook.validateWorkbookPassword(password));
+
+        
+        workbook = openSampleWorkbook("workbookProtection_not_protected.xlsx");
+
+        // setting a null password shouldn't introduce the protection element
+        workbook.setWorkbookPassword(null, null);
+        assertNull(workbook.getCTWorkbook().getWorkbookProtection());
+
+        // compare the hashes
+        workbook.setWorkbookPassword(password, null);
+        int hashVal = CryptoFunctions.createXorVerifier1(password);
+        int actualVal = Integer.parseInt(workbook.getCTWorkbook().getWorkbookProtection().xgetWorkbookPassword().getStringValue(),16);
+        assertEquals(hashVal, actualVal);
+        assertTrue(workbook.validateWorkbookPassword(password));
+        
+        // removing the password again
+        workbook.setWorkbookPassword(null, null);
+        assertFalse(workbook.getCTWorkbook().getWorkbookProtection().isSetWorkbookPassword());
+        
+        // removing the whole protection structure
+        workbook.unLock();
+        assertNull(workbook.getCTWorkbook().getWorkbookProtection());
+        
+        // setting a null password shouldn't introduce the protection element
+        workbook.setRevisionsPassword(null, null);
+        assertNull(workbook.getCTWorkbook().getWorkbookProtection());
+
+        // compare the hashes
+        password = "T\u0400ST\u0100passwordWhichIsLongerThan15Chars";
+        workbook.setRevisionsPassword(password, null);
+        hashVal = CryptoFunctions.createXorVerifier1(password);
+        actualVal = Integer.parseInt(workbook.getCTWorkbook().getWorkbookProtection().xgetRevisionsPassword().getStringValue(),16);
+        assertEquals(hashVal, actualVal);
+        assertTrue(workbook.validateRevisionsPassword(password));
+    }
+    
+    @Test
+    public void shouldReadWorkbookProtection() throws Exception {
+               XSSFWorkbook workbook = openSampleWorkbook("workbookProtection_not_protected.xlsx");
                assertFalse(workbook.isStructureLocked());
                assertFalse(workbook.isWindowsLocked());
                assertFalse(workbook.isRevisionLocked());
 
-               workbook = XSSFTestDataSamples.openSampleWorkbook("workbookProtection_workbook_structure_protected.xlsx");
+               workbook = openSampleWorkbook("workbookProtection_workbook_structure_protected.xlsx");
                assertTrue(workbook.isStructureLocked());
                assertFalse(workbook.isWindowsLocked());
                assertFalse(workbook.isRevisionLocked());
 
-               workbook = XSSFTestDataSamples.openSampleWorkbook("workbookProtection_workbook_windows_protected.xlsx");
+               workbook = openSampleWorkbook("workbookProtection_workbook_windows_protected.xlsx");
                assertTrue(workbook.isWindowsLocked());
                assertFalse(workbook.isStructureLocked());
                assertFalse(workbook.isRevisionLocked());
 
-               workbook = XSSFTestDataSamples.openSampleWorkbook("workbookProtection_workbook_revision_protected.xlsx");
+               workbook = openSampleWorkbook("workbookProtection_workbook_revision_protected.xlsx");
                assertTrue(workbook.isRevisionLocked());
                assertFalse(workbook.isWindowsLocked());
                assertFalse(workbook.isStructureLocked());
        }
 
-       public void testShouldWriteStructureLock() throws Exception {
-               XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("workbookProtection_not_protected.xlsx");
+    @Test
+       public void shouldWriteStructureLock() throws Exception {
+               XSSFWorkbook workbook = openSampleWorkbook("workbookProtection_not_protected.xlsx");
                assertFalse(workbook.isStructureLocked());
 
                workbook.lockStructure();
@@ -63,8 +115,9 @@ public class TestWorkbookProtection extends TestCase {
                assertFalse(workbook.isStructureLocked());
        }
 
-       public void testShouldWriteWindowsLock() throws Exception {
-               XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("workbookProtection_not_protected.xlsx");
+    @Test
+       public void shouldWriteWindowsLock() throws Exception {
+               XSSFWorkbook workbook = openSampleWorkbook("workbookProtection_not_protected.xlsx");
                assertFalse(workbook.isWindowsLocked());
 
                workbook.lockWindows();
@@ -76,8 +129,9 @@ public class TestWorkbookProtection extends TestCase {
                assertFalse(workbook.isWindowsLocked());
        }
 
-       public void testShouldWriteRevisionLock() throws Exception {
-               XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("workbookProtection_not_protected.xlsx");
+    @Test
+       public void shouldWriteRevisionLock() throws Exception {
+               XSSFWorkbook workbook = openSampleWorkbook("workbookProtection_not_protected.xlsx");
                assertFalse(workbook.isRevisionLocked());
 
                workbook.lockRevision();
@@ -89,22 +143,32 @@ public class TestWorkbookProtection extends TestCase {
                assertFalse(workbook.isRevisionLocked());
        }
 
+    @SuppressWarnings("resource")
+    @Test
+    public void testHashPassword() throws Exception {
+        XSSFWorkbook wb = new XSSFWorkbook();
+        wb.lockRevision();
+        wb.setRevisionsPassword("test", HashAlgorithm.sha1);
+        
+        wb = writeOutAndReadBack(wb);
+        
+        assertTrue(wb.isRevisionLocked());
+        assertTrue(wb.validateRevisionsPassword("test"));
+    }
+    
+    @SuppressWarnings("resource")
+    @Test
        public void testIntegration() throws Exception {
                XSSFWorkbook wb = new XSSFWorkbook();
                wb.createSheet("Testing purpose sheet");
                assertFalse(wb.isRevisionLocked());
 
                wb.lockRevision();
+               wb.setRevisionsPassword("test", null);
 
-               File tempFile = TempFile.createTempFile("workbookProtection", ".xlsx");
-               FileOutputStream out = new FileOutputStream(tempFile);
-               wb.write(out);
-               out.close();
-
-               FileInputStream inputStream = new FileInputStream(tempFile);
-               XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
-               inputStream.close();
-
-               assertTrue(workbook.isRevisionLocked());
+               wb = writeOutAndReadBack(wb);
+               
+               assertTrue(wb.isRevisionLocked());
+               assertTrue(wb.validateRevisionsPassword("test"));
        }
 }
index 9621b91eb47612b0deadfe5baa28a3fdd17247a6..d0e118ae20788175702cc5f307e106225b3248e2 100644 (file)
@@ -49,7 +49,8 @@ import org.xml.sax.SAXException;
  * @author Roberto Manicardi
  */
 public final class TestXSSFExportToXML extends TestCase {
-       public void testExportToXML() throws Exception {
+
+    public void testExportToXML() throws Exception {
 
                XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXMLMappings.xlsx");
 
@@ -580,4 +581,37 @@ public final class TestXSSFExportToXML extends TestCase {
        }
        assertTrue(found);
    }
+
+   public void testRefElementsInXmlSchema_Bugzilla_56730() throws Exception {
+       XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56730.xlsx");
+       
+       boolean found = false;
+       for (POIXMLDocumentPart p : wb.getRelations()) {
+           
+           if (!(p instanceof MapInfo)) {
+               continue;
+           }
+           MapInfo mapInfo = (MapInfo) p;
+           
+           XSSFMap map = mapInfo.getXSSFMapById(1);
+           
+           assertNotNull("XSSFMap is null", map);
+           
+           XSSFExportToXml exporter = new XSSFExportToXml(map);
+           ByteArrayOutputStream os = new ByteArrayOutputStream();
+           exporter.exportToXML(os, true);
+           String xmlData = os.toString("UTF-8");
+           
+           assertNotNull(xmlData);
+           assertFalse(xmlData.equals(""));
+           
+           assertEquals("2014-12-31", xmlData.split("<DATE>")[1].split("</DATE>")[0].trim());
+           assertEquals("12.5", xmlData.split("<REFELEMENT>")[1].split("</REFELEMENT>")[0].trim());
+           
+           parseXML(xmlData);
+           
+           found = true;
+       }
+       assertTrue(found);
+   }
 }
index 80e5f525103d15588ef6e241077788c7daa479d2..0932177e000aebf2dd5c754155c53912a8659a5d 100644 (file)
@@ -32,7 +32,7 @@ public final class TestCalculationChain extends TestCase {
         CalculationChain chain = wb.getCalculationChain();
         //the bean holding the reference to the formula to be deleted
         CTCalcCell c = chain.getCTCalcChain().getCArray(0);
-        int cnt = chain.getCTCalcChain().getCList().size();
+        int cnt = chain.getCTCalcChain().sizeOfCArray();
         assertEquals(10, c.getI());
         assertEquals("E1", c.getR());
 
@@ -44,7 +44,7 @@ public final class TestCalculationChain extends TestCase {
 
         //the count of items is less by one
         c = chain.getCTCalcChain().getCArray(0);
-        int cnt2 =  chain.getCTCalcChain().getCList().size();
+        int cnt2 =  chain.getCTCalcChain().sizeOfCArray();
         assertEquals(cnt - 1, cnt2);
         //the first item in the calculation chain is the former second one
         assertEquals(10, c.getI());
index 7a4e98320fe995f0d6c9af561a7c4b1b77c4c791..33e91e8d3f1bc86b19fe0364a516e340de992da6 100644 (file)
@@ -50,7 +50,7 @@ public final class TestMapInfo extends TestCase {
 
                 assertNotNull(ctMapInfo);
 
-                assertEquals(1, ctMapInfo.getSchemaList().size());
+                assertEquals(1, ctMapInfo.sizeOfSchemaArray());
 
                 for (XSSFMap map : mapInfo.getAllXSSFMaps()) {
                     Node xmlSchema = map.getSchema();
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/model/TestThemesTable.java b/src/ooxml/testcases/org/apache/poi/xssf/model/TestThemesTable.java
new file mode 100644 (file)
index 0000000..40ab5b4
--- /dev/null
@@ -0,0 +1,78 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.xssf.model;\r
+\r
+import static org.junit.Assert.assertEquals;\r
+\r
+import java.io.FileOutputStream;\r
+\r
+import org.apache.commons.codec.binary.Hex;\r
+import org.apache.poi.ss.usermodel.CellStyle;\r
+import org.apache.poi.ss.usermodel.Row;\r
+import org.apache.poi.xssf.XSSFTestDataSamples;\r
+import org.apache.poi.xssf.usermodel.XSSFCellStyle;\r
+import org.apache.poi.xssf.usermodel.XSSFColor;\r
+import org.apache.poi.xssf.usermodel.XSSFFont;\r
+import org.apache.poi.xssf.usermodel.XSSFRow;\r
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;\r
+import org.junit.Test;\r
+\r
+public class TestThemesTable {\r
+    private String testFile = "Themes.xlsx";\r
+\r
+    @Test\r
+    public void testThemesTableColors() throws Exception {\r
+        XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook(testFile);\r
+        String rgbExpected[] = {\r
+            "ffffff", // Lt1\r
+            "000000", // Dk1\r
+            "eeece1", // Lt2\r
+            "1f497d", // DK2\r
+            "4f81bd", // Accent1\r
+            "c0504d", // Accent2\r
+            "9bbb59", // Accent3\r
+            "8064a2", // Accent4\r
+            "4bacc6", // Accent5\r
+            "f79646", // Accent6\r
+            "0000ff", // Hlink\r
+            "800080"  // FolHlink\r
+        };\r
+        boolean createFile = false;\r
+        int i=0;\r
+        for (Row row : workbook.getSheetAt(0)) {\r
+            XSSFFont font = ((XSSFRow)row).getCell(0).getCellStyle().getFont();\r
+            XSSFColor color = font.getXSSFColor();\r
+            assertEquals("Failed color theme "+i, rgbExpected[i], Hex.encodeHexString(color.getRgb()));\r
+            long themeIdx = font.getCTFont().getColorArray(0).getTheme();\r
+            assertEquals("Failed color theme "+i, i, themeIdx);\r
+            if (createFile) {\r
+                XSSFCellStyle cs = (XSSFCellStyle)row.getSheet().getWorkbook().createCellStyle();\r
+                cs.setFillForegroundColor(color);\r
+                cs.setFillPattern(CellStyle.SOLID_FOREGROUND);\r
+                row.createCell(1).setCellStyle(cs);\r
+            }\r
+            i++;\r
+        }\r
+        \r
+        if (createFile) {\r
+            FileOutputStream fos = new FileOutputStream("foobaa.xlsx");\r
+            workbook.write(fos);\r
+            fos.close();\r
+        }\r
+    }\r
+}
\ No newline at end of file
index a08dffd2d1c9aeb937f2b46dd6300135f167d5aa..79bbc4ea6d9c5b30a3eeab8f8be0342443ea70b7 100644 (file)
@@ -964,9 +964,9 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
        assertEquals(text, cell.getStringCellValue());
        
        assertEquals(4, cell.getRichStringCellValue().numFormattingRuns());
-       assertEquals("Use", cell.getRichStringCellValue().getCTRst().getRList().get(0).getT());
+       assertEquals("Use", cell.getRichStringCellValue().getCTRst().getRArray(0).getT());
        
-       String r3 = cell.getRichStringCellValue().getCTRst().getRList().get(2).getT();
+       String r3 = cell.getRichStringCellValue().getCTRst().getRArray(2).getT();
        assertEquals("line.\n", r3.substring(r3.length()-6));
 
        // Save and re-check
index f99d007090135e183a18dd8cc5d1fc0873c60106..92fc298ab518d5b1a3174aa8aa638582f312f602 100644 (file)
@@ -45,6 +45,7 @@ public class TestXSSFColGrouping extends TestCase {
      * Tests that POI doesn't produce "col" elements without "width" attribute. 
      * POI-52186
      */
+    @SuppressWarnings("deprecation")
     public void testNoColsWithoutWidthWhenGrouping() {
                XSSFWorkbook wb = new XSSFWorkbook();
                XSSFSheet sheet = wb.createSheet("test");
@@ -60,7 +61,7 @@ public class TestXSSFColGrouping extends TestCase {
         
         CTCols cols = sheet.getCTWorksheet().getColsArray(0);
         logger.log(POILogger.DEBUG, "test52186/cols:" + cols);
-        for (CTCol col : cols.getColList()) {
+        for (CTCol col : cols.getColArray()) {
                        assertTrue("Col width attribute is unset: " + col.toString(), col.isSetWidth());
                }
     }
@@ -69,6 +70,7 @@ public class TestXSSFColGrouping extends TestCase {
      * Tests that POI doesn't produce "col" elements without "width" attribute. 
      * POI-52186
      */
+    @SuppressWarnings("deprecation")
     public void testNoColsWithoutWidthWhenGroupingAndCollapsing() {
                XSSFWorkbook wb = new XSSFWorkbook();
                XSSFSheet sheet = wb.createSheet("test");
@@ -90,7 +92,7 @@ public class TestXSSFColGrouping extends TestCase {
                assertEquals("Unexpected width of column "+ i, 5000, sheet.getColumnWidth(i));
         }
         cols = sheet.getCTWorksheet().getColsArray(0);
-        for (CTCol col : cols.getColList()) {
+        for (CTCol col : cols.getColArray()) {
                        assertTrue("Col width attribute is unset: " + col.toString(), col.isSetWidth());
                }
     }
index b2aa11447b32b1f957a0b8e6d549422419a60d81..6f31cc49f4b5e85dfa36fe9b4ff5b6f274b6cf71 100644 (file)
@@ -24,49 +24,49 @@ import org.apache.poi.xssf.XSSFTestDataSamples;
 public final class TestXSSFColor extends TestCase {
    public void testIndexedColour() throws Exception {
       XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48779.xlsx");
-      
+
       // Check the CTColor is as expected
       XSSFColor indexed = wb.getCellStyleAt((short)1).getFillBackgroundXSSFColor();
       assertEquals(true, indexed.getCTColor().isSetIndexed());
       assertEquals(64, indexed.getCTColor().getIndexed());
       assertEquals(false, indexed.getCTColor().isSetRgb());
       assertEquals(null, indexed.getCTColor().getRgb());
-      
+
       // Now check the XSSFColor
       // Note - 64 is a special "auto" one with no rgb equiv
       assertEquals(64, indexed.getIndexed());
       assertEquals(null, indexed.getRgb());
       assertEquals(null, indexed.getRgbWithTint());
       assertEquals(null, indexed.getARGBHex());
-      
+
       // Now move to one with indexed rgb values
       indexed.setIndexed(59);
       assertEquals(true, indexed.getCTColor().isSetIndexed());
       assertEquals(59, indexed.getCTColor().getIndexed());
       assertEquals(false, indexed.getCTColor().isSetRgb());
       assertEquals(null, indexed.getCTColor().getRgb());
-      
+
       assertEquals(59, indexed.getIndexed());
       assertEquals("FF333300", indexed.getARGBHex());
-      
+
       assertEquals(3, indexed.getRgb().length);
       assertEquals(0x33, indexed.getRgb()[0]);
       assertEquals(0x33, indexed.getRgb()[1]);
       assertEquals(0x00, indexed.getRgb()[2]);
-      
+
       assertEquals(4, indexed.getARgb().length);
       assertEquals(-1, indexed.getARgb()[0]);
       assertEquals(0x33, indexed.getARgb()[1]);
       assertEquals(0x33, indexed.getARgb()[2]);
       assertEquals(0x00, indexed.getARgb()[3]);
-      
+
       // You don't get tinted indexed colours, sorry...
       assertEquals(null, indexed.getRgbWithTint());
    }
-   
+
    public void testRGBColour() throws Exception {
       XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50299.xlsx");
-      
+
       // Check the CTColor is as expected
       XSSFColor rgb3 = wb.getCellStyleAt((short)25).getFillForegroundXSSFColor();
       assertEquals(false, rgb3.getCTColor().isSetIndexed());
@@ -75,37 +75,39 @@ public final class TestXSSFColor extends TestCase {
       assertEquals(-0.34999, rgb3.getCTColor().getTint(), 0.00001);
       assertEquals(true,  rgb3.getCTColor().isSetRgb());
       assertEquals(3,     rgb3.getCTColor().getRgb().length);
-      
+
       // Now check the XSSFColor
       assertEquals(0, rgb3.getIndexed());
       assertEquals(-0.34999, rgb3.getTint(), 0.00001);
-      
+
       assertEquals("FFFFFFFF", rgb3.getARGBHex());
       assertEquals(3, rgb3.getRgb().length);
       assertEquals(-1, rgb3.getRgb()[0]);
       assertEquals(-1, rgb3.getRgb()[1]);
       assertEquals(-1,  rgb3.getRgb()[2]);
-      
+
       assertEquals(4, rgb3.getARgb().length);
       assertEquals(-1, rgb3.getARgb()[0]);
       assertEquals(-1, rgb3.getARgb()[1]);
       assertEquals(-1,  rgb3.getARgb()[2]);
       assertEquals(-1,  rgb3.getARgb()[3]);
-      
+
       // Tint doesn't have the alpha
+      // tint = -0.34999
+      // 255 * (1 + tint) = 165 truncated
+      // or (byte) -91 (which is 165 - 256)
       assertEquals(3, rgb3.getRgbWithTint().length);
-      assertEquals(0, rgb3.getRgbWithTint()[0]);
-      assertEquals(0,  rgb3.getRgbWithTint()[1]);
-      assertEquals(0,  rgb3.getRgbWithTint()[2]);
-      
-      // Set the colour to black, will get translated internally
-      // (Excel stores 3 colour white and black wrong!)
-      rgb3.setRgb(new byte[] {-1,-1,-1});
-      assertEquals("FFFFFFFF", rgb3.getARGBHex());
+      assertEquals(-91, rgb3.getRgbWithTint()[0]);
+      assertEquals(-91,  rgb3.getRgbWithTint()[1]);
+      assertEquals(-91,  rgb3.getRgbWithTint()[2]);
+
+      // Set the color to black (no theme).
+      rgb3.setRgb(new byte[] {0, 0, 0});
+      assertEquals("FF000000", rgb3.getARGBHex());
       assertEquals(0, rgb3.getCTColor().getRgb()[0]);
       assertEquals(0, rgb3.getCTColor().getRgb()[1]);
       assertEquals(0, rgb3.getCTColor().getRgb()[2]);
-      
+
       // Set another, is fine
       rgb3.setRgb(new byte[] {16,17,18});
       assertEquals("FF101112", rgb3.getARGBHex());
@@ -113,45 +115,45 @@ public final class TestXSSFColor extends TestCase {
       assertEquals(0x11, rgb3.getCTColor().getRgb()[1]);
       assertEquals(0x12, rgb3.getCTColor().getRgb()[2]);
    }
-   
+
    public void testARGBColour() throws Exception {
       XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48779.xlsx");
-      
+
       // Check the CTColor is as expected
       XSSFColor rgb4 = wb.getCellStyleAt((short)1).getFillForegroundXSSFColor();
       assertEquals(false, rgb4.getCTColor().isSetIndexed());
       assertEquals(0,     rgb4.getCTColor().getIndexed());
       assertEquals(true, rgb4.getCTColor().isSetRgb());
       assertEquals(4, rgb4.getCTColor().getRgb().length);
-      
+
       // Now check the XSSFColor
       assertEquals(0, rgb4.getIndexed());
       assertEquals(0.0, rgb4.getTint());
-      
+
       assertEquals("FFFF0000", rgb4.getARGBHex());
       assertEquals(3, rgb4.getRgb().length);
       assertEquals(-1, rgb4.getRgb()[0]);
       assertEquals(0,  rgb4.getRgb()[1]);
       assertEquals(0,  rgb4.getRgb()[2]);
-      
+
       assertEquals(4, rgb4.getARgb().length);
       assertEquals(-1, rgb4.getARgb()[0]);
       assertEquals(-1, rgb4.getARgb()[1]);
       assertEquals(0,  rgb4.getARgb()[2]);
       assertEquals(0,  rgb4.getARgb()[3]);
-      
+
       // Tint doesn't have the alpha
       assertEquals(3, rgb4.getRgbWithTint().length);
       assertEquals(-1, rgb4.getRgbWithTint()[0]);
       assertEquals(0,  rgb4.getRgbWithTint()[1]);
       assertEquals(0,  rgb4.getRgbWithTint()[2]);
 
-      
+
       // Turn on tinting, and check it behaves
       // TODO These values are suspected to be wrong...
       rgb4.setTint(0.4);
       assertEquals(0.4, rgb4.getTint());
-      
+
       assertEquals(3, rgb4.getRgbWithTint().length);
       assertEquals(-1, rgb4.getRgbWithTint()[0]);
       assertEquals(102,  rgb4.getRgbWithTint()[1]);
index 5d93fa121510de393684eddb84a7e0003341e055..3bbe6f2788588203439edd620af5542cf7cc755d 100644 (file)
@@ -65,7 +65,7 @@ public final class TestXSSFFont extends BaseTestFont{
 
 
                xssfFont.setBold(true);
-               assertEquals(ctFont.getBList().size(),1);
+               assertEquals(ctFont.sizeOfBArray(),1);
                assertEquals(true, ctFont.getBArray(0).getVal());
        }
 
@@ -135,7 +135,7 @@ public final class TestXSSFFont extends BaseTestFont{
                assertEquals(false, xssfFont.getItalic());
 
                xssfFont.setItalic(true);
-               assertEquals(ctFont.getIList().size(),1);
+               assertEquals(ctFont.sizeOfIArray(),1);
                assertEquals(true, ctFont.getIArray(0).getVal());
                assertEquals(true,ctFont.getIArray(0).getVal());
        }
@@ -150,7 +150,7 @@ public final class TestXSSFFont extends BaseTestFont{
                assertEquals(false, xssfFont.getStrikeout());
 
                xssfFont.setStrikeout(true);
-               assertEquals(ctFont.getStrikeList().size(),1);
+               assertEquals(ctFont.sizeOfStrikeArray(),1);
                assertEquals(true, ctFont.getStrikeArray(0).getVal());
                assertEquals(true,ctFont.getStrikeArray(0).getVal());
        }
@@ -191,11 +191,11 @@ public final class TestXSSFFont extends BaseTestFont{
                assertEquals(Font.U_SINGLE, xssfFont.getUnderline());
 
                xssfFont.setUnderline(Font.U_DOUBLE);
-               assertEquals(ctFont.getUList().size(),1);
+               assertEquals(ctFont.sizeOfUArray(),1);
                assertEquals(STUnderlineValues.DOUBLE,ctFont.getUArray(0).getVal());
 
                xssfFont.setUnderline(FontUnderline.DOUBLE_ACCOUNTING);
-               assertEquals(ctFont.getUList().size(),1);
+               assertEquals(ctFont.sizeOfUArray(),1);
                assertEquals(STUnderlineValues.DOUBLE_ACCOUNTING,ctFont.getUArray(0).getVal());
        }
 
index e5cf432fbe734af5586d31d83e6343ac9bc385cc..a813bce8166ff04e917de69b30a0ab234e4c12f8 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.xssf.usermodel;
 
+import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -288,48 +289,212 @@ public final class TestXSSFFormulaEvaluation extends BaseTestFormulaEvaluator {
         }
     }
     
-    public void testMultisheetFormulaEval() {
+    public void testMultisheetFormulaEval() throws IOException {
        XSSFWorkbook wb = new XSSFWorkbook();
-               XSSFSheet sheet1 = wb.createSheet("Sheet1");
-               XSSFSheet sheet2 = wb.createSheet("Sheet2");
-               XSSFSheet sheet3 = wb.createSheet("Sheet3");
-               
-               // sheet1 A1
-               XSSFCell cell = sheet1.createRow(0).createCell(0);
-               cell.setCellType(Cell.CELL_TYPE_NUMERIC);
-               cell.setCellValue(1.0);
-               
-               // sheet2 A1
-               cell = sheet2.createRow(0).createCell(0);
-               cell.setCellType(Cell.CELL_TYPE_NUMERIC);
-               cell.setCellValue(1.0);
-               
-               // sheet2 B1
-               cell = sheet2.getRow(0).createCell(1);
-               cell.setCellType(Cell.CELL_TYPE_NUMERIC);
-               cell.setCellValue(1.0);
-               
-               // sheet3 A1
-               cell = sheet3.createRow(0).createCell(0);
-               cell.setCellType(Cell.CELL_TYPE_NUMERIC);
-               cell.setCellValue(1.0);
-               
-               // sheet1 A2 formulae
-               cell = sheet1.createRow(1).createCell(0);
-               cell.setCellType(Cell.CELL_TYPE_FORMULA);
-               cell.setCellFormula("SUM(Sheet1:Sheet3!A1)");
-               
-               // sheet1 A3 formulae
-               cell = sheet1.createRow(2).createCell(0);
-               cell.setCellType(Cell.CELL_TYPE_FORMULA);
-               cell.setCellFormula("SUM(Sheet1:Sheet3!A1:B1)");
-               
-               wb.getCreationHelper().createFormulaEvaluator().evaluateAll();
-               
-               cell = sheet1.getRow(1).getCell(0);
-               assertEquals(3.0, cell.getNumericCellValue());
-               
-               cell = sheet1.getRow(2).getCell(0);
-               assertEquals(4.0, cell.getNumericCellValue());
+       try {
+               XSSFSheet sheet1 = wb.createSheet("Sheet1");
+               XSSFSheet sheet2 = wb.createSheet("Sheet2");
+               XSSFSheet sheet3 = wb.createSheet("Sheet3");
+               
+               // sheet1 A1
+               XSSFCell cell = sheet1.createRow(0).createCell(0);
+               cell.setCellType(Cell.CELL_TYPE_NUMERIC);
+               cell.setCellValue(1.0);
+               
+               // sheet2 A1
+               cell = sheet2.createRow(0).createCell(0);
+               cell.setCellType(Cell.CELL_TYPE_NUMERIC);
+               cell.setCellValue(1.0);
+               
+               // sheet2 B1
+               cell = sheet2.getRow(0).createCell(1);
+               cell.setCellType(Cell.CELL_TYPE_NUMERIC);
+               cell.setCellValue(1.0);
+               
+               // sheet3 A1
+               cell = sheet3.createRow(0).createCell(0);
+               cell.setCellType(Cell.CELL_TYPE_NUMERIC);
+               cell.setCellValue(1.0);
+               
+               // sheet1 A2 formulae
+               cell = sheet1.createRow(1).createCell(0);
+               cell.setCellType(Cell.CELL_TYPE_FORMULA);
+               cell.setCellFormula("SUM(Sheet1:Sheet3!A1)");
+               
+               // sheet1 A3 formulae
+               cell = sheet1.createRow(2).createCell(0);
+               cell.setCellType(Cell.CELL_TYPE_FORMULA);
+               cell.setCellFormula("SUM(Sheet1:Sheet3!A1:B1)");
+               
+               wb.getCreationHelper().createFormulaEvaluator().evaluateAll();
+               
+               cell = sheet1.getRow(1).getCell(0);
+               assertEquals(3.0, cell.getNumericCellValue());
+               
+               cell = sheet1.getRow(2).getCell(0);
+               assertEquals(4.0, cell.getNumericCellValue());
+       } finally {
+           wb.close();
+       }
        }
+
+    public void testBug55843() throws IOException {
+        XSSFWorkbook wb = new XSSFWorkbook();
+        try {
+            XSSFSheet sheet = wb.createSheet("test");
+            XSSFRow row = sheet.createRow(0);
+            XSSFRow row2 = sheet.createRow(1);
+            XSSFCell cellA2 = row2.createCell(0, Cell.CELL_TYPE_FORMULA);
+            XSSFCell cellB1 = row.createCell(1, Cell.CELL_TYPE_NUMERIC);
+            cellB1.setCellValue(10);
+            XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
+            cellA2.setCellFormula("IF(B1=0,\"\",((ROW()-ROW(A$1))*12))");
+            CellValue evaluate = formulaEvaluator.evaluate(cellA2);
+            System.out.println(evaluate);
+            assertEquals("12.0", evaluate.formatAsString());
+
+            cellA2.setCellFormula("IF(NOT(B1=0),((ROW()-ROW(A$1))*12),\"\")");
+            CellValue evaluateN = formulaEvaluator.evaluate(cellA2);
+            System.out.println(evaluateN);
+            
+            assertEquals(evaluate.toString(), evaluateN.toString());
+            assertEquals("12.0", evaluateN.formatAsString());
+        } finally {
+            wb.close();
+        }
+    }
+    
+    public void testBug55843a() throws IOException {
+        XSSFWorkbook wb = new XSSFWorkbook();
+        try {
+            XSSFSheet sheet = wb.createSheet("test");
+            XSSFRow row = sheet.createRow(0);
+            XSSFRow row2 = sheet.createRow(1);
+            XSSFCell cellA2 = row2.createCell(0, Cell.CELL_TYPE_FORMULA);
+            XSSFCell cellB1 = row.createCell(1, Cell.CELL_TYPE_NUMERIC);
+            cellB1.setCellValue(10);
+            XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
+            cellA2.setCellFormula("IF(B1=0,\"\",((ROW(A$1))))");
+            CellValue evaluate = formulaEvaluator.evaluate(cellA2);
+            System.out.println(evaluate);
+            assertEquals("1.0", evaluate.formatAsString());
+
+            cellA2.setCellFormula("IF(NOT(B1=0),((ROW(A$1))),\"\")");
+            CellValue evaluateN = formulaEvaluator.evaluate(cellA2);
+            System.out.println(evaluateN);
+            
+            assertEquals(evaluate.toString(), evaluateN.toString());
+            assertEquals("1.0", evaluateN.formatAsString());
+        } finally {
+            wb.close();
+        }
+    }    
+
+    public void testBug55843b() throws IOException {
+        XSSFWorkbook wb = new XSSFWorkbook();
+        try {
+            XSSFSheet sheet = wb.createSheet("test");
+            XSSFRow row = sheet.createRow(0);
+            XSSFRow row2 = sheet.createRow(1);
+            XSSFCell cellA2 = row2.createCell(0, Cell.CELL_TYPE_FORMULA);
+            XSSFCell cellB1 = row.createCell(1, Cell.CELL_TYPE_NUMERIC);
+            cellB1.setCellValue(10);
+            XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
+
+            cellA2.setCellFormula("IF(B1=0,\"\",((ROW())))");
+            CellValue evaluate = formulaEvaluator.evaluate(cellA2);
+            System.out.println(evaluate);
+            assertEquals("2.0", evaluate.formatAsString());
+            
+            cellA2.setCellFormula("IF(NOT(B1=0),((ROW())),\"\")");
+            CellValue evaluateN = formulaEvaluator.evaluate(cellA2);
+            System.out.println(evaluateN);
+            
+            assertEquals(evaluate.toString(), evaluateN.toString());
+            assertEquals("2.0", evaluateN.formatAsString());
+        } finally {
+            wb.close();
+        }
+    }
+    
+    public void testBug55843c() throws IOException {
+        XSSFWorkbook wb = new XSSFWorkbook();
+        try {
+            XSSFSheet sheet = wb.createSheet("test");
+            XSSFRow row = sheet.createRow(0);
+            XSSFRow row2 = sheet.createRow(1);
+            XSSFCell cellA2 = row2.createCell(0, Cell.CELL_TYPE_FORMULA);
+            XSSFCell cellB1 = row.createCell(1, Cell.CELL_TYPE_NUMERIC);
+            cellB1.setCellValue(10);
+            XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
+            
+            cellA2.setCellFormula("IF(NOT(B1=0),((ROW())))");
+            CellValue evaluateN = formulaEvaluator.evaluate(cellA2);
+            System.out.println(evaluateN);
+            assertEquals("2.0", evaluateN.formatAsString());
+        } finally {
+            wb.close();
+        }
+    }
+    
+    public void testBug55843d() throws IOException {
+        XSSFWorkbook wb = new XSSFWorkbook();
+        try {
+            XSSFSheet sheet = wb.createSheet("test");
+            XSSFRow row = sheet.createRow(0);
+            XSSFRow row2 = sheet.createRow(1);
+            XSSFCell cellA2 = row2.createCell(0, Cell.CELL_TYPE_FORMULA);
+            XSSFCell cellB1 = row.createCell(1, Cell.CELL_TYPE_NUMERIC);
+            cellB1.setCellValue(10);
+            XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
+            
+            cellA2.setCellFormula("IF(NOT(B1=0),((ROW())),\"\")");
+            CellValue evaluateN = formulaEvaluator.evaluate(cellA2);
+            System.out.println(evaluateN);
+            assertEquals("2.0", evaluateN.formatAsString());
+        } finally {
+            wb.close();
+        }
+    }
+
+    public void testBug55843e() throws IOException {
+        XSSFWorkbook wb = new XSSFWorkbook();
+        try {
+            XSSFSheet sheet = wb.createSheet("test");
+            XSSFRow row = sheet.createRow(0);
+            XSSFRow row2 = sheet.createRow(1);
+            XSSFCell cellA2 = row2.createCell(0, Cell.CELL_TYPE_FORMULA);
+            XSSFCell cellB1 = row.createCell(1, Cell.CELL_TYPE_NUMERIC);
+            cellB1.setCellValue(10);
+            XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
+
+            cellA2.setCellFormula("IF(B1=0,\"\",((ROW())))");
+            CellValue evaluate = formulaEvaluator.evaluate(cellA2);
+            System.out.println(evaluate);
+            assertEquals("2.0", evaluate.formatAsString());
+        } finally {
+            wb.close();
+        }
+    }
+    
+
+    public void testBug55843f() throws IOException {
+        XSSFWorkbook wb = new XSSFWorkbook();
+        try {
+            XSSFSheet sheet = wb.createSheet("test");
+            XSSFRow row = sheet.createRow(0);
+            XSSFRow row2 = sheet.createRow(1);
+            XSSFCell cellA2 = row2.createCell(0, Cell.CELL_TYPE_FORMULA);
+            XSSFCell cellB1 = row.createCell(1, Cell.CELL_TYPE_NUMERIC);
+            cellB1.setCellValue(10);
+            XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
+
+            cellA2.setCellFormula("IF(B1=0,\"\",IF(B1=10,3,4))");
+            CellValue evaluate = formulaEvaluator.evaluate(cellA2);
+            System.out.println(evaluate);
+            assertEquals("3.0", evaluate.formatAsString());
+        } finally {
+            wb.close();
+        }
+    }    
 }
index 40f8b065ad98e5cbc37e00bea14b97fbf092e256..5a45219ac38452e5a351a11a688aaf5193160667 100644 (file)
@@ -308,22 +308,22 @@ public final class TestXSSFRichTextString extends TestCase {
 
         str = new XSSFRichTextString("Incorrect\nLine-Breaking");
         str.applyFont(0, 8, font);
-        t1 = str.getCTRst().getRList().get(0).xgetT();
-        t2 = str.getCTRst().getRList().get(1).xgetT();
+        t1 = str.getCTRst().getRArray(0).xgetT();
+        t2 = str.getCTRst().getRArray(1).xgetT();
         assertEquals("<xml-fragment>Incorrec</xml-fragment>", t1.xmlText());
         assertEquals("<xml-fragment>t\nLine-Breaking</xml-fragment>", t2.xmlText());
 
         str = new XSSFRichTextString("Incorrect\nLine-Breaking");
         str.applyFont(0, 9, font);
-        t1 = str.getCTRst().getRList().get(0).xgetT();
-        t2 = str.getCTRst().getRList().get(1).xgetT();
+        t1 = str.getCTRst().getRArray(0).xgetT();
+        t2 = str.getCTRst().getRArray(1).xgetT();
         assertEquals("<xml-fragment>Incorrect</xml-fragment>", t1.xmlText());
         assertEquals("<xml-fragment xml:space=\"preserve\">\nLine-Breaking</xml-fragment>", t2.xmlText());
 
         str = new XSSFRichTextString("Incorrect\n Line-Breaking");
         str.applyFont(0, 9, font);
-        t1 = str.getCTRst().getRList().get(0).xgetT();
-        t2 = str.getCTRst().getRList().get(1).xgetT();
+        t1 = str.getCTRst().getRArray(0).xgetT();
+        t2 = str.getCTRst().getRArray(1).xgetT();
         assertEquals("<xml-fragment>Incorrect</xml-fragment>", t1.xmlText());
         assertEquals("<xml-fragment xml:space=\"preserve\">\n Line-Breaking</xml-fragment>", t2.xmlText());
 
@@ -333,15 +333,15 @@ public final class TestXSSFRichTextString extends TestCase {
         assertEquals("<xml-fragment xml:space=\"preserve\">Tab\tseparated\n</xml-fragment>", t1.xmlText());
 
         str.applyFont(0, 3, font);
-        t1 = str.getCTRst().getRList().get(0).xgetT();
-        t2 = str.getCTRst().getRList().get(1).xgetT();
+        t1 = str.getCTRst().getRArray(0).xgetT();
+        t2 = str.getCTRst().getRArray(1).xgetT();
         assertEquals("<xml-fragment>Tab</xml-fragment>", t1.xmlText());
         assertEquals("<xml-fragment xml:space=\"preserve\">\tseparated\n</xml-fragment>", t2.xmlText());
 
         str = new XSSFRichTextString("Tab\tseparated\n");
         str.applyFont(0, 4, font);
-        t1 = str.getCTRst().getRList().get(0).xgetT();
-        t2 = str.getCTRst().getRList().get(1).xgetT();
+        t1 = str.getCTRst().getRArray(0).xgetT();
+        t2 = str.getCTRst().getRArray(1).xgetT();
         // YK: don't know why, but XmlBeans converts leading tab characters to spaces
         //assertEquals("<xml-fragment>Tab\t</xml-fragment>", t1.xmlText());
         assertEquals("<xml-fragment xml:space=\"preserve\">separated\n</xml-fragment>", t2.xmlText());
@@ -349,9 +349,9 @@ public final class TestXSSFRichTextString extends TestCase {
         str = new XSSFRichTextString("\n\n\nNew Line\n\n");
         str.applyFont(0, 3, font);
         str.applyFont(11, 13, font);
-        t1 = str.getCTRst().getRList().get(0).xgetT();
-        t2 = str.getCTRst().getRList().get(1).xgetT();
-        t3 = str.getCTRst().getRList().get(2).xgetT();
+        t1 = str.getCTRst().getRArray(0).xgetT();
+        t2 = str.getCTRst().getRArray(1).xgetT();
+        t3 = str.getCTRst().getRArray(2).xgetT();
         // YK: don't know why, but XmlBeans converts leading tab characters to spaces
         assertEquals("<xml-fragment xml:space=\"preserve\">\n\n\n</xml-fragment>", t1.xmlText());
         assertEquals("<xml-fragment>New Line</xml-fragment>", t2.xmlText());
index 44342781a888847e5ec6b324c9883dd546b6aa48..5c91032defce1a979ae1481dd656482f102f3e89 100644 (file)
@@ -19,6 +19,8 @@ package org.apache.poi.xssf.usermodel;
 
 import static junit.framework.TestCase.assertNotNull;
 import static junit.framework.TestCase.assertTrue;
+import static org.apache.poi.xssf.XSSFTestDataSamples.openSampleWorkbook;
+import static org.apache.poi.xssf.XSSFTestDataSamples.writeOutAndReadBack;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotSame;
@@ -26,10 +28,14 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.fail;
 
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.poi.hssf.HSSFTestDataSamples;
-import org.apache.poi.hssf.record.PasswordRecord;
+import org.apache.poi.poifs.crypt.CryptoFunctions;
+import org.apache.poi.poifs.crypt.HashAlgorithm;
 import org.apache.poi.ss.usermodel.AutoFilter;
 import org.apache.poi.ss.usermodel.BaseTestSheet;
 import org.apache.poi.ss.usermodel.Cell;
@@ -41,7 +47,6 @@ import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.ss.util.AreaReference;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.CellReference;
-import org.apache.poi.util.HexDump;
 import org.apache.poi.xssf.SXSSFITestDataProvider;
 import org.apache.poi.xssf.XSSFITestDataProvider;
 import org.apache.poi.xssf.XSSFTestDataSamples;
@@ -293,6 +298,7 @@ public final class TestXSSFSheet extends BaseTestSheet {
         CellRangeAddress region_1 = CellRangeAddress.valueOf("A1:B2");
         CellRangeAddress region_2 = CellRangeAddress.valueOf("C3:D4");
         CellRangeAddress region_3 = CellRangeAddress.valueOf("E5:F6");
+        CellRangeAddress region_4 = CellRangeAddress.valueOf("G7:H8");
         sheet.addMergedRegion(region_1);
         sheet.addMergedRegion(region_2);
         sheet.addMergedRegion(region_3);
@@ -306,6 +312,17 @@ public final class TestXSSFSheet extends BaseTestSheet {
         assertEquals(0, sheet.getNumMergedRegions());
         assertNull(" CTMergeCells should be deleted after removing the last merged " +
                 "region on the sheet.", sheet.getCTWorksheet().getMergeCells());
+        sheet.addMergedRegion(region_1);
+        sheet.addMergedRegion(region_2);
+        sheet.addMergedRegion(region_3);
+        sheet.addMergedRegion(region_4);
+        // test invalid indexes OOBE
+        Set<Integer> rmIdx = new HashSet<Integer>(Arrays.asList(5,6));
+        sheet.removeMergedRegions(rmIdx);
+        rmIdx = new HashSet<Integer>(Arrays.asList(1,3));
+        sheet.removeMergedRegions(rmIdx);
+        assertEquals("A1:B2", ctWorksheet.getMergeCells().getMergeCellArray(0).getRef());
+        assertEquals("E5:F6", ctWorksheet.getMergeCells().getMergeCellArray(1).getRef());
     }
 
     @Test
@@ -335,6 +352,7 @@ public final class TestXSSFSheet extends BaseTestSheet {
 
 
     @Test
+    @SuppressWarnings("deprecation")
     public void groupUngroupColumn() {
         XSSFWorkbook workbook = new XSSFWorkbook();
         XSSFSheet sheet = workbook.createSheet();
@@ -344,36 +362,36 @@ public final class TestXSSFSheet extends BaseTestSheet {
         sheet.groupColumn(10, 11);
         CTCols cols = sheet.getCTWorksheet().getColsArray(0);
         assertEquals(2, cols.sizeOfColArray());
-        List<CTCol> colArray = cols.getColList();
+        CTCol[] colArray = cols.getColArray();
         assertNotNull(colArray);
-        assertEquals(2 + 1, colArray.get(0).getMin()); // 1 based
-        assertEquals(7 + 1, colArray.get(0).getMax()); // 1 based
-        assertEquals(1, colArray.get(0).getOutlineLevel());
+        assertEquals(2 + 1, colArray[0].getMin()); // 1 based
+        assertEquals(7 + 1, colArray[0].getMax()); // 1 based
+        assertEquals(1, colArray[0].getOutlineLevel());
 
         //two level
         sheet.groupColumn(1, 2);
         cols = sheet.getCTWorksheet().getColsArray(0);
         assertEquals(4, cols.sizeOfColArray());
-        colArray = cols.getColList();
-        assertEquals(2, colArray.get(1).getOutlineLevel());
+        colArray = cols.getColArray();
+        assertEquals(2, colArray[1].getOutlineLevel());
 
         //three level
         sheet.groupColumn(6, 8);
         sheet.groupColumn(2, 3);
         cols = sheet.getCTWorksheet().getColsArray(0);
         assertEquals(7, cols.sizeOfColArray());
-        colArray = cols.getColList();
-        assertEquals(3, colArray.get(1).getOutlineLevel());
+        colArray = cols.getColArray();
+        assertEquals(3, colArray[1].getOutlineLevel());
         assertEquals(3, sheet.getCTWorksheet().getSheetFormatPr().getOutlineLevelCol());
 
         sheet.ungroupColumn(8, 10);
-        colArray = cols.getColList();
+        colArray = cols.getColArray();
         //assertEquals(3, colArray[1].getOutlineLevel());
 
         sheet.ungroupColumn(4, 6);
         sheet.ungroupColumn(2, 2);
-        colArray = cols.getColList();
-        assertEquals(4, colArray.size());
+        colArray = cols.getColArray();
+        assertEquals(4, colArray.length);
         assertEquals(2, sheet.getCTWorksheet().getSheetFormatPr().getOutlineLevelCol());
     }
 
@@ -758,9 +776,8 @@ public final class TestXSSFSheet extends BaseTestSheet {
         XSSFSheet xs = sheet;
         CTWorksheet cts = xs.getCTWorksheet();
 
-        List<CTCols> cols_s = cts.getColsList();
-        assertEquals(1, cols_s.size());
-        CTCols cols = cols_s.get(0);
+        assertEquals(1, cts.sizeOfColsArray());
+        CTCols cols = cts.getColsArray(0);
         assertEquals(1, cols.sizeOfColArray());
         CTCol col = cols.getColArray(0);
 
@@ -773,9 +790,8 @@ public final class TestXSSFSheet extends BaseTestSheet {
         // Now set another
         sheet.setColumnWidth(3, 33 * 256);
 
-        cols_s = cts.getColsList();
-        assertEquals(1, cols_s.size());
-        cols = cols_s.get(0);
+        assertEquals(1, cts.sizeOfColsArray());
+        cols = cts.getColsArray(0);
         assertEquals(2, cols.sizeOfColArray());
 
         col = cols.getColArray(0);
@@ -960,6 +976,7 @@ public final class TestXSSFSheet extends BaseTestSheet {
      * but CTRows are kept in ascending order
      */
     @Test
+    @SuppressWarnings("deprecation")
     public void createRow() {
         XSSFWorkbook workbook = new XSSFWorkbook();
         XSSFSheet sheet = workbook.createSheet();
@@ -983,27 +1000,27 @@ public final class TestXSSFSheet extends BaseTestSheet {
         row3.createCell(5);
 
 
-        List<CTRow> xrow = sheetData.getRowList();
-        assertEquals(3, xrow.size());
+        CTRow[] xrow = sheetData.getRowArray();
+        assertEquals(3, xrow.length);
 
         //rows are sorted: {0, 1, 2}
-        assertEquals(4, xrow.get(0).sizeOfCArray());
-        assertEquals(1, xrow.get(0).getR());
-        assertTrue(xrow.get(0).equals(row3.getCTRow()));
+        assertEquals(4, xrow[0].sizeOfCArray());
+        assertEquals(1, xrow[0].getR());
+        assertTrue(xrow[0].equals(row3.getCTRow()));
 
-        assertEquals(3, xrow.get(1).sizeOfCArray());
-        assertEquals(2, xrow.get(1).getR());
-        assertTrue(xrow.get(1).equals(row2.getCTRow()));
+        assertEquals(3, xrow[1].sizeOfCArray());
+        assertEquals(2, xrow[1].getR());
+        assertTrue(xrow[1].equals(row2.getCTRow()));
 
-        assertEquals(2, xrow.get(2).sizeOfCArray());
-        assertEquals(3, xrow.get(2).getR());
-        assertTrue(xrow.get(2).equals(row1.getCTRow()));
+        assertEquals(2, xrow[2].sizeOfCArray());
+        assertEquals(3, xrow[2].getR());
+        assertTrue(xrow[2].equals(row1.getCTRow()));
 
-        List<CTCell> xcell = xrow.get(0).getCList();
-        assertEquals("D1", xcell.get(0).getR());
-        assertEquals("A1", xcell.get(1).getR());
-        assertEquals("C1", xcell.get(2).getR());
-        assertEquals("F1", xcell.get(3).getR());
+        CTCell[] xcell = xrow[0].getCArray();
+        assertEquals("D1", xcell[0].getR());
+        assertEquals("A1", xcell[1].getR());
+        assertEquals("C1", xcell[2].getR());
+        assertEquals("F1", xcell[3].getR());
 
         //re-creating a row does NOT add extra data to the parent
         row2 = sheet.createRow(1);
@@ -1015,25 +1032,25 @@ public final class TestXSSFSheet extends BaseTestSheet {
         workbook = XSSFTestDataSamples.writeOutAndReadBack(workbook);
         sheet = workbook.getSheetAt(0);
         wsh = sheet.getCTWorksheet();
-        xrow = sheetData.getRowList();
-        assertEquals(3, xrow.size());
+        xrow = sheetData.getRowArray();
+        assertEquals(3, xrow.length);
 
         //rows are sorted: {0, 1, 2}
-        assertEquals(4, xrow.get(0).sizeOfCArray());
-        assertEquals(1, xrow.get(0).getR());
+        assertEquals(4, xrow[0].sizeOfCArray());
+        assertEquals(1, xrow[0].getR());
         //cells are now sorted
-        xcell = xrow.get(0).getCList();
-        assertEquals("A1", xcell.get(0).getR());
-        assertEquals("C1", xcell.get(1).getR());
-        assertEquals("D1", xcell.get(2).getR());
-        assertEquals("F1", xcell.get(3).getR());
+        xcell = xrow[0].getCArray();
+        assertEquals("A1", xcell[0].getR());
+        assertEquals("C1", xcell[1].getR());
+        assertEquals("D1", xcell[2].getR());
+        assertEquals("F1", xcell[3].getR());
 
 
-        assertEquals(0, xrow.get(1).sizeOfCArray());
-        assertEquals(2, xrow.get(1).getR());
+        assertEquals(0, xrow[1].sizeOfCArray());
+        assertEquals(2, xrow[1].getR());
 
-        assertEquals(2, xrow.get(2).sizeOfCArray());
-        assertEquals(3, xrow.get(2).getR());
+        assertEquals(2, xrow[2].sizeOfCArray());
+        assertEquals(3, xrow[2].getR());
 
     }
 
@@ -1068,13 +1085,27 @@ public final class TestXSSFSheet extends BaseTestSheet {
         assertTrue("sheet protection should be on", pr.isSetSheet());
         assertTrue("object protection should be on", pr.isSetObjects());
         assertTrue("scenario protection should be on", pr.isSetScenarios());
-        String hash = String.valueOf(HexDump.shortToHex(PasswordRecord.hashPassword(password))).substring(2);
-        assertEquals("well known value for top secret hash should be "+ hash, hash, pr.xgetPassword().getStringValue());
+        int hashVal = CryptoFunctions.createXorVerifier1(password);
+        int actualVal = Integer.parseInt(pr.xgetPassword().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());
     }
 
+    @Test
+    public void protectSheet_lowlevel_2013() {
+        String password = "test";
+        XSSFWorkbook wb = new XSSFWorkbook();
+        XSSFSheet xs = wb.createSheet();
+        xs.setSheetPassword(password, HashAlgorithm.sha384);
+        wb = writeOutAndReadBack(wb);
+        assertTrue(wb.getSheetAt(0).validateSheetPassword(password));
+        
+        wb = openSampleWorkbook("workbookProtection-sheet_password-2013.xlsx");
+        assertTrue(wb.getSheetAt(0).validateSheetPassword("pwd"));
+    }
+    
 
     @Test
     public void bug49966() {
index d7bfc2f769a19aa8fa7ee72976d67f3442b1e110..d3729e0c921b87e1d7423853a18458cb32df023d 100644 (file)
@@ -25,9 +25,11 @@ import org.apache.poi.ss.usermodel.Comment;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.CellUtil;
 import org.apache.poi.xssf.XSSFITestDataProvider;
 import org.apache.poi.xssf.XSSFTestDataSamples;
+import org.junit.Test;
 
 /**
  * @author Yegor Kozlov
@@ -187,4 +189,14 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows {
         assertEquals("Amdocs", comment.getAuthor());
         assertEquals("Amdocs:\ntest\n", comment.getString().getString());
        }
+
+       @Test
+       public void testBug55280() {
+        Workbook w = new XSSFWorkbook();
+        Sheet s = w.createSheet();
+        for (int row = 0; row < 5000; ++row)
+            s.addMergedRegion(new CellRangeAddress(row, row, 0, 3));
+
+        s.shiftRows(0, 4999, 1);        // takes a long time...
+       }
 }
index de7eff6be733bb47605fb0d9f353066a70f4fa6e..ccde5422454dd80ee569d7cdd258641527bf0de4 100644 (file)
 
 package org.apache.poi.xssf.usermodel;
 
-import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.xssf.XSSFTestDataSamples;
-import org.apache.poi.xssf.streaming.SXSSFWorkbook;
-import org.apache.poi.util.TempFile;
-import org.junit.Test;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTable;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -32,8 +27,13 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.util.TempFile;
+import org.apache.poi.xssf.XSSFTestDataSamples;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.junit.Test;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTable;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn;
 
 public final class TestXSSFTable {
 
@@ -41,6 +41,7 @@ public final class TestXSSFTable {
     }
 
     @Test
+    @SuppressWarnings("deprecation")
     public void bug56274() throws IOException {
         // read sample file
         XSSFWorkbook inputWorkbook = XSSFTestDataSamples.openSampleWorkbook("56274.xlsx");
@@ -60,13 +61,13 @@ public final class TestXSSFTable {
         // re-read the saved file and make sure headers in the xml are in the original order
         inputWorkbook = new org.apache.poi.xssf.usermodel.XSSFWorkbook(new FileInputStream(outputFile));
         CTTable ctTable = inputWorkbook.getSheetAt(0).getTables().get(0).getCTTable();
-        List<CTTableColumn> ctTableColumnList = ctTable.getTableColumns().getTableColumnList();
+        CTTableColumn[] ctTableColumnArray = ctTable.getTableColumns().getTableColumnArray();
 
         assertEquals("number of headers in xml table should match number of header cells in worksheet",
-                headers.size(), ctTableColumnList.size());
+                headers.size(), ctTableColumnArray.length);
         for (int i = 0; i < headers.size(); i++) {
             assertEquals("header name in xml table should match number of header cells in worksheet",
-                    headers.get(i), ctTableColumnList.get(i).getName());
+                    headers.get(i), ctTableColumnArray[i].getName());
         }
         assertTrue(outputFile.delete());
     }
index f50fb5dfa5c682452bfb0a8155c28216066e3b80..fd41ac672140407a746fa4c188768e9a5a862fe9 100644 (file)
@@ -704,7 +704,7 @@ public final class TestXSSFWorkbook extends BaseTestWorkbook {
         CTPivotCache pivotCache = wb.addPivotCache("0");
         //Ensures that pivotCaches is initiated
         assertTrue(ctWb.isSetPivotCaches());
-        assertSame(pivotCache, ctWb.getPivotCaches().getPivotCacheList().get(0));
+        assertSame(pivotCache, ctWb.getPivotCaches().getPivotCacheArray(0));
         assertEquals("0", pivotCache.getId());
     }
 
index 2ad4f5645d96b212f652a5985da2ef6925d118c4..b268410bfab5b64645bed718877b32c975239994 100644 (file)
@@ -31,34 +31,34 @@ import junit.framework.TestCase;
 
 
 public class TestXSSFCellFill extends TestCase {
-       
-       public void testGetFillBackgroundColor() {
-               CTFill ctFill = CTFill.Factory.newInstance();
-               XSSFCellFill cellFill = new XSSFCellFill(ctFill);
-               CTPatternFill ctPatternFill = ctFill.addNewPatternFill();
-               CTColor bgColor = ctPatternFill.addNewBgColor();
-               assertNotNull(cellFill.getFillBackgroundColor());
-               bgColor.setIndexed(2);
-               assertEquals(2, cellFill.getFillBackgroundColor().getIndexed());
-       }
-       
-       public void testGetFillForegroundColor() {
-               CTFill ctFill = CTFill.Factory.newInstance();
-               XSSFCellFill cellFill = new XSSFCellFill(ctFill);
-               CTPatternFill ctPatternFill = ctFill.addNewPatternFill();
-               CTColor fgColor = ctPatternFill.addNewFgColor();
-               assertNotNull(cellFill.getFillForegroundColor());
-               fgColor.setIndexed(8);
-               assertEquals(8, cellFill.getFillForegroundColor().getIndexed());
-       }
-       
-       public void testGetSetPatternType() {
-               CTFill ctFill = CTFill.Factory.newInstance();
-               XSSFCellFill cellFill = new XSSFCellFill(ctFill);
-               CTPatternFill ctPatternFill = ctFill.addNewPatternFill();
-               ctPatternFill.setPatternType(STPatternType.SOLID);
-               //assertEquals(FillPatternType.SOLID_FOREGROUND.ordinal(), cellFill.getPatternType().ordinal());
-       }
+
+    public void testGetFillBackgroundColor() {
+        CTFill ctFill = CTFill.Factory.newInstance();
+        XSSFCellFill cellFill = new XSSFCellFill(ctFill);
+        CTPatternFill ctPatternFill = ctFill.addNewPatternFill();
+        CTColor bgColor = ctPatternFill.addNewBgColor();
+        assertNotNull(cellFill.getFillBackgroundColor());
+        bgColor.setIndexed(2);
+        assertEquals(2, cellFill.getFillBackgroundColor().getIndexed());
+    }
+
+    public void testGetFillForegroundColor() {
+        CTFill ctFill = CTFill.Factory.newInstance();
+        XSSFCellFill cellFill = new XSSFCellFill(ctFill);
+        CTPatternFill ctPatternFill = ctFill.addNewPatternFill();
+        CTColor fgColor = ctPatternFill.addNewFgColor();
+        assertNotNull(cellFill.getFillForegroundColor());
+        fgColor.setIndexed(8);
+        assertEquals(8, cellFill.getFillForegroundColor().getIndexed());
+    }
+
+    public void testGetSetPatternType() {
+        CTFill ctFill = CTFill.Factory.newInstance();
+        XSSFCellFill cellFill = new XSSFCellFill(ctFill);
+        CTPatternFill ctPatternFill = ctFill.addNewPatternFill();
+        ctPatternFill.setPatternType(STPatternType.SOLID);
+        //assertEquals(FillPatternType.SOLID_FOREGROUND.ordinal(), cellFill.getPatternType().ordinal());
+    }
 
     public void testGetNotModifies() {
         CTFill ctFill = CTFill.Factory.newInstance();
@@ -75,11 +75,16 @@ public class TestXSSFCellFill extends TestCase {
         XSSFColor foregroundColor = cellWithThemeColor.getCellStyle().getFillForegroundXSSFColor();
         byte[] rgb = foregroundColor.getRgb();
         byte[] rgbWithTint = foregroundColor.getRgbWithTint();
-        assertEquals(rgb[0],-18);
-        assertEquals(rgb[1],-20);
-        assertEquals(rgb[2],-31);
-        assertEquals(rgbWithTint[0],-12);
-        assertEquals(rgbWithTint[1],-13);
-        assertEquals(rgbWithTint[2],-20);
+        // Dk2
+        assertEquals(rgb[0],31);
+        assertEquals(rgb[1],73);
+        assertEquals(rgb[2],125);
+        // Dk2, lighter 40% (tint is about 0.39998)
+        // 31 * (1.0 - 0.39998) + (255 - 255 * (1.0 - 0.39998)) = 120.59552 => 120 (byte)
+        // 73 * (1.0 - 0.39998) + (255 - 255 * (1.0 - 0.39998)) = 145.79636 => -111 (byte)
+        // 125 * (1.0 - 0.39998) + (255 - 255 * (1.0 - 0.39998)) = 176.99740 => -80 (byte)
+        assertEquals(rgbWithTint[0],120);
+        assertEquals(rgbWithTint[1],-111);
+        assertEquals(rgbWithTint[2],-80);
     }
 }
index 8ca6fc6f9bad6bd80d73a98d78ff9f89b65c86f8..a99e0f75ebc3eb5c98d0414712445d1b330b4ff5 100644 (file)
@@ -186,7 +186,7 @@ public final class TestColumnHelper extends TestCase {
         helper.addCleanColIntoCols(cols1, col9);
 
         // TODO - assert something interesting
-        assertEquals(12, cols1.getColList().size());
+        assertEquals(12, cols1.sizeOfColArray());
         assertEquals(1, cols1.getColArray(0).getMin());
         assertEquals(16750, cols1.getColArray(11).getMax());
     }
index 64f43c4a75a8a33b31174e199309447cfe908470..9fa8320bbaf5d4ea1a87e0bdcf76fffe416380f0 100644 (file)
@@ -27,39 +27,37 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol;
 public final class TestCTColComparator extends TestCase {
 
     public void testCompare() {
-        CTColComparator comparator = new CTColComparator();
         CTCol o1 = CTCol.Factory.newInstance();
         o1.setMin(1);
         o1.setMax(10);
         CTCol o2 = CTCol.Factory.newInstance();
         o2.setMin(11);
         o2.setMax(12);
-        assertEquals(-1, comparator.compare(o1, o2));
+        assertEquals(-1, CTColComparator.BY_MIN_MAX.compare(o1, o2));
         CTCol o3 = CTCol.Factory.newInstance();
         o3.setMin(5);
         o3.setMax(8);
         CTCol o4 = CTCol.Factory.newInstance();
         o4.setMin(5);
         o4.setMax(80);
-        assertEquals(-1, comparator.compare(o3, o4));
+        assertEquals(-1, CTColComparator.BY_MIN_MAX.compare(o3, o4));
     }
 
     public void testArraysSort() {
-        CTColComparator comparator = new CTColComparator();
         CTCol o1 = CTCol.Factory.newInstance();
         o1.setMin(1);
         o1.setMax(10);
         CTCol o2 = CTCol.Factory.newInstance();
         o2.setMin(11);
         o2.setMax(12);
-        assertEquals(-1, comparator.compare(o1, o2));
+        assertEquals(-1, CTColComparator.BY_MIN_MAX.compare(o1, o2));
         CTCol o3 = CTCol.Factory.newInstance();
         o3.setMin(5);
         o3.setMax(80);
         CTCol o4 = CTCol.Factory.newInstance();
         o4.setMin(5);
         o4.setMax(8);
-        assertEquals(1, comparator.compare(o3, o4));
+        assertEquals(1, CTColComparator.BY_MIN_MAX.compare(o3, o4));
         CTCol[] cols = new CTCol[4];
         cols[0] = o1;
         cols[1] = o2;
@@ -67,7 +65,7 @@ public final class TestCTColComparator extends TestCase {
         cols[3] = o4;
         assertEquals(80, cols[2].getMax());
         assertEquals(8, cols[3].getMax());
-        Arrays.sort(cols, comparator);
+        Arrays.sort(cols, CTColComparator.BY_MIN_MAX);
         assertEquals(12, cols[3].getMax());
         assertEquals(8, cols[1].getMax());
         assertEquals(80, cols[2].getMax());
index 09c1c1636fdf93c2bfd8cd851e95e17d46f390a4..7621404b8d08c504d66b7a244c6e852bafb47cd8 100644 (file)
@@ -19,6 +19,7 @@ package org.apache.poi.xwpf.usermodel;
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.Arrays;
 import java.util.List;
 
 import junit.framework.TestCase;
@@ -32,7 +33,6 @@ import org.apache.poi.openxml4j.opc.PackagePartName;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.apache.poi.openxml4j.opc.PackagingURIHelper;
 import org.apache.poi.openxml4j.opc.TargetMode;
-import org.apache.poi.util.ArrayUtil;
 import org.apache.poi.xwpf.XWPFTestDataSamples;
 import org.apache.xmlbeans.XmlCursor;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
@@ -234,7 +234,7 @@ public final class TestXWPFDocument extends TestCase {
         OutputStream os = newImagePart.getOutputStream();
         os.write(nature1);
            os.close();
-           XWPFHeader xwpfHeader = doc.getHeaderList().get(0);
+           XWPFHeader xwpfHeader = doc.getHeaderArray(0);
            PackageRelationship relationship = xwpfHeader.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, jpgRelation.getRelation());
            XWPFPictureData newPicData = new XWPFPictureData(newImagePart,relationship);
            /* new part is now ready to rumble */
@@ -307,7 +307,7 @@ public final class TestXWPFDocument extends TestCase {
            String id1 = doc.addPictureData(newPic, Document.PICTURE_TYPE_JPEG);
            assertEquals(2,doc.getAllPackagePictures().size());
            /* copy data, to avoid instance-equality */
-           byte[] newPicCopy = ArrayUtil.copyOf(newPic, newPic.length);
+           byte[] newPicCopy = Arrays.copyOf(newPic, newPic.length);
            String id2 = doc.addPictureData(newPicCopy, Document.PICTURE_TYPE_JPEG);
            assertEquals(id1,id2);
            doc.getPackage().revert();
@@ -317,13 +317,13 @@ public final class TestXWPFDocument extends TestCase {
            XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_2.docx");
            assertEquals(1,doc.getAllPictures().size());
            assertEquals(1,doc.getAllPackagePictures().size());
-           assertEquals(1,doc.getHeaderList().get(0).getAllPictures().size());
+           assertEquals(1,doc.getHeaderArray(0).getAllPictures().size());
            doc.getPackage().revert();
        }
        
        public void testPictureHandlingComplex() throws IOException, InvalidFormatException {
            XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_3.docx");
-           XWPFHeader xwpfHeader = doc.getHeaderList().get(0);
+           XWPFHeader xwpfHeader = doc.getHeaderArray(0);
 
            assertEquals(3,doc.getAllPictures().size());
         assertEquals(3,xwpfHeader.getAllPictures().size());
index 7d6e83c3037540177acd2c1710c983565b56427c..c8f179680f7fac093f0742a966f7a55df21c53d5 100644 (file)
@@ -24,6 +24,9 @@ import java.util.List;
 import junit.framework.TestCase;
 
 import org.apache.poi.xwpf.XWPFTestDataSamples;
+import org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture;
+import org.openxmlformats.schemas.drawingml.x2006.picture.PicDocument;
+import org.openxmlformats.schemas.drawingml.x2006.picture.impl.PicDocumentImpl;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTInd;
@@ -39,9 +42,6 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STLineSpacingRule;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTextAlignment;
-import        org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture;
-import org.openxmlformats.schemas.drawingml.x2006.picture.PicDocument;
-import org.openxmlformats.schemas.drawingml.x2006.picture.impl.PicDocumentImpl;
 
 /**
  * Tests for XWPF Paragraphs
@@ -62,7 +62,7 @@ public final class TestXWPFParagraph extends TestCase {
         assertEquals(1, ps.size());
         XWPFParagraph p = ps.get(0);
 
-        assertEquals(5, p.getCTP().getRList().size());
+        assertEquals(5, p.getCTP().sizeOfRArray());
         assertEquals("First header column!\tMid header\tRight header!", p
                 .getText());
     }
@@ -234,6 +234,7 @@ public final class TestXWPFParagraph extends TestCase {
         assertEquals(STOnOff.TRUE, ppr.getPageBreakBefore().getVal());
     }
 
+    @SuppressWarnings("deprecation")
     public void testBookmarks() throws IOException {
         XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("bookmarks.docx");
         XWPFParagraph paragraph = doc.getParagraphs().get(0);
@@ -242,7 +243,7 @@ public final class TestXWPFParagraph extends TestCase {
         assertEquals(0, paragraph.getCTP().sizeOfBookmarkEndArray());
         CTBookmark ctBookmark = paragraph.getCTP().getBookmarkStartArray(0);
         assertEquals("poi", ctBookmark.getName());
-        for(CTBookmark bookmark : paragraph.getCTP().getBookmarkStartList()) {
+        for(CTBookmark bookmark : paragraph.getCTP().getBookmarkStartArray()) {
            assertEquals("poi", bookmark.getName());
         }
     }
index d3c42e912f0bbefb9b015dff9fc55ceca47a7540..618618f92cef29eb528329b0ea25916440d0ec43 100644 (file)
@@ -180,7 +180,7 @@ public class TestXWPFRun extends TestCase {
         run.addCarriageReturn();
         run.setText("T2");
         run.addCarriageReturn();
-        assertEquals(3, run.getCTR().getCrList().size());
+        assertEquals(3, run.getCTR().sizeOfCrArray());
         
         assertEquals("T1\n\nT2\n", run.toString());
     }
@@ -200,8 +200,8 @@ public class TestXWPFRun extends TestCase {
         run.setText("T2");
         run.addTab();
         run.setText("T3");
-        assertEquals(1, run.getCTR().getCrList().size());
-        assertEquals(1, run.getCTR().getTabList().size());
+        assertEquals(1, run.getCTR().sizeOfCrArray());
+        assertEquals(1, run.getCTR().sizeOfTabArray());
         
         assertEquals("T1\nT2\tT3", run.toString());
     }
index 5d13185cfcfbdf73ac2fb29a757287633837c35b..fc2c3a28e66ade4a4e054a26b1a60950b72903da 100644 (file)
@@ -116,6 +116,6 @@ public class TestXWPFStyles extends TestCase {
         ex.setName("ex1");
         XWPFLatentStyles ls = new XWPFLatentStyles(latentStyles);
         assertEquals(true, ls.isLatentStyle("ex1"));
-
+        assertEquals(false, ls.isLatentStyle("notex1"));
     }
 }
index 58cf567a58947fadc7eb570ab23ae8a44e47d17e..918afdb3c808f1e69c8d261db486bd4bbc7c0966 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.hwpf.model;\r
 \r
-import org.apache.poi.util.ArrayUtil;\r
 import org.apache.poi.util.LittleEndian;\r
 import org.apache.poi.util.POILogFactory;\r
 import org.apache.poi.util.POILogger;\r
 \r
+import java.util.Arrays;\r
+\r
 public class NilPICFAndBinData\r
 {\r
 \r
@@ -52,8 +53,8 @@ public class NilPICFAndBinData
 \r
         // skip the 62 ignored bytes\r
         int binaryLength = lcb - cbHeader;\r
-        this._binData = ArrayUtil.copyOfRange( data, offset + cbHeader,\r
-                offset + cbHeader + binaryLength );\r
+        this._binData = Arrays.copyOfRange(data, offset + cbHeader,\r
+                offset + cbHeader + binaryLength);\r
     }\r
 \r
     public byte[] getBinData()\r
index 6e114d8dab1ca6e058a1cc3f4ac8eca5056a0826..5f02c1ed4a02fef96829b4da1f27f74ceb056801 100644 (file)
@@ -23,7 +23,6 @@ import java.util.Arrays;
 import java.util.NoSuchElementException;
 
 import org.apache.poi.hwpf.model.io.HWPFOutputStream;
-import org.apache.poi.util.ArrayUtil;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
@@ -118,10 +117,10 @@ public class PlfLfo
     {
         final int newLfoMac = _lfoMac + 1;
 
-        _rgLfo = ArrayUtil.copyOf( _rgLfo, new LFO[newLfoMac] );
+        _rgLfo = Arrays.copyOf(_rgLfo, newLfoMac);
         _rgLfo[_lfoMac + 1] = lfo;
 
-        _rgLfoData = ArrayUtil.copyOf( _rgLfoData, new LFOData[_lfoMac + 1] );
+        _rgLfoData = Arrays.copyOf(_rgLfoData, newLfoMac);
         _rgLfoData[_lfoMac + 1] = lfoData;
 
         this._lfoMac = newLfoMac;
index 5f721f92bed6d792b811f2153819aebe2d45027a..01c5d22e5df06ed38cac6e53d5eaa1823c0dc408 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.hwpf.model;\r
 \r
-import org.apache.poi.util.ArrayUtil;\r
 import org.apache.poi.util.LittleEndian;\r
 import org.apache.poi.util.StringUtil;\r
 \r
+import java.util.Arrays;\r
+\r
 /**\r
  * The STTB is a string table that is made up of a header that is followed by an\r
  * array of elements. The cData value specifies the number of elements that are\r
@@ -64,7 +65,7 @@ public class Sttb
     {\r
         this._cDataLength = cDataLength;\r
 \r
-        this._data = ArrayUtil.copyOf( data, new String[data.length] );\r
+        this._data = Arrays.copyOf(data, data.length);\r
 \r
         this._cbExtra = 0;\r
         this._extraData = null;\r
index 8b84477286eb17b435cd1e1a22a63892cab7c724..c829159a5c4e8eafddf2b5d3bec119c95845639e 100644 (file)
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.hssf.model;\r
-\r
-import junit.framework.TestCase;\r
-import org.apache.poi.ddf.*;\r
-import org.apache.poi.hssf.HSSFTestDataSamples;\r
-import org.apache.poi.hssf.record.CommonObjectDataSubRecord;\r
-import org.apache.poi.hssf.record.EscherAggregate;\r
-import org.apache.poi.hssf.record.ObjRecord;\r
-import org.apache.poi.hssf.usermodel.*;\r
-import org.apache.poi.ss.usermodel.Workbook;\r
-import org.apache.poi.util.HexDump;\r
-\r
-import java.io.IOException;\r
-\r
-/**\r
- * @author Evgeniy Berlog\r
- * date: 12.06.12\r
- */\r
-public class TestDrawingShapes extends TestCase {\r
-\r
-    /**\r
-     * HSSFShape tree bust be built correctly\r
-     * Check file with such records structure:\r
-     * -patriarch\r
-     * --shape\r
-     * --group\r
-     * ---group\r
-     * ----shape\r
-     * ----shape\r
-     * ---shape\r
-     * ---group\r
-     * ----shape\r
-     * ----shape\r
-     */\r
-    public void testDrawingGroups() {\r
-        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");\r
-        HSSFSheet sheet = wb.getSheet("groups");\r
-        HSSFPatriarch patriarch = sheet.getDrawingPatriarch();\r
-        assertEquals(patriarch.getChildren().size(), 2);\r
-        HSSFShapeGroup group = (HSSFShapeGroup) patriarch.getChildren().get(1);\r
-        assertEquals(3, group.getChildren().size());\r
-        HSSFShapeGroup group1 = (HSSFShapeGroup) group.getChildren().get(0);\r
-        assertEquals(2, group1.getChildren().size());\r
-        group1 = (HSSFShapeGroup) group.getChildren().get(2);\r
-        assertEquals(2, group1.getChildren().size());\r
-    }\r
-\r
-    public void testHSSFShapeCompatibility() {\r
-        HSSFSimpleShape shape = new HSSFSimpleShape(null, new HSSFClientAnchor());\r
-        shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);\r
-        assertEquals(0x08000040, shape.getLineStyleColor());\r
-        assertEquals(0x08000009, shape.getFillColor());\r
-        assertEquals(HSSFShape.LINEWIDTH_DEFAULT, shape.getLineWidth());\r
-        assertEquals(HSSFShape.LINESTYLE_SOLID, shape.getLineStyle());\r
-        assertFalse(shape.isNoFill());\r
-\r
-        AbstractShape sp = AbstractShape.createShape(shape, 1);\r
-        EscherContainerRecord spContainer = sp.getSpContainer();\r
-        EscherOptRecord opt =\r
-                spContainer.getChildById(EscherOptRecord.RECORD_ID);\r
-\r
-        assertEquals(7, opt.getEscherProperties().size());\r
-        assertEquals(true,\r
-                ((EscherBoolProperty) opt.lookup(EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE)).isTrue());\r
-        assertEquals(0x00000004,\r
-                ((EscherSimpleProperty) opt.lookup(EscherProperties.GEOMETRY__SHAPEPATH)).getPropertyValue());\r
-        assertEquals(0x08000009,\r
-                ((EscherSimpleProperty) opt.lookup(EscherProperties.FILL__FILLCOLOR)).getPropertyValue());\r
-        assertEquals(true,\r
-                ((EscherBoolProperty) opt.lookup(EscherProperties.FILL__NOFILLHITTEST)).isTrue());\r
-        assertEquals(0x08000040,\r
-                ((EscherSimpleProperty) opt.lookup(EscherProperties.LINESTYLE__COLOR)).getPropertyValue());\r
-        assertEquals(true,\r
-                ((EscherBoolProperty) opt.lookup(EscherProperties.LINESTYLE__NOLINEDRAWDASH)).isTrue());\r
-        assertEquals(true,\r
-                ((EscherBoolProperty) opt.lookup(EscherProperties.GROUPSHAPE__PRINT)).isTrue());\r
-    }\r
-\r
-    public void testDefaultPictureSettings() {\r
-        HSSFPicture picture = new HSSFPicture(null, new HSSFClientAnchor());\r
-        assertEquals(picture.getLineWidth(), HSSFShape.LINEWIDTH_DEFAULT);\r
-        assertEquals(picture.getFillColor(), HSSFShape.FILL__FILLCOLOR_DEFAULT);\r
-        assertEquals(picture.getLineStyle(), HSSFShape.LINESTYLE_NONE);\r
-        assertEquals(picture.getLineStyleColor(), HSSFShape.LINESTYLE__COLOR_DEFAULT);\r
-        assertEquals(picture.isNoFill(), false);\r
-        assertEquals(picture.getPictureIndex(), -1);//not set yet\r
-    }\r
-\r
-    /**\r
-     * No NullPointerException should appear\r
-     */\r
-    public void testDefaultSettingsWithEmptyContainer() {\r
-        EscherContainerRecord container = new EscherContainerRecord();\r
-        EscherOptRecord opt = new EscherOptRecord();\r
-        opt.setRecordId(EscherOptRecord.RECORD_ID);\r
-        container.addChildRecord(opt);\r
-        ObjRecord obj = new ObjRecord();\r
-        CommonObjectDataSubRecord cod = new CommonObjectDataSubRecord();\r
-        cod.setObjectType(HSSFSimpleShape.OBJECT_TYPE_PICTURE);\r
-        obj.addSubRecord(cod);\r
-        HSSFPicture picture = new HSSFPicture(container, obj);\r
-\r
-        assertEquals(picture.getLineWidth(), HSSFShape.LINEWIDTH_DEFAULT);\r
-        assertEquals(picture.getFillColor(), HSSFShape.FILL__FILLCOLOR_DEFAULT);\r
-        assertEquals(picture.getLineStyle(), HSSFShape.LINESTYLE_DEFAULT);\r
-        assertEquals(picture.getLineStyleColor(), HSSFShape.LINESTYLE__COLOR_DEFAULT);\r
-        assertEquals(picture.isNoFill(), HSSFShape.NO_FILL_DEFAULT);\r
-        assertEquals(picture.getPictureIndex(), -1);//not set yet\r
-    }\r
-\r
-    /**\r
-     * create a rectangle, save the workbook, read back and verify that all shape properties are there\r
-     */\r
-    public void testReadWriteRectangle() throws IOException {\r
-\r
-        HSSFWorkbook wb = new HSSFWorkbook();\r
-        HSSFSheet sheet = wb.createSheet();\r
-\r
-        HSSFPatriarch drawing = sheet.createDrawingPatriarch();\r
-        HSSFClientAnchor anchor = new HSSFClientAnchor(10, 10, 50, 50, (short) 2, 2, (short) 4, 4);\r
-        anchor.setAnchorType(2);\r
-        assertEquals(anchor.getAnchorType(), 2);\r
-\r
-        HSSFSimpleShape rectangle = drawing.createSimpleShape(anchor);\r
-        rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);\r
-        rectangle.setLineWidth(10000);\r
-        rectangle.setFillColor(777);\r
-        assertEquals(rectangle.getFillColor(), 777);\r
-        assertEquals(10000, rectangle.getLineWidth());\r
-        rectangle.setLineStyle(10);\r
-        assertEquals(10, rectangle.getLineStyle());\r
-        assertEquals(rectangle.getWrapText(), HSSFSimpleShape.WRAP_SQUARE);\r
-        rectangle.setLineStyleColor(1111);\r
-        rectangle.setNoFill(true);\r
-        rectangle.setWrapText(HSSFSimpleShape.WRAP_NONE);\r
-        rectangle.setString(new HSSFRichTextString("teeeest"));\r
-        assertEquals(rectangle.getLineStyleColor(), 1111);\r
-        assertEquals(((EscherSimpleProperty)((EscherOptRecord)HSSFTestHelper.getEscherContainer(rectangle).getChildById(EscherOptRecord.RECORD_ID))\r
-                .lookup(EscherProperties.TEXT__TEXTID)).getPropertyValue(), "teeeest".hashCode());\r
-        assertEquals(rectangle.isNoFill(), true);\r
-        assertEquals(rectangle.getWrapText(), HSSFSimpleShape.WRAP_NONE);\r
-        assertEquals(rectangle.getString().getString(), "teeeest");\r
-\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-        sheet = wb.getSheetAt(0);\r
-        drawing = sheet.getDrawingPatriarch();\r
-        assertEquals(1, drawing.getChildren().size());\r
-\r
-        HSSFSimpleShape rectangle2 =\r
-                (HSSFSimpleShape) drawing.getChildren().get(0);\r
-        assertEquals(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE,\r
-                rectangle2.getShapeType());\r
-        assertEquals(10000, rectangle2.getLineWidth());\r
-        assertEquals(10, rectangle2.getLineStyle());\r
-        assertEquals(anchor, rectangle2.getAnchor());\r
-        assertEquals(rectangle2.getLineStyleColor(), 1111);\r
-        assertEquals(rectangle2.getFillColor(), 777);\r
-        assertEquals(rectangle2.isNoFill(), true);\r
-        assertEquals(rectangle2.getString().getString(), "teeeest");\r
-        assertEquals(rectangle.getWrapText(), HSSFSimpleShape.WRAP_NONE);\r
-\r
-        rectangle2.setFillColor(3333);\r
-        rectangle2.setLineStyle(9);\r
-        rectangle2.setLineStyleColor(4444);\r
-        rectangle2.setNoFill(false);\r
-        rectangle2.setLineWidth(77);\r
-        rectangle2.getAnchor().setDx1(2);\r
-        rectangle2.getAnchor().setDx2(3);\r
-        rectangle2.getAnchor().setDy1(4);\r
-        rectangle2.getAnchor().setDy2(5);\r
-        rectangle.setWrapText(HSSFSimpleShape.WRAP_BY_POINTS);\r
-        rectangle2.setString(new HSSFRichTextString("test22"));\r
-\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-        sheet = wb.getSheetAt(0);\r
-        drawing = sheet.getDrawingPatriarch();\r
-        assertEquals(1, drawing.getChildren().size());\r
-        rectangle2 = (HSSFSimpleShape) drawing.getChildren().get(0);\r
-        assertEquals(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE, rectangle2.getShapeType());\r
-        assertEquals(rectangle.getWrapText(), HSSFSimpleShape.WRAP_BY_POINTS);\r
-        assertEquals(77, rectangle2.getLineWidth());\r
-        assertEquals(9, rectangle2.getLineStyle());\r
-        assertEquals(rectangle2.getLineStyleColor(), 4444);\r
-        assertEquals(rectangle2.getFillColor(), 3333);\r
-        assertEquals(rectangle2.getAnchor().getDx1(), 2);\r
-        assertEquals(rectangle2.getAnchor().getDx2(), 3);\r
-        assertEquals(rectangle2.getAnchor().getDy1(), 4);\r
-        assertEquals(rectangle2.getAnchor().getDy2(), 5);\r
-        assertEquals(rectangle2.isNoFill(), false);\r
-        assertEquals(rectangle2.getString().getString(), "test22");\r
-\r
-        HSSFSimpleShape rect3 = drawing.createSimpleShape(new HSSFClientAnchor());\r
-        rect3.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-\r
-        drawing = wb.getSheetAt(0).getDrawingPatriarch();\r
-        assertEquals(drawing.getChildren().size(), 2);\r
-    }\r
-\r
-    public void testReadExistingImage() {\r
-        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");\r
-        HSSFSheet sheet = wb.getSheet("pictures");\r
-        HSSFPatriarch drawing = sheet.getDrawingPatriarch();\r
-        assertEquals(1, drawing.getChildren().size());\r
-        HSSFPicture picture = (HSSFPicture) drawing.getChildren().get(0);\r
-\r
-        assertEquals(picture.getPictureIndex(), 2);\r
-        assertEquals(picture.getLineStyleColor(), HSSFShape.LINESTYLE__COLOR_DEFAULT);\r
-        assertEquals(picture.getFillColor(), 0x5DC943);\r
-        assertEquals(picture.getLineWidth(), HSSFShape.LINEWIDTH_DEFAULT);\r
-        assertEquals(picture.getLineStyle(), HSSFShape.LINESTYLE_DEFAULT);\r
-        assertEquals(picture.isNoFill(), false);\r
-\r
-        picture.setPictureIndex(2);\r
-        assertEquals(picture.getPictureIndex(), 2);\r
-    }\r
-\r
-\r
-    /* assert shape properties when reading shapes from a existing workbook */\r
-    public void testReadExistingRectangle() {\r
-        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");\r
-        HSSFSheet sheet = wb.getSheet("rectangles");\r
-        HSSFPatriarch drawing = sheet.getDrawingPatriarch();\r
-        assertEquals(1, drawing.getChildren().size());\r
-\r
-        HSSFSimpleShape shape = (HSSFSimpleShape) drawing.getChildren().get(0);\r
-        assertEquals(shape.isNoFill(), false);\r
-        assertEquals(shape.getLineStyle(), HSSFShape.LINESTYLE_DASHDOTGEL);\r
-        assertEquals(shape.getLineStyleColor(), 0x616161);\r
-        assertEquals(HexDump.toHex(shape.getFillColor()), shape.getFillColor(), 0x2CE03D);\r
-        assertEquals(shape.getLineWidth(), HSSFShape.LINEWIDTH_ONE_PT * 2);\r
-        assertEquals(shape.getString().getString(), "POItest");\r
-        assertEquals(shape.getRotationDegree(), 27);\r
-    }\r
-\r
-    public void testShapeIds() {\r
-        HSSFWorkbook wb = new HSSFWorkbook();\r
-        HSSFSheet sheet1 = wb.createSheet();\r
-        HSSFPatriarch patriarch1 = sheet1.createDrawingPatriarch();\r
-        for (int i = 0; i < 2; i++) {\r
-            patriarch1.createSimpleShape(new HSSFClientAnchor());\r
-        }\r
-\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-        sheet1 = wb.getSheetAt(0);\r
-        patriarch1 = sheet1.getDrawingPatriarch();\r
-\r
-        EscherAggregate agg1 = HSSFTestHelper.getEscherAggregate(patriarch1);\r
-        // last shape ID cached in EscherDgRecord\r
-        EscherDgRecord dg1 =\r
-                agg1.getEscherContainer().getChildById(EscherDgRecord.RECORD_ID);\r
-        assertEquals(1026, dg1.getLastMSOSPID());\r
-\r
-        // iterate over shapes and check shapeId\r
-        EscherContainerRecord spgrContainer =\r
-                agg1.getEscherContainer().getChildContainers().get(0);\r
-        // root spContainer + 2 spContainers for shapes\r
-        assertEquals(3, spgrContainer.getChildRecords().size());\r
-\r
-        EscherSpRecord sp0 =\r
-                ((EscherContainerRecord) spgrContainer.getChild(0)).getChildById(EscherSpRecord.RECORD_ID);\r
-        assertEquals(1024, sp0.getShapeId());\r
-\r
-        EscherSpRecord sp1 =\r
-                ((EscherContainerRecord) spgrContainer.getChild(1)).getChildById(EscherSpRecord.RECORD_ID);\r
-        assertEquals(1025, sp1.getShapeId());\r
-\r
-        EscherSpRecord sp2 =\r
-                ((EscherContainerRecord) spgrContainer.getChild(2)).getChildById(EscherSpRecord.RECORD_ID);\r
-        assertEquals(1026, sp2.getShapeId());\r
-    }\r
-\r
-    /**\r
-     * Test get new id for shapes from existing file\r
-     * File already have for 1 shape on each sheet, because document must contain EscherDgRecord for each sheet\r
-     */\r
-    public void testAllocateNewIds() {\r
-        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("empty.xls");\r
-        HSSFSheet sheet = wb.getSheetAt(0);\r
-        HSSFPatriarch patriarch = sheet.getDrawingPatriarch();\r
-\r
-        /**\r
-         * 2048 - main SpContainer id\r
-         * 2049 - existing shape id\r
-         */\r
-        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 2050);\r
-        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 2051);\r
-        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 2052);\r
-\r
-        sheet = wb.getSheetAt(1);\r
-        patriarch = sheet.getDrawingPatriarch();\r
-\r
-        /**\r
-         * 3072 - main SpContainer id\r
-         * 3073 - existing shape id\r
-         */\r
-        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 3074);\r
-        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 3075);\r
-        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 3076);\r
-\r
-\r
-        sheet = wb.getSheetAt(2);\r
-        patriarch = sheet.getDrawingPatriarch();\r
-\r
-        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 1026);\r
-        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 1027);\r
-        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 1028);\r
-    }\r
-\r
-    public void testOpt() throws Exception {\r
-        HSSFWorkbook wb = new HSSFWorkbook();\r
-\r
-        // create a sheet with a text box\r
-        HSSFSheet sheet = wb.createSheet();\r
-        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();\r
-\r
-        HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());\r
-        EscherOptRecord opt1 = HSSFTestHelper.getOptRecord(textbox);\r
-        EscherOptRecord opt2 = HSSFTestHelper.getEscherContainer(textbox).getChildById(EscherOptRecord.RECORD_ID);\r
-        assertSame(opt1, opt2);\r
-    }\r
-    \r
-    public void testCorrectOrderInOptRecord(){\r
-        HSSFWorkbook wb = new HSSFWorkbook();\r
-        HSSFSheet sheet = wb.createSheet();\r
-        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();\r
-\r
-        HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());\r
-        EscherOptRecord opt = HSSFTestHelper.getOptRecord(textbox);    \r
-        \r
-        String opt1Str = opt.toXml();\r
-\r
-        textbox.setFillColor(textbox.getFillColor());\r
-        EscherContainerRecord container = HSSFTestHelper.getEscherContainer(textbox);\r
-        EscherOptRecord optRecord = container.getChildById(EscherOptRecord.RECORD_ID);\r
-        assertEquals(opt1Str, optRecord.toXml());\r
-        textbox.setLineStyle(textbox.getLineStyle());\r
-        assertEquals(opt1Str, optRecord.toXml());\r
-        textbox.setLineWidth(textbox.getLineWidth());\r
-        assertEquals(opt1Str, optRecord.toXml());\r
-        textbox.setLineStyleColor(textbox.getLineStyleColor());\r
-        assertEquals(opt1Str, optRecord.toXml());\r
-    }\r
-\r
-    public void testDgRecordNumShapes(){\r
-        HSSFWorkbook wb = new HSSFWorkbook();\r
-        HSSFSheet sheet = wb.createSheet();\r
-        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();\r
-\r
-        EscherAggregate aggregate = HSSFTestHelper.getEscherAggregate(patriarch);\r
-        EscherDgRecord dgRecord = (EscherDgRecord) aggregate.getEscherRecord(0).getChild(0);\r
-        assertEquals(dgRecord.getNumShapes(), 1);\r
-    }\r
-\r
-    public void testTextForSimpleShape(){\r
-        HSSFWorkbook wb = new HSSFWorkbook();\r
-        HSSFSheet sheet = wb.createSheet();\r
-        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();\r
-\r
-        HSSFSimpleShape shape = patriarch.createSimpleShape(new HSSFClientAnchor());\r
-        shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);\r
-\r
-        EscherAggregate agg = HSSFTestHelper.getEscherAggregate(patriarch);\r
-        assertEquals(agg.getShapeToObjMapping().size(), 2);\r
-\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-        sheet = wb.getSheetAt(0);\r
-        patriarch = sheet.getDrawingPatriarch();\r
-\r
-        shape = (HSSFSimpleShape) patriarch.getChildren().get(0);\r
-\r
-        agg = HSSFTestHelper.getEscherAggregate(patriarch);\r
-        assertEquals(agg.getShapeToObjMapping().size(), 2);\r
-\r
-        shape.setString(new HSSFRichTextString("string1"));\r
-        assertEquals(shape.getString().getString(), "string1");\r
-\r
-        assertNotNull(HSSFTestHelper.getEscherContainer(shape).getChildById(EscherTextboxRecord.RECORD_ID));\r
-        assertEquals(agg.getShapeToObjMapping().size(), 2);\r
-\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-        sheet = wb.getSheetAt(0);\r
-        patriarch = sheet.getDrawingPatriarch();\r
-\r
-        shape = (HSSFSimpleShape) patriarch.getChildren().get(0);\r
-\r
-        assertNotNull(HSSFTestHelper.getTextObjRecord(shape));\r
-        assertEquals(shape.getString().getString(), "string1");\r
-        assertNotNull(HSSFTestHelper.getEscherContainer(shape).getChildById(EscherTextboxRecord.RECORD_ID));\r
-        assertEquals(agg.getShapeToObjMapping().size(), 2);\r
-    }\r
-\r
-    public void testRemoveShapes(){\r
-        HSSFWorkbook wb = new HSSFWorkbook();\r
-        HSSFSheet sheet = wb.createSheet();\r
-        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();\r
-\r
-        HSSFSimpleShape rectangle = patriarch.createSimpleShape(new HSSFClientAnchor());\r
-        rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);\r
-\r
-        int idx = wb.addPicture(new byte[]{1,2,3}, Workbook.PICTURE_TYPE_JPEG);\r
-        patriarch.createPicture(new HSSFClientAnchor(), idx);\r
-\r
-        patriarch.createCellComment(new HSSFClientAnchor());\r
-\r
-        HSSFPolygon polygon = patriarch.createPolygon(new HSSFClientAnchor());\r
-        polygon.setPoints(new int[]{1,2}, new int[]{2,3});\r
-\r
-        patriarch.createTextbox(new HSSFClientAnchor());\r
-\r
-        HSSFShapeGroup group = patriarch.createGroup(new HSSFClientAnchor());\r
-        group.createTextbox(new HSSFChildAnchor());\r
-        group.createPicture(new HSSFChildAnchor(), idx);\r
-\r
-        assertEquals(patriarch.getChildren().size(), 6);\r
-        assertEquals(group.getChildren().size(), 2);\r
-\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 12);\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);\r
-\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-        sheet = wb.getSheetAt(0);\r
-        patriarch = sheet.getDrawingPatriarch();\r
-\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 12);\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);\r
-\r
-        assertEquals(patriarch.getChildren().size(), 6);\r
-\r
-        group = (HSSFShapeGroup) patriarch.getChildren().get(5);\r
-        group.removeShape(group.getChildren().get(0));\r
-\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 10);\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);\r
-\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-        sheet = wb.getSheetAt(0);\r
-        patriarch = sheet.getDrawingPatriarch();\r
-\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 10);\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);\r
-\r
-        group = (HSSFShapeGroup) patriarch.getChildren().get(5);\r
-        patriarch.removeShape(group);\r
-\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 8);\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);\r
-\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-        sheet = wb.getSheetAt(0);\r
-        patriarch = sheet.getDrawingPatriarch();\r
-\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 8);\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);\r
-        assertEquals(patriarch.getChildren().size(), 5);\r
-\r
-        HSSFShape shape = patriarch.getChildren().get(0);\r
-        patriarch.removeShape(shape);\r
-\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 6);\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);\r
-        assertEquals(patriarch.getChildren().size(), 4);\r
-\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-        sheet = wb.getSheetAt(0);\r
-        patriarch = sheet.getDrawingPatriarch();\r
-\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 6);\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);\r
-        assertEquals(patriarch.getChildren().size(), 4);\r
-\r
-        HSSFPicture picture = (HSSFPicture) patriarch.getChildren().get(0);\r
-        patriarch.removeShape(picture);\r
-\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 5);\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);\r
-        assertEquals(patriarch.getChildren().size(), 3);\r
-\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-        sheet = wb.getSheetAt(0);\r
-        patriarch = sheet.getDrawingPatriarch();\r
-\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 5);\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);\r
-        assertEquals(patriarch.getChildren().size(), 3);\r
-\r
-        HSSFComment comment = (HSSFComment) patriarch.getChildren().get(0);\r
-        patriarch.removeShape(comment);\r
-\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 3);\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);\r
-        assertEquals(patriarch.getChildren().size(), 2);\r
-\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-        sheet = wb.getSheetAt(0);\r
-        patriarch = sheet.getDrawingPatriarch();\r
-\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 3);\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);\r
-        assertEquals(patriarch.getChildren().size(), 2);\r
-\r
-        polygon = (HSSFPolygon) patriarch.getChildren().get(0);\r
-        patriarch.removeShape(polygon);\r
-\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 2);\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);\r
-        assertEquals(patriarch.getChildren().size(), 1);\r
-\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-        sheet = wb.getSheetAt(0);\r
-        patriarch = sheet.getDrawingPatriarch();\r
-\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 2);\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);\r
-        assertEquals(patriarch.getChildren().size(), 1);\r
-\r
-        HSSFTextbox textbox = (HSSFTextbox) patriarch.getChildren().get(0);\r
-        patriarch.removeShape(textbox);\r
-\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 0);\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);\r
-        assertEquals(patriarch.getChildren().size(), 0);\r
-\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-        sheet = wb.getSheetAt(0);\r
-        patriarch = sheet.getDrawingPatriarch();\r
-\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 0);\r
-        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);\r
-        assertEquals(patriarch.getChildren().size(), 0);\r
-    }\r
-\r
-    public void testShapeFlip(){\r
-        HSSFWorkbook wb = new HSSFWorkbook();\r
-        HSSFSheet sheet = wb.createSheet();\r
-        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();\r
-\r
-        HSSFSimpleShape rectangle = patriarch.createSimpleShape(new HSSFClientAnchor());\r
-        rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);\r
-\r
-        assertEquals(rectangle.isFlipVertical(), false);\r
-        assertEquals(rectangle.isFlipHorizontal(), false);\r
-\r
-        rectangle.setFlipVertical(true);\r
-        assertEquals(rectangle.isFlipVertical(), true);\r
-        rectangle.setFlipHorizontal(true);\r
-        assertEquals(rectangle.isFlipHorizontal(), true);\r
-\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-        sheet = wb.getSheetAt(0);\r
-        patriarch = sheet.getDrawingPatriarch();\r
-\r
-        rectangle = (HSSFSimpleShape) patriarch.getChildren().get(0);\r
-\r
-        assertEquals(rectangle.isFlipHorizontal(), true);\r
-        rectangle.setFlipHorizontal(false);\r
-        assertEquals(rectangle.isFlipHorizontal(), false);\r
-\r
-        assertEquals(rectangle.isFlipVertical(), true);\r
-        rectangle.setFlipVertical(false);\r
-        assertEquals(rectangle.isFlipVertical(), false);\r
-\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-        sheet = wb.getSheetAt(0);\r
-        patriarch = sheet.getDrawingPatriarch();\r
-\r
-        rectangle = (HSSFSimpleShape) patriarch.getChildren().get(0);\r
-\r
-        assertEquals(rectangle.isFlipVertical(), false);\r
-        assertEquals(rectangle.isFlipHorizontal(), false);\r
-    }\r
-\r
-    public void testRotation() {\r
-        HSSFWorkbook wb = new HSSFWorkbook();\r
-        HSSFSheet sheet = wb.createSheet();\r
-        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();\r
-\r
-        HSSFSimpleShape rectangle = patriarch.createSimpleShape(new HSSFClientAnchor(0,0,100,100, (short) 0,0,(short)5,5));\r
-        rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);\r
-\r
-        assertEquals(rectangle.getRotationDegree(), 0);\r
-        rectangle.setRotationDegree((short) 45);\r
-        assertEquals(rectangle.getRotationDegree(), 45);\r
-        rectangle.setFlipHorizontal(true);\r
-\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-        sheet = wb.getSheetAt(0);\r
-        patriarch = sheet.getDrawingPatriarch();\r
-        rectangle = (HSSFSimpleShape) patriarch.getChildren().get(0);\r
-        assertEquals(rectangle.getRotationDegree(), 45);\r
-        rectangle.setRotationDegree((short) 30);\r
-        assertEquals(rectangle.getRotationDegree(), 30);\r
-\r
-        patriarch.setCoordinates(0, 0, 10, 10);\r
-        rectangle.setString(new HSSFRichTextString("1234"));\r
-    }\r
-\r
-    public void testShapeContainerImplementsIterable(){\r
-        HSSFWorkbook wb = new HSSFWorkbook();\r
-        HSSFSheet sheet = wb.createSheet();\r
-        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();\r
-\r
-        patriarch.createSimpleShape(new HSSFClientAnchor());\r
-        patriarch.createSimpleShape(new HSSFClientAnchor());\r
-\r
-        int i=2;\r
-\r
-        for (HSSFShape shape: patriarch){\r
-            i--;\r
-        }\r
-        assertEquals(i, 0);\r
-    }\r
-\r
-    public void testClearShapesForPatriarch(){\r
-        HSSFWorkbook wb = new HSSFWorkbook();\r
-        HSSFSheet sheet = wb.createSheet();\r
-        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();\r
-\r
-        patriarch.createSimpleShape(new HSSFClientAnchor());\r
-        patriarch.createSimpleShape(new HSSFClientAnchor());\r
-        patriarch.createCellComment(new HSSFClientAnchor());\r
-\r
-        EscherAggregate agg = HSSFTestHelper.getEscherAggregate(patriarch);\r
-\r
-        assertEquals(agg.getShapeToObjMapping().size(), 6);\r
-        assertEquals(agg.getTailRecords().size(), 1);\r
-        assertEquals(patriarch.getChildren().size(), 3);\r
-\r
-        patriarch.clear();\r
-\r
-        assertEquals(agg.getShapeToObjMapping().size(), 0);\r
-        assertEquals(agg.getTailRecords().size(), 0);\r
-        assertEquals(patriarch.getChildren().size(), 0);\r
-\r
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
-        sheet = wb.getSheetAt(0);\r
-        patriarch = sheet.getDrawingPatriarch();\r
-\r
-        assertEquals(agg.getShapeToObjMapping().size(), 0);\r
-        assertEquals(agg.getTailRecords().size(), 0);\r
-        assertEquals(patriarch.getChildren().size(), 0);\r
-    }\r
-}\r
+/* ====================================================================
+   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.hssf.model;
+
+import java.io.IOException;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.ddf.EscherBoolProperty;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherDgRecord;
+import org.apache.poi.ddf.EscherOptRecord;
+import org.apache.poi.ddf.EscherProperties;
+import org.apache.poi.ddf.EscherSimpleProperty;
+import org.apache.poi.ddf.EscherSpRecord;
+import org.apache.poi.ddf.EscherTextboxRecord;
+import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
+import org.apache.poi.hssf.record.EscherAggregate;
+import org.apache.poi.hssf.record.ObjRecord;
+import org.apache.poi.hssf.usermodel.*;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.util.HexDump;
+
+
+/**
+ * @author Evgeniy Berlog
+ * date: 12.06.12
+ */
+public class TestDrawingShapes extends TestCase {
+    static {
+        //System.setProperty("poi.deserialize.escher", "true");
+    }
+    
+    /**
+     * HSSFShape tree bust be built correctly
+     * Check file with such records structure:
+     * -patriarch
+     * --shape
+     * --group
+     * ---group
+     * ----shape
+     * ----shape
+     * ---shape
+     * ---group
+     * ----shape
+     * ----shape
+     */
+    public void testDrawingGroups() {
+        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
+        HSSFSheet sheet = wb.getSheet("groups");
+        HSSFPatriarch patriarch = sheet.getDrawingPatriarch();
+        assertEquals(patriarch.getChildren().size(), 2);
+        HSSFShapeGroup group = (HSSFShapeGroup) patriarch.getChildren().get(1);
+        assertEquals(3, group.getChildren().size());
+        HSSFShapeGroup group1 = (HSSFShapeGroup) group.getChildren().get(0);
+        assertEquals(2, group1.getChildren().size());
+        group1 = (HSSFShapeGroup) group.getChildren().get(2);
+        assertEquals(2, group1.getChildren().size());
+    }
+
+    public void testHSSFShapeCompatibility() {
+        HSSFSimpleShape shape = new HSSFSimpleShape(null, new HSSFClientAnchor());
+        shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
+        assertEquals(0x08000040, shape.getLineStyleColor());
+        assertEquals(0x08000009, shape.getFillColor());
+        assertEquals(HSSFShape.LINEWIDTH_DEFAULT, shape.getLineWidth());
+        assertEquals(HSSFShape.LINESTYLE_SOLID, shape.getLineStyle());
+        assertFalse(shape.isNoFill());
+
+        AbstractShape sp = AbstractShape.createShape(shape, 1);
+        EscherContainerRecord spContainer = sp.getSpContainer();
+        EscherOptRecord opt =
+                spContainer.getChildById(EscherOptRecord.RECORD_ID);
+
+        assertEquals(7, opt.getEscherProperties().size());
+        assertEquals(true,
+                ((EscherBoolProperty) opt.lookup(EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE)).isTrue());
+        assertEquals(0x00000004,
+                ((EscherSimpleProperty) opt.lookup(EscherProperties.GEOMETRY__SHAPEPATH)).getPropertyValue());
+        assertEquals(0x08000009,
+                ((EscherSimpleProperty) opt.lookup(EscherProperties.FILL__FILLCOLOR)).getPropertyValue());
+        assertEquals(true,
+                ((EscherBoolProperty) opt.lookup(EscherProperties.FILL__NOFILLHITTEST)).isTrue());
+        assertEquals(0x08000040,
+                ((EscherSimpleProperty) opt.lookup(EscherProperties.LINESTYLE__COLOR)).getPropertyValue());
+        assertEquals(true,
+                ((EscherBoolProperty) opt.lookup(EscherProperties.LINESTYLE__NOLINEDRAWDASH)).isTrue());
+        assertEquals(true,
+                ((EscherBoolProperty) opt.lookup(EscherProperties.GROUPSHAPE__PRINT)).isTrue());
+    }
+
+    public void testDefaultPictureSettings() {
+        HSSFPicture picture = new HSSFPicture(null, new HSSFClientAnchor());
+        assertEquals(picture.getLineWidth(), HSSFShape.LINEWIDTH_DEFAULT);
+        assertEquals(picture.getFillColor(), HSSFShape.FILL__FILLCOLOR_DEFAULT);
+        assertEquals(picture.getLineStyle(), HSSFShape.LINESTYLE_NONE);
+        assertEquals(picture.getLineStyleColor(), HSSFShape.LINESTYLE__COLOR_DEFAULT);
+        assertEquals(picture.isNoFill(), false);
+        assertEquals(picture.getPictureIndex(), -1);//not set yet
+    }
+
+    /**
+     * No NullPointerException should appear
+     */
+    public void testDefaultSettingsWithEmptyContainer() {
+        EscherContainerRecord container = new EscherContainerRecord();
+        EscherOptRecord opt = new EscherOptRecord();
+        opt.setRecordId(EscherOptRecord.RECORD_ID);
+        container.addChildRecord(opt);
+        ObjRecord obj = new ObjRecord();
+        CommonObjectDataSubRecord cod = new CommonObjectDataSubRecord();
+        cod.setObjectType(HSSFSimpleShape.OBJECT_TYPE_PICTURE);
+        obj.addSubRecord(cod);
+        HSSFPicture picture = new HSSFPicture(container, obj);
+
+        assertEquals(picture.getLineWidth(), HSSFShape.LINEWIDTH_DEFAULT);
+        assertEquals(picture.getFillColor(), HSSFShape.FILL__FILLCOLOR_DEFAULT);
+        assertEquals(picture.getLineStyle(), HSSFShape.LINESTYLE_DEFAULT);
+        assertEquals(picture.getLineStyleColor(), HSSFShape.LINESTYLE__COLOR_DEFAULT);
+        assertEquals(picture.isNoFill(), HSSFShape.NO_FILL_DEFAULT);
+        assertEquals(picture.getPictureIndex(), -1);//not set yet
+    }
+
+    /**
+     * create a rectangle, save the workbook, read back and verify that all shape properties are there
+     */
+    public void testReadWriteRectangle() throws IOException {
+
+        HSSFWorkbook wb = new HSSFWorkbook();
+        HSSFSheet sheet = wb.createSheet();
+
+        HSSFPatriarch drawing = sheet.createDrawingPatriarch();
+        HSSFClientAnchor anchor = new HSSFClientAnchor(10, 10, 50, 50, (short) 2, 2, (short) 4, 4);
+        anchor.setAnchorType(2);
+        assertEquals(anchor.getAnchorType(), 2);
+
+        HSSFSimpleShape rectangle = drawing.createSimpleShape(anchor);
+        rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
+        rectangle.setLineWidth(10000);
+        rectangle.setFillColor(777);
+        assertEquals(rectangle.getFillColor(), 777);
+        assertEquals(10000, rectangle.getLineWidth());
+        rectangle.setLineStyle(10);
+        assertEquals(10, rectangle.getLineStyle());
+        assertEquals(rectangle.getWrapText(), HSSFSimpleShape.WRAP_SQUARE);
+        rectangle.setLineStyleColor(1111);
+        rectangle.setNoFill(true);
+        rectangle.setWrapText(HSSFSimpleShape.WRAP_NONE);
+        rectangle.setString(new HSSFRichTextString("teeeest"));
+        assertEquals(rectangle.getLineStyleColor(), 1111);
+        assertEquals(((EscherSimpleProperty)((EscherOptRecord)HSSFTestHelper.getEscherContainer(rectangle).getChildById(EscherOptRecord.RECORD_ID))
+                .lookup(EscherProperties.TEXT__TEXTID)).getPropertyValue(), "teeeest".hashCode());
+        assertEquals(rectangle.isNoFill(), true);
+        assertEquals(rectangle.getWrapText(), HSSFSimpleShape.WRAP_NONE);
+        assertEquals(rectangle.getString().getString(), "teeeest");
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt(0);
+        drawing = sheet.getDrawingPatriarch();
+        assertEquals(1, drawing.getChildren().size());
+
+        HSSFSimpleShape rectangle2 =
+                (HSSFSimpleShape) drawing.getChildren().get(0);
+        assertEquals(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE,
+                rectangle2.getShapeType());
+        assertEquals(10000, rectangle2.getLineWidth());
+        assertEquals(10, rectangle2.getLineStyle());
+        assertEquals(anchor, rectangle2.getAnchor());
+        assertEquals(rectangle2.getLineStyleColor(), 1111);
+        assertEquals(rectangle2.getFillColor(), 777);
+        assertEquals(rectangle2.isNoFill(), true);
+        assertEquals(rectangle2.getString().getString(), "teeeest");
+        assertEquals(rectangle.getWrapText(), HSSFSimpleShape.WRAP_NONE);
+
+        rectangle2.setFillColor(3333);
+        rectangle2.setLineStyle(9);
+        rectangle2.setLineStyleColor(4444);
+        rectangle2.setNoFill(false);
+        rectangle2.setLineWidth(77);
+        rectangle2.getAnchor().setDx1(2);
+        rectangle2.getAnchor().setDx2(3);
+        rectangle2.getAnchor().setDy1(4);
+        rectangle2.getAnchor().setDy2(5);
+        rectangle.setWrapText(HSSFSimpleShape.WRAP_BY_POINTS);
+        rectangle2.setString(new HSSFRichTextString("test22"));
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt(0);
+        drawing = sheet.getDrawingPatriarch();
+        assertEquals(1, drawing.getChildren().size());
+        rectangle2 = (HSSFSimpleShape) drawing.getChildren().get(0);
+        assertEquals(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE, rectangle2.getShapeType());
+        assertEquals(rectangle.getWrapText(), HSSFSimpleShape.WRAP_BY_POINTS);
+        assertEquals(77, rectangle2.getLineWidth());
+        assertEquals(9, rectangle2.getLineStyle());
+        assertEquals(rectangle2.getLineStyleColor(), 4444);
+        assertEquals(rectangle2.getFillColor(), 3333);
+        assertEquals(rectangle2.getAnchor().getDx1(), 2);
+        assertEquals(rectangle2.getAnchor().getDx2(), 3);
+        assertEquals(rectangle2.getAnchor().getDy1(), 4);
+        assertEquals(rectangle2.getAnchor().getDy2(), 5);
+        assertEquals(rectangle2.isNoFill(), false);
+        assertEquals(rectangle2.getString().getString(), "test22");
+
+        HSSFSimpleShape rect3 = drawing.createSimpleShape(new HSSFClientAnchor());
+        rect3.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+
+        drawing = wb.getSheetAt(0).getDrawingPatriarch();
+        assertEquals(drawing.getChildren().size(), 2);
+    }
+
+    public void testReadExistingImage() {
+        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
+        HSSFSheet sheet = wb.getSheet("pictures");
+        HSSFPatriarch drawing = sheet.getDrawingPatriarch();
+        assertEquals(1, drawing.getChildren().size());
+        HSSFPicture picture = (HSSFPicture) drawing.getChildren().get(0);
+
+        assertEquals(picture.getPictureIndex(), 2);
+        assertEquals(picture.getLineStyleColor(), HSSFShape.LINESTYLE__COLOR_DEFAULT);
+        assertEquals(picture.getFillColor(), 0x5DC943);
+        assertEquals(picture.getLineWidth(), HSSFShape.LINEWIDTH_DEFAULT);
+        assertEquals(picture.getLineStyle(), HSSFShape.LINESTYLE_DEFAULT);
+        assertEquals(picture.isNoFill(), false);
+
+        picture.setPictureIndex(2);
+        assertEquals(picture.getPictureIndex(), 2);
+    }
+
+
+    /* assert shape properties when reading shapes from a existing workbook */
+    public void testReadExistingRectangle() {
+        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
+        HSSFSheet sheet = wb.getSheet("rectangles");
+        HSSFPatriarch drawing = sheet.getDrawingPatriarch();
+        assertEquals(1, drawing.getChildren().size());
+
+        HSSFSimpleShape shape = (HSSFSimpleShape) drawing.getChildren().get(0);
+        assertEquals(shape.isNoFill(), false);
+        assertEquals(shape.getLineStyle(), HSSFShape.LINESTYLE_DASHDOTGEL);
+        assertEquals(shape.getLineStyleColor(), 0x616161);
+        assertEquals(HexDump.toHex(shape.getFillColor()), shape.getFillColor(), 0x2CE03D);
+        assertEquals(shape.getLineWidth(), HSSFShape.LINEWIDTH_ONE_PT * 2);
+        assertEquals(shape.getString().getString(), "POItest");
+        assertEquals(shape.getRotationDegree(), 27);
+    }
+
+    public void testShapeIds() {
+        HSSFWorkbook wb = new HSSFWorkbook();
+        HSSFSheet sheet1 = wb.createSheet();
+        HSSFPatriarch patriarch1 = sheet1.createDrawingPatriarch();
+        for (int i = 0; i < 2; i++) {
+            patriarch1.createSimpleShape(new HSSFClientAnchor());
+        }
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet1 = wb.getSheetAt(0);
+        patriarch1 = sheet1.getDrawingPatriarch();
+
+        EscherAggregate agg1 = HSSFTestHelper.getEscherAggregate(patriarch1);
+        // last shape ID cached in EscherDgRecord
+        EscherDgRecord dg1 =
+                agg1.getEscherContainer().getChildById(EscherDgRecord.RECORD_ID);
+        assertEquals(1026, dg1.getLastMSOSPID());
+
+        // iterate over shapes and check shapeId
+        EscherContainerRecord spgrContainer =
+                agg1.getEscherContainer().getChildContainers().get(0);
+        // root spContainer + 2 spContainers for shapes
+        assertEquals(3, spgrContainer.getChildRecords().size());
+
+        EscherSpRecord sp0 =
+                ((EscherContainerRecord) spgrContainer.getChild(0)).getChildById(EscherSpRecord.RECORD_ID);
+        assertEquals(1024, sp0.getShapeId());
+
+        EscherSpRecord sp1 =
+                ((EscherContainerRecord) spgrContainer.getChild(1)).getChildById(EscherSpRecord.RECORD_ID);
+        assertEquals(1025, sp1.getShapeId());
+
+        EscherSpRecord sp2 =
+                ((EscherContainerRecord) spgrContainer.getChild(2)).getChildById(EscherSpRecord.RECORD_ID);
+        assertEquals(1026, sp2.getShapeId());
+    }
+
+    /**
+     * Test get new id for shapes from existing file
+     * File already have for 1 shape on each sheet, because document must contain EscherDgRecord for each sheet
+     */
+    public void testAllocateNewIds() {
+        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("empty.xls");
+        HSSFSheet sheet = wb.getSheetAt(0);
+        HSSFPatriarch patriarch = sheet.getDrawingPatriarch();
+
+        /**
+         * 2048 - main SpContainer id
+         * 2049 - existing shape id
+         */
+        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 2050);
+        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 2051);
+        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 2052);
+
+        sheet = wb.getSheetAt(1);
+        patriarch = sheet.getDrawingPatriarch();
+
+        /**
+         * 3072 - main SpContainer id
+         * 3073 - existing shape id
+         */
+        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 3074);
+        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 3075);
+        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 3076);
+
+
+        sheet = wb.getSheetAt(2);
+        patriarch = sheet.getDrawingPatriarch();
+
+        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 1026);
+        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 1027);
+        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 1028);
+    }
+
+    public void testOpt() throws Exception {
+        HSSFWorkbook wb = new HSSFWorkbook();
+
+        try {
+            // create a sheet with a text box
+            HSSFSheet sheet = wb.createSheet();
+            HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
+    
+            HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
+            EscherOptRecord opt1 = HSSFTestHelper.getOptRecord(textbox);
+            EscherOptRecord opt2 = HSSFTestHelper.getEscherContainer(textbox).getChildById(EscherOptRecord.RECORD_ID);
+            assertSame(opt1, opt2);
+        } finally {
+            wb.close();
+        }
+    }
+    
+    public void testCorrectOrderInOptRecord() throws IOException{
+        HSSFWorkbook wb = new HSSFWorkbook();
+        
+        try {
+            HSSFSheet sheet = wb.createSheet();
+            HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
+    
+            HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
+            EscherOptRecord opt = HSSFTestHelper.getOptRecord(textbox);
+            
+            String opt1Str = opt.toXml();
+    
+            textbox.setFillColor(textbox.getFillColor());
+            EscherContainerRecord container = HSSFTestHelper.getEscherContainer(textbox);
+            EscherOptRecord optRecord = container.getChildById(EscherOptRecord.RECORD_ID);
+            assertEquals(opt1Str, optRecord.toXml());
+            textbox.setLineStyle(textbox.getLineStyle());
+            assertEquals(opt1Str, optRecord.toXml());
+            textbox.setLineWidth(textbox.getLineWidth());
+            assertEquals(opt1Str, optRecord.toXml());
+            textbox.setLineStyleColor(textbox.getLineStyleColor());
+            assertEquals(opt1Str, optRecord.toXml());
+        } finally {
+            wb.close();
+        }
+    }
+
+    public void testDgRecordNumShapes() throws IOException{
+        HSSFWorkbook wb = new HSSFWorkbook();
+        try {
+            HSSFSheet sheet = wb.createSheet();
+            HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
+    
+            EscherAggregate aggregate = HSSFTestHelper.getEscherAggregate(patriarch);
+            EscherDgRecord dgRecord = (EscherDgRecord) aggregate.getEscherRecord(0).getChild(0);
+            assertEquals(dgRecord.getNumShapes(), 1);
+        } finally {
+            wb.close();
+        }
+    }
+
+    public void testTextForSimpleShape(){
+        HSSFWorkbook wb = new HSSFWorkbook();
+        HSSFSheet sheet = wb.createSheet();
+        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
+
+        HSSFSimpleShape shape = patriarch.createSimpleShape(new HSSFClientAnchor());
+        shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
+
+        EscherAggregate agg = HSSFTestHelper.getEscherAggregate(patriarch);
+        assertEquals(agg.getShapeToObjMapping().size(), 2);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt(0);
+        patriarch = sheet.getDrawingPatriarch();
+
+        shape = (HSSFSimpleShape) patriarch.getChildren().get(0);
+
+        agg = HSSFTestHelper.getEscherAggregate(patriarch);
+        assertEquals(agg.getShapeToObjMapping().size(), 2);
+
+        shape.setString(new HSSFRichTextString("string1"));
+        assertEquals(shape.getString().getString(), "string1");
+
+        assertNotNull(HSSFTestHelper.getEscherContainer(shape).getChildById(EscherTextboxRecord.RECORD_ID));
+        assertEquals(agg.getShapeToObjMapping().size(), 2);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt(0);
+        patriarch = sheet.getDrawingPatriarch();
+
+        shape = (HSSFSimpleShape) patriarch.getChildren().get(0);
+
+        assertNotNull(HSSFTestHelper.getTextObjRecord(shape));
+        assertEquals(shape.getString().getString(), "string1");
+        assertNotNull(HSSFTestHelper.getEscherContainer(shape).getChildById(EscherTextboxRecord.RECORD_ID));
+        assertEquals(agg.getShapeToObjMapping().size(), 2);
+    }
+
+    public void testRemoveShapes(){
+        HSSFWorkbook wb = new HSSFWorkbook();
+        HSSFSheet sheet = wb.createSheet();
+        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
+
+        HSSFSimpleShape rectangle = patriarch.createSimpleShape(new HSSFClientAnchor());
+        rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
+
+        int idx = wb.addPicture(new byte[]{1,2,3}, Workbook.PICTURE_TYPE_JPEG);
+        patriarch.createPicture(new HSSFClientAnchor(), idx);
+
+        patriarch.createCellComment(new HSSFClientAnchor());
+
+        HSSFPolygon polygon = patriarch.createPolygon(new HSSFClientAnchor());
+        polygon.setPoints(new int[]{1,2}, new int[]{2,3});
+
+        patriarch.createTextbox(new HSSFClientAnchor());
+
+        HSSFShapeGroup group = patriarch.createGroup(new HSSFClientAnchor());
+        group.createTextbox(new HSSFChildAnchor());
+        group.createPicture(new HSSFChildAnchor(), idx);
+
+        assertEquals(patriarch.getChildren().size(), 6);
+        assertEquals(group.getChildren().size(), 2);
+
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 12);
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt(0);
+        patriarch = sheet.getDrawingPatriarch();
+
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 12);
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
+
+        assertEquals(patriarch.getChildren().size(), 6);
+
+        group = (HSSFShapeGroup) patriarch.getChildren().get(5);
+        group.removeShape(group.getChildren().get(0));
+
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 10);
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt(0);
+        patriarch = sheet.getDrawingPatriarch();
+
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 10);
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
+
+        group = (HSSFShapeGroup) patriarch.getChildren().get(5);
+        patriarch.removeShape(group);
+
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 8);
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt(0);
+        patriarch = sheet.getDrawingPatriarch();
+
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 8);
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
+        assertEquals(patriarch.getChildren().size(), 5);
+
+        HSSFShape shape = patriarch.getChildren().get(0);
+        patriarch.removeShape(shape);
+
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 6);
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
+        assertEquals(patriarch.getChildren().size(), 4);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt(0);
+        patriarch = sheet.getDrawingPatriarch();
+
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 6);
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
+        assertEquals(patriarch.getChildren().size(), 4);
+
+        HSSFPicture picture = (HSSFPicture) patriarch.getChildren().get(0);
+        patriarch.removeShape(picture);
+
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 5);
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
+        assertEquals(patriarch.getChildren().size(), 3);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt(0);
+        patriarch = sheet.getDrawingPatriarch();
+
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 5);
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
+        assertEquals(patriarch.getChildren().size(), 3);
+
+        HSSFComment comment = (HSSFComment) patriarch.getChildren().get(0);
+        patriarch.removeShape(comment);
+
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 3);
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);
+        assertEquals(patriarch.getChildren().size(), 2);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt(0);
+        patriarch = sheet.getDrawingPatriarch();
+
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 3);
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);
+        assertEquals(patriarch.getChildren().size(), 2);
+
+        polygon = (HSSFPolygon) patriarch.getChildren().get(0);
+        patriarch.removeShape(polygon);
+
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 2);
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);
+        assertEquals(patriarch.getChildren().size(), 1);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt(0);
+        patriarch = sheet.getDrawingPatriarch();
+
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 2);
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);
+        assertEquals(patriarch.getChildren().size(), 1);
+
+        HSSFTextbox textbox = (HSSFTextbox) patriarch.getChildren().get(0);
+        patriarch.removeShape(textbox);
+
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 0);
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);
+        assertEquals(patriarch.getChildren().size(), 0);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt(0);
+        patriarch = sheet.getDrawingPatriarch();
+
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 0);
+        assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);
+        assertEquals(patriarch.getChildren().size(), 0);
+    }
+
+    public void testShapeFlip(){
+        HSSFWorkbook wb = new HSSFWorkbook();
+        HSSFSheet sheet = wb.createSheet();
+        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
+
+        HSSFSimpleShape rectangle = patriarch.createSimpleShape(new HSSFClientAnchor());
+        rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
+
+        assertEquals(rectangle.isFlipVertical(), false);
+        assertEquals(rectangle.isFlipHorizontal(), false);
+
+        rectangle.setFlipVertical(true);
+        assertEquals(rectangle.isFlipVertical(), true);
+        rectangle.setFlipHorizontal(true);
+        assertEquals(rectangle.isFlipHorizontal(), true);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt(0);
+        patriarch = sheet.getDrawingPatriarch();
+
+        rectangle = (HSSFSimpleShape) patriarch.getChildren().get(0);
+
+        assertEquals(rectangle.isFlipHorizontal(), true);
+        rectangle.setFlipHorizontal(false);
+        assertEquals(rectangle.isFlipHorizontal(), false);
+
+        assertEquals(rectangle.isFlipVertical(), true);
+        rectangle.setFlipVertical(false);
+        assertEquals(rectangle.isFlipVertical(), false);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt(0);
+        patriarch = sheet.getDrawingPatriarch();
+
+        rectangle = (HSSFSimpleShape) patriarch.getChildren().get(0);
+
+        assertEquals(rectangle.isFlipVertical(), false);
+        assertEquals(rectangle.isFlipHorizontal(), false);
+    }
+
+    public void testRotation() {
+        HSSFWorkbook wb = new HSSFWorkbook();
+        HSSFSheet sheet = wb.createSheet();
+        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
+
+        HSSFSimpleShape rectangle = patriarch.createSimpleShape(new HSSFClientAnchor(0,0,100,100, (short) 0,0,(short)5,5));
+        rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
+
+        assertEquals(rectangle.getRotationDegree(), 0);
+        rectangle.setRotationDegree((short) 45);
+        assertEquals(rectangle.getRotationDegree(), 45);
+        rectangle.setFlipHorizontal(true);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt(0);
+        patriarch = sheet.getDrawingPatriarch();
+        rectangle = (HSSFSimpleShape) patriarch.getChildren().get(0);
+        assertEquals(rectangle.getRotationDegree(), 45);
+        rectangle.setRotationDegree((short) 30);
+        assertEquals(rectangle.getRotationDegree(), 30);
+
+        patriarch.setCoordinates(0, 0, 10, 10);
+        rectangle.setString(new HSSFRichTextString("1234"));
+    }
+
+    public void testShapeContainerImplementsIterable() throws IOException{
+        HSSFWorkbook wb = new HSSFWorkbook();
+        
+        try {
+            HSSFSheet sheet = wb.createSheet();
+            HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
+    
+            patriarch.createSimpleShape(new HSSFClientAnchor());
+            patriarch.createSimpleShape(new HSSFClientAnchor());
+    
+            int i=2;
+    
+            for (HSSFShape shape: patriarch){
+                i--;
+            }
+            assertEquals(i, 0);
+        } finally {
+            wb.close();
+        }
+    }
+
+    public void testClearShapesForPatriarch(){
+        HSSFWorkbook wb = new HSSFWorkbook();
+        HSSFSheet sheet = wb.createSheet();
+        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
+
+        patriarch.createSimpleShape(new HSSFClientAnchor());
+        patriarch.createSimpleShape(new HSSFClientAnchor());
+        patriarch.createCellComment(new HSSFClientAnchor());
+
+        EscherAggregate agg = HSSFTestHelper.getEscherAggregate(patriarch);
+
+        assertEquals(agg.getShapeToObjMapping().size(), 6);
+        assertEquals(agg.getTailRecords().size(), 1);
+        assertEquals(patriarch.getChildren().size(), 3);
+
+        patriarch.clear();
+
+        assertEquals(agg.getShapeToObjMapping().size(), 0);
+        assertEquals(agg.getTailRecords().size(), 0);
+        assertEquals(patriarch.getChildren().size(), 0);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt(0);
+        patriarch = sheet.getDrawingPatriarch();
+
+        assertEquals(agg.getShapeToObjMapping().size(), 0);
+        assertEquals(agg.getTailRecords().size(), 0);
+        assertEquals(patriarch.getChildren().size(), 0);
+    }
+    
+    public void testBug45312() throws Exception {
+        HSSFWorkbook wb = new HSSFWorkbook();
+        try {
+            HSSFSheet sheet = wb.createSheet();
+            HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
+    
+            {
+                HSSFClientAnchor a1 = new HSSFClientAnchor();
+                a1.setAnchor( (short)1, 1, 0, 0, (short) 1, 1, 512, 100);
+                HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1);
+                shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
+            }
+            {
+                HSSFClientAnchor a1 = new HSSFClientAnchor();
+                a1.setAnchor( (short)1, 1, 512, 0, (short) 1, 1, 1024, 100);
+                HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1);
+                shape1.setFlipVertical(true);
+                shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
+            }
+
+            {
+                HSSFClientAnchor a1 = new HSSFClientAnchor();
+                a1.setAnchor( (short)2, 2, 0, 0, (short) 2, 2, 512, 100);
+                HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1);
+                shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
+            }
+            {
+                HSSFClientAnchor a1 = new HSSFClientAnchor();
+                a1.setAnchor( (short)2, 2, 0, 100, (short) 2, 2, 512, 200);
+                HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1);
+                shape1.setFlipHorizontal(true);
+                shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
+            }
+            
+            /*OutputStream stream = new FileOutputStream("/tmp/45312.xls");
+            try {
+                wb.write(stream);
+            } finally {
+                stream.close();
+            }*/
+            
+            checkWorkbookBack(wb);
+        } finally {
+            wb.close();
+        }
+    }
+
+    private void checkWorkbookBack(HSSFWorkbook wb) {
+        HSSFWorkbook wbBack = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        assertNotNull(wbBack);
+        
+        HSSFSheet sheetBack = wbBack.getSheetAt(0);
+        assertNotNull(sheetBack);
+        
+        HSSFPatriarch patriarchBack = sheetBack.getDrawingPatriarch();
+        assertNotNull(patriarchBack);
+        
+        List<HSSFShape> children = patriarchBack.getChildren();
+        assertEquals(4, children.size());
+        HSSFShape hssfShape = children.get(0);
+        assertTrue(hssfShape instanceof HSSFSimpleShape);
+        HSSFAnchor anchor = hssfShape.getAnchor();
+        assertTrue(anchor instanceof HSSFClientAnchor);
+        assertEquals(0, anchor.getDx1());
+        assertEquals(512, anchor.getDx2());
+        assertEquals(0, anchor.getDy1());
+        assertEquals(100, anchor.getDy2());
+        HSSFClientAnchor cAnchor = (HSSFClientAnchor) anchor;
+        assertEquals(1, cAnchor.getCol1());
+        assertEquals(1, cAnchor.getCol2());
+        assertEquals(1, cAnchor.getRow1());
+        assertEquals(1, cAnchor.getRow2());
+
+        hssfShape = children.get(1);
+        assertTrue(hssfShape instanceof HSSFSimpleShape);
+        anchor = hssfShape.getAnchor();
+        assertTrue(anchor instanceof HSSFClientAnchor);
+        assertEquals(512, anchor.getDx1());
+        assertEquals(1024, anchor.getDx2());
+        assertEquals(0, anchor.getDy1());
+        assertEquals(100, anchor.getDy2());
+        cAnchor = (HSSFClientAnchor) anchor;
+        assertEquals(1, cAnchor.getCol1());
+        assertEquals(1, cAnchor.getCol2());
+        assertEquals(1, cAnchor.getRow1());
+        assertEquals(1, cAnchor.getRow2());
+
+        hssfShape = children.get(2);
+        assertTrue(hssfShape instanceof HSSFSimpleShape);
+        anchor = hssfShape.getAnchor();
+        assertTrue(anchor instanceof HSSFClientAnchor);
+        assertEquals(0, anchor.getDx1());
+        assertEquals(512, anchor.getDx2());
+        assertEquals(0, anchor.getDy1());
+        assertEquals(100, anchor.getDy2());
+        cAnchor = (HSSFClientAnchor) anchor;
+        assertEquals(2, cAnchor.getCol1());
+        assertEquals(2, cAnchor.getCol2());
+        assertEquals(2, cAnchor.getRow1());
+        assertEquals(2, cAnchor.getRow2());
+
+        hssfShape = children.get(3);
+        assertTrue(hssfShape instanceof HSSFSimpleShape);
+        anchor = hssfShape.getAnchor();
+        assertTrue(anchor instanceof HSSFClientAnchor);
+        assertEquals(0, anchor.getDx1());
+        assertEquals(512, anchor.getDx2());
+        assertEquals(100, anchor.getDy1());
+        assertEquals(200, anchor.getDy2());
+        cAnchor = (HSSFClientAnchor) anchor;
+        assertEquals(2, cAnchor.getCol1());
+        assertEquals(2, cAnchor.getCol2());
+        assertEquals(2, cAnchor.getRow1());
+        assertEquals(2, cAnchor.getRow2());
+    }
+}
index 9518f3fff2fb5955f298789a467cc3f839614071..b101a4ee2b7e726c3ed85366dfd5cc0aae0b8bc0 100644 (file)
@@ -23,7 +23,6 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.Arrays;
 import junit.framework.TestCase;
-import org.apache.poi.util.ArrayUtil;
 import org.apache.poi.util.LittleEndianOutputStream;
 
 /**
@@ -288,7 +287,7 @@ public class TestDConRefRecord extends TestCase
     public void testGetPath()
     {
         DConRefRecord instance = new DConRefRecord(TestcaseRecordInputStream.create(81, data1));
-        byte[] expResult = ArrayUtil.copyOfRange(data1, 9, data1.length);
+        byte[] expResult = Arrays.copyOfRange(data1, 9, data1.length);
         byte[] result = instance.getPath();
         assertTrue("get path", Arrays.equals(expResult, result));
     }
index 5c6af7b2611de6d02f2560a99bbaa0463c23a2d2..b6e6ca932e7285f5d24aaed7562380425b36a912 100644 (file)
@@ -390,7 +390,6 @@ public abstract class BaseTestConditionalFormatting extends TestCase {
     }\r
 \r
     public void testShiftRows() {\r
-\r
         Workbook wb = _testDataProvider.createWorkbook();\r
         Sheet sheet = wb.createSheet();\r
 \r
@@ -403,30 +402,42 @@ public abstract class BaseTestConditionalFormatting extends TestCase {
 \r
         PatternFormatting patternFmt = rule1.createPatternFormatting();\r
         patternFmt.setFillBackgroundColor(IndexedColors.YELLOW.index);\r
-        ConditionalFormattingRule [] cfRules = { rule1, };\r
+\r
+        ConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(\r
+                ComparisonOperator.BETWEEN, "SUM(A10:A15)", "1+SUM(B16:B30)");\r
+        BorderFormatting borderFmt = rule2.createBorderFormatting();\r
+        borderFmt.setBorderDiagonal((short) 2);\r
 \r
         CellRangeAddress [] regions = {\r
             new CellRangeAddress(2, 4, 0, 0), // A3:A5\r
         };\r
-        sheetCF.addConditionalFormatting(regions, cfRules);\r
+        sheetCF.addConditionalFormatting(regions, rule1);\r
+        sheetCF.addConditionalFormatting(regions, rule2);\r
 \r
         // This row-shift should destroy the CF region\r
         sheet.shiftRows(10, 20, -9);\r
         assertEquals(0, sheetCF.getNumConditionalFormattings());\r
 \r
         // re-add the CF\r
-        sheetCF.addConditionalFormatting(regions, cfRules);\r
+        sheetCF.addConditionalFormatting(regions, rule1);\r
+        sheetCF.addConditionalFormatting(regions, rule2);\r
 \r
         // This row shift should only affect the formulas\r
         sheet.shiftRows(14, 17, 8);\r
-        ConditionalFormatting cf = sheetCF.getConditionalFormattingAt(0);\r
-        assertEquals("SUM(A10:A23)", cf.getRule(0).getFormula1());\r
-        assertEquals("1+SUM(B24:B30)", cf.getRule(0).getFormula2());\r
+        ConditionalFormatting cf1 = sheetCF.getConditionalFormattingAt(0);\r
+        assertEquals("SUM(A10:A23)", cf1.getRule(0).getFormula1());\r
+        assertEquals("1+SUM(B24:B30)", cf1.getRule(0).getFormula2());\r
+        ConditionalFormatting cf2 = sheetCF.getConditionalFormattingAt(1);\r
+        assertEquals("SUM(A10:A23)", cf2.getRule(0).getFormula1());\r
+        assertEquals("1+SUM(B24:B30)", cf2.getRule(0).getFormula2());\r
 \r
         sheet.shiftRows(0, 8, 21);\r
-        cf = sheetCF.getConditionalFormattingAt(0);\r
-        assertEquals("SUM(A10:A21)", cf.getRule(0).getFormula1());\r
-        assertEquals("1+SUM(#REF!)", cf.getRule(0).getFormula2());\r
+        cf1 = sheetCF.getConditionalFormattingAt(0);\r
+        assertEquals("SUM(A10:A21)", cf1.getRule(0).getFormula1());\r
+        assertEquals("1+SUM(#REF!)", cf1.getRule(0).getFormula2());\r
+        cf2 = sheetCF.getConditionalFormattingAt(1);\r
+        assertEquals("SUM(A10:A21)", cf2.getRule(0).getFormula1());\r
+        assertEquals("1+SUM(#REF!)", cf2.getRule(0).getFormula2());\r
     }\r
 \r
     protected void testRead(String filename){\r
diff --git a/test-data/spreadsheet/56730.xlsx b/test-data/spreadsheet/56730.xlsx
new file mode 100644 (file)
index 0000000..9883de4
Binary files /dev/null and b/test-data/spreadsheet/56730.xlsx differ
diff --git a/test-data/spreadsheet/Themes.xlsx b/test-data/spreadsheet/Themes.xlsx
new file mode 100644 (file)
index 0000000..188f1bd
Binary files /dev/null and b/test-data/spreadsheet/Themes.xlsx differ
diff --git a/test-data/spreadsheet/workbookProtection-sheet_password-2013.xlsx b/test-data/spreadsheet/workbookProtection-sheet_password-2013.xlsx
new file mode 100644 (file)
index 0000000..691b2cc
Binary files /dev/null and b/test-data/spreadsheet/workbookProtection-sheet_password-2013.xlsx differ
diff --git a/test-data/spreadsheet/workbookProtection-workbook_password-2013.xlsx b/test-data/spreadsheet/workbookProtection-workbook_password-2013.xlsx
new file mode 100644 (file)
index 0000000..9782107
Binary files /dev/null and b/test-data/spreadsheet/workbookProtection-workbook_password-2013.xlsx differ
diff --git a/test-data/spreadsheet/workbookProtection-workbook_password_user_range-2010.xlsx b/test-data/spreadsheet/workbookProtection-workbook_password_user_range-2010.xlsx
new file mode 100644 (file)
index 0000000..2712913
Binary files /dev/null and b/test-data/spreadsheet/workbookProtection-workbook_password_user_range-2010.xlsx differ