You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2016/08/08 01:14:37 UTC

svn commit: r1755463 [1/3] - in /poi/branches/hssf_cryptoapi: ./ maven/ sonar/main/ src/java/org/apache/poi/hssf/record/aggregates/ src/java/org/apache/poi/hssf/usermodel/ src/java/org/apache/poi/poifs/crypt/ src/java/org/apache/poi/ss/formula/ src/jav...

Author: kiwiwings
Date: Mon Aug  8 01:14:36 2016
New Revision: 1755463

URL: http://svn.apache.org/viewvc?rev=1755463&view=rev
Log:
merge down trunk

Added:
    poi/branches/hssf_cryptoapi/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java
      - copied unchanged from r1755462, poi/trunk/src/java/org/apache/poi/ss/formula/BaseFormulaEvaluator.java
    poi/branches/hssf_cryptoapi/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPasswordHelper.java
      - copied unchanged from r1755462, poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPasswordHelper.java
    poi/branches/hssf_cryptoapi/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestHWPFWrite.java
      - copied unchanged from r1755462, poi/trunk/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestHWPFWrite.java
    poi/branches/hssf_cryptoapi/src/testcases/org/apache/poi/ss/formula/functions/TestWeekdayFunc.java
      - copied unchanged from r1755462, poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestWeekdayFunc.java
    poi/branches/hssf_cryptoapi/test-data/spreadsheet/59736.xlsx
      - copied unchanged from r1755462, poi/trunk/test-data/spreadsheet/59736.xlsx
Modified:
    poi/branches/hssf_cryptoapi/build.xml
    poi/branches/hssf_cryptoapi/maven/poi.pom
    poi/branches/hssf_cryptoapi/sonar/main/pom.xml
    poi/branches/hssf_cryptoapi/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
    poi/branches/hssf_cryptoapi/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java
    poi/branches/hssf_cryptoapi/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
    poi/branches/hssf_cryptoapi/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java
    poi/branches/hssf_cryptoapi/src/java/org/apache/poi/ss/formula/LazyRefEval.java
    poi/branches/hssf_cryptoapi/src/java/org/apache/poi/ss/formula/functions/Subtotal.java
    poi/branches/hssf_cryptoapi/src/java/org/apache/poi/ss/usermodel/CellStyle.java
    poi/branches/hssf_cryptoapi/src/java/org/apache/poi/ss/usermodel/Workbook.java
    poi/branches/hssf_cryptoapi/src/java/org/apache/poi/util/CommonsLogger.java
    poi/branches/hssf_cryptoapi/src/java/org/apache/poi/util/NullLogger.java
    poi/branches/hssf_cryptoapi/src/java/org/apache/poi/util/SystemOutLogger.java
    poi/branches/hssf_cryptoapi/src/ooxml/java/org/apache/poi/POIXMLDocument.java
    poi/branches/hssf_cryptoapi/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java
    poi/branches/hssf_cryptoapi/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java
    poi/branches/hssf_cryptoapi/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java
    poi/branches/hssf_cryptoapi/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java
    poi/branches/hssf_cryptoapi/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java
    poi/branches/hssf_cryptoapi/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java
    poi/branches/hssf_cryptoapi/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFEvaluationWorkbook.java
    poi/branches/hssf_cryptoapi/src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFFormulaEvaluator.java
    poi/branches/hssf_cryptoapi/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFormulaEvaluator.java
    poi/branches/hssf_cryptoapi/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFName.java
    poi/branches/hssf_cryptoapi/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
    poi/branches/hssf_cryptoapi/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
    poi/branches/hssf_cryptoapi/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFFormulaUtils.java
    poi/branches/hssf_cryptoapi/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPaswordHelper.java   (contents, props changed)
    poi/branches/hssf_cryptoapi/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java
    poi/branches/hssf_cryptoapi/src/ooxml/testcases/org/apache/poi/openxml4j/opc/internal/TestContentTypeManager.java
    poi/branches/hssf_cryptoapi/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java
    poi/branches/hssf_cryptoapi/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java
    poi/branches/hssf_cryptoapi/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFName.java
    poi/branches/hssf_cryptoapi/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java
    poi/branches/hssf_cryptoapi/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java
    poi/branches/hssf_cryptoapi/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java
    poi/branches/hssf_cryptoapi/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShow.java
    poi/branches/hssf_cryptoapi/src/testcases/org/apache/poi/ss/formula/functions/TestIndirect.java
    poi/branches/hssf_cryptoapi/src/testcases/org/apache/poi/ss/formula/functions/TestSubtotal.java
    poi/branches/hssf_cryptoapi/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java
    poi/branches/hssf_cryptoapi/src/testcases/org/apache/poi/ss/usermodel/BaseTestNamedRange.java
    poi/branches/hssf_cryptoapi/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java
    poi/branches/hssf_cryptoapi/src/testcases/org/apache/poi/ss/util/BaseTestCellUtil.java
    poi/branches/hssf_cryptoapi/src/testcases/org/apache/poi/util/DummyPOILogger.java
    poi/branches/hssf_cryptoapi/src/testcases/org/apache/poi/util/TestPOILogger.java

Modified: poi/branches/hssf_cryptoapi/build.xml
URL: http://svn.apache.org/viewvc/poi/branches/hssf_cryptoapi/build.xml?rev=1755463&r1=1755462&r2=1755463&view=diff
==============================================================================
--- poi/branches/hssf_cryptoapi/build.xml (original)
+++ poi/branches/hssf_cryptoapi/build.xml Mon Aug  8 01:14:36 2016
@@ -17,7 +17,6 @@ KIND, either express or implied.  See th
 specific language governing permissions and limitations
 under the License.
 -->
-
 <!--
     This build was tested with ant 1.9.4 although it will probably work with
     other versions, however at least 1.8.0 is required.
@@ -133,6 +132,7 @@ under the License.
     <property name="ooxml.output.test.dir" location="build/ooxml-test-classes"/>
     <property name="ooxml.testokfile" location="build/ooxml-testokfile.txt"/>
     <property name="ooxml.lite.output.dir" location="build/ooxml-lite-classes"/>
+    <property name="ooxml.lite.testokfile" location="build/ooxml-lite-testokfile.txt"/>
 
     <!-- XSSF/SXSSF subset of OOXML: -->
     <property name="ooxml.ss.testokfile" location="build/ooxml-ss-testokfile.txt"/>
@@ -169,6 +169,9 @@ under the License.
     <property name="main.ant.url" value="${repository.m2}/maven2/org/apache/ant/ant/1.9.4/ant-1.9.4.jar"/>
     <property name="main.antlauncher.jar" location="${main.lib}/ant-launcher-1.9.4.jar"/>
     <property name="main.antlauncher.url" value="${repository.m2}/maven2/org/apache/ant/ant-launcher/1.9.4/ant-launcher-1.9.4.jar"/>
+    <property name="main.commons-collections4.jar" location="${main.lib}/commons-collections4-4.1.jar"/>
+    <property name="main.commons-collections4.url"
+              value="${repository.m2}/maven2/org/apache/commons/commons-collections4/4.1/commons-collections4-4.1.jar"/>
 
     <!-- xml signature libs -->
     <property name="dsig.xmlsec.jar" location="${compile.lib}/xmlsec-2.0.6.jar"/>
@@ -192,8 +195,8 @@ under the License.
               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.6.201602180812.zip"/>
-    <property name="jacoco.url" value="${repository.m2}/maven2/org/jacoco/jacoco/0.7.6.201602180812/jacoco-0.7.6.201602180812.zip"/>
+    <property name="jacoco.zip" location="${main.lib}/jacoco-0.7.7.201606060606.zip"/>
+    <property name="jacoco.url" value="${repository.m2}/maven2/org/jacoco/jacoco/0.7.7.201606060606/jacoco-0.7.7.201606060606.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"/>
 
@@ -285,6 +288,7 @@ under the License.
     </condition>
     <property name="findbugs.version" value="2.0.3" if:set="findbugs.jdk6"/>
     <property name="findbugs.version" value="3.0.1" unless:set="findbugs.jdk6"/>
+    <echo message="Findbugs-Version: ${findbugs.version} for Java ${ant.java.version}"/>
 	<property name="findbugs.url" value="http://prdownloads.sourceforge.net/findbugs/findbugs-noUpdateChecks-${findbugs.version}.zip?download"/>
 	<property name="findbugs.jar" location="${main.lib}/findbugs-noUpdateChecks-${findbugs.version}.zip"/>
 
@@ -303,6 +307,8 @@ under the License.
 
     <!-- this can be overwriten to empty when running with Java 9 -->
     <property name="maxpermsize" value="-XX:MaxPermSize=256m"/>
+    <property name="java9addmods" value="-Dthis.is.a.dummy=true"/>
+    <property name="java9addmodsvalue" value="-Dthis.is.a.dummy=true"/>
 
     <path id="main.classpath">
         <pathelement location="${main.commons-logging.jar}"/>
@@ -310,6 +316,7 @@ under the License.
         <pathelement location="${main.log4j.jar}"/>
         <pathelement location="${main.junit.jar}"/>
         <pathelement location="${main.hamcrest.jar}"/>
+        <pathelement location="${main.commons-collections4.jar}"/>
     </path>
 
     <path id="scratchpad.classpath">
@@ -498,9 +505,7 @@ under the License.
         <attribute name="src"/>
         <attribute name="dest"/>
         <sequential>
-            <local name="exists"/>
-            <available file="@{dest}" property="exists"/>
-            <!--fail unless:true="${exists}"
+            <!--fail
                 message="Java version might be uncapable to download https URLs - see https://stackoverflow.com/questions/6851461/java-why-does-ssl-handshake-give-could-not-generate-dh-keypair-exception">
                 <condition>
                     <and>
@@ -509,7 +514,7 @@ under the License.
                     </and>
                 </condition>
             </fail-->
-            <get src="@{src}" dest="@{dest}" unless:true="${exists}"/>
+            <get src="@{src}" dest="@{dest}" skipexisting="true"/>
         </sequential>
     </macrodef>
 
@@ -531,12 +536,14 @@ under the License.
                 <include name="jacoco-0.7.2*"/>
                 <include name="jacoco-0.7.3*"/>
                 <include name="jacoco-0.7.4*"/>
+                <include name="jacoco-0.7.6*"/>
                 <include name="log4j-1.2.13*"/>
                 <include name="org.jacoco.*-0.6.*"/>
                 <include name="org.jacoco.*-0.7.1*"/>
                 <include name="org.jacoco.*-0.7.2*"/>
                 <include name="org.jacoco.*-0.7.3*"/>
                 <include name="org.jacoco.*-0.7.4*"/>
+                <include name="org.jacoco.*-0.7.6*"/>
                 <include name="dom4j*"/>
                 <include name="apache-rat-0.10*"/>
                 <include name="xercesImpl-*.jar"/>
@@ -587,6 +594,7 @@ under the License.
                     <available file="${dsig.bouncycastle-pkix.jar}"/>
                     <available file="${dsig.xmlsec.jar}"/>
                     <available file="${dsig.sl4j-api.jar}"/>
+                    <available file="${main.commons-collections4.jar}"/>
                 </and>
                 <isset property="disconnected"/>
             </or>
@@ -605,6 +613,7 @@ under the License.
         <downloadfile src="${main.antlauncher.url}" dest="${main.antlauncher.jar}"/>
         <downloadfile src="${asm.url}" dest="${asm.jar}"/>
         <downloadfile src="${jacoco.url}" dest="${jacoco.zip}"/>
+        <downloadfile src="${main.commons-collections4.url}" dest="${main.commons-collections4.jar}"/>
         <unzip src="${jacoco.zip}" dest=".">
             <patternset>
                 <include name="lib/*.jar"/>
@@ -1161,6 +1170,8 @@ under the License.
                 <group name="Main">
                     <classfiles>
                         <fileset dir="${main.output.dir}">
+                            <!-- exclude some generated classes -->
+                            <exclude name="org/apache/poi/sl/draw/binding/*.class"/>
                             <!-- exclude large test-class -->
                             <exclude name="org/apache/poi/hssf/usermodel/DummyGraphics2d.class"/>
                         </fileset>
@@ -1242,6 +1253,8 @@ under the License.
                 <jvmarg value="-ea"/>
                 <jvmarg value="-Xmx256m"/>
                 <!-- jvmarg value="-Duser.timezone=UTC"/ -->
+                <jvmarg value="${java9addmods}" />
+                <jvmarg value="${java9addmodsvalue}" />
                 <formatter type="plain"/>
                 <formatter type="xml"/>
                 <batchtest todir="${main.reports.test}">
@@ -1258,6 +1271,16 @@ under the License.
         <antcall target="-test-main-write-testfile"/>
     </target>
 
+	<target name="test-report" depends="init">
+		<mkdir dir="build/report"/>
+		<junitreport todir="build/report">
+		  <fileset dir="build">
+			<include name="*results/**/TEST-*.xml"/>
+		  </fileset>
+		  <report format="frames" todir="build/report"/>
+		</junitreport>
+	</target>
+
     <target name="-test-property-check" unless="testcase">
         <echo message="Please use -Dtestcase=org.your.testcase to run a single test"/>
         <fail/>
@@ -1288,6 +1311,8 @@ under the License.
                 <jvmarg value="-ea"/>
                 <jvmarg value="-Xmx256m"/>
                 <!-- jvmarg value="-Duser.timezone=UTC"/ -->
+                <jvmarg value="${java9addmods}" />
+                <jvmarg value="${java9addmodsvalue}" />
                 <formatter type="plain"/>
                 <formatter type="xml"/>
                 <batchtest todir="${main.reports.test}">
@@ -1335,6 +1360,8 @@ under the License.
                   and on Windows with jdk-1.5.22
                 -->
                 <jvmarg value="-Xmx256M"/>
+                <jvmarg value="${java9addmods}" />
+                <jvmarg value="${java9addmodsvalue}" />
                 <formatter type="plain"/>
                 <formatter type="xml"/>
                 <batchtest todir="${scratchpad.reports.test}">
@@ -1373,6 +1400,8 @@ under the License.
                     <jvmarg value="${maxpermsize}"/>
                     <jvmarg value="-Xmx768M"/>
                   <jvmarg value="-ea"/>
+                  <jvmarg value="${java9addmods}" />
+                  <jvmarg value="${java9addmodsvalue}" />
                     <!-- jvmarg value="-Duser.timezone=UTC"/ -->
                   <formatter type="plain"/>
                   <formatter type="xml"/>
@@ -1396,6 +1425,8 @@ under the License.
                   <syspropertyset refid="junit.properties"/>
                     <jvmarg value="-Xmx768M"/>
                   <jvmarg value="-ea"/>
+                  <jvmarg value="${java9addmods}" />
+                  <jvmarg value="${java9addmodsvalue}" />
                   <formatter type="plain"/>
                   <formatter type="xml"/>
                   <batchtest todir="${ooxml.reports.test}">
@@ -1439,6 +1470,8 @@ under the License.
                     <jvmarg value="${maxpermsize}"/>
                     <jvmarg value="-Xmx768M"/>
                   <jvmarg value="-ea"/>
+                  <jvmarg value="${java9addmods}" />
+                  <jvmarg value="${java9addmodsvalue}" />
                     <!-- jvmarg value="-Duser.timezone=UTC"/ -->
                   <formatter type="plain"/>
                   <formatter type="xml"/>
@@ -1485,6 +1518,8 @@ under the License.
                 <syspropertyset refid="junit.properties"/>
                 <jvmarg value="-ea"/>
                 <jvmarg value="-Xmx1512M"/>
+                <jvmarg value="${java9addmods}" />
+                <jvmarg value="${java9addmodsvalue}" />
                 <formatter type="plain"/>
                 <formatter type="xml"/>
                 <batchtest todir="${integration.reports.test}">
@@ -1503,7 +1538,20 @@ under the License.
     </target>
 
     <!-- Section: test-ooxml-lite -->
-    <target name="compile-ooxml-lite" depends="compile-ooxml">
+    <target name="-compile-ooxml-lite-check">
+        <uptodate property="ooxml.lite.test.notRequired" targetfile="${ooxml.lite.testokfile}">
+            <srcfiles dir="${ooxml.src}"/>
+            <srcfiles dir="${ooxml.src.test}"/>
+            <srcfiles file="${ooxml.xsds.jar}"/>
+            <srcfiles file="${ooxml.security.jar}"/>
+        </uptodate>
+    </target>
+
+    <target name="compile-ooxml-lite" depends="-compile-ooxml-lite-check,compile-ooxml"
+            unless="ooxml.lite.test.notRequired">
+        <delete file="${ooxml.lite.testokfile}"/>
+        <echo message="Running ooxml-lite generator"/>
+
         <property name="ooxml.lite-merged.dir" location="build/ooxml-lite-merged"/>
         <mkdir dir="${ooxml.lite-merged.dir}"/>
 
@@ -1522,6 +1570,8 @@ under the License.
             <syspropertyset refid="junit.properties"/>
             <jvmarg value="${maxpermsize}"/>
             <jvmarg value="-Xmx512m"/>
+			<jvmarg value="${java9addmods}" />
+			<jvmarg value="${java9addmodsvalue}" />
             <arg value="-ooxml"/>
             <arg value="${ooxml.lite-merged.dir}/ooxml-lite-merged.jar"/>
             <arg value="-test"/>
@@ -1529,6 +1579,8 @@ under the License.
             <arg value="-dest"/>
             <arg value="${ooxml.lite.output.dir}"/>
         </java>
+
+        <echo file="${ooxml.lite.testokfile}" append="false" message="testok"/>
     </target>
 
     <target name="test-ooxml-lite" depends="jacocotask,compile-ooxml-xsds,compile-ooxml-lite">
@@ -1557,6 +1609,8 @@ under the License.
                 <classpath refid="test.excelant.classpath"/>
                 <syspropertyset refid="junit.properties"/>
                 <jvmarg value="-ea"/>
+                <jvmarg value="${java9addmods}" />
+                <jvmarg value="${java9addmodsvalue}" />
                 <formatter type="plain"/>
                 <formatter type="xml"/>
                 <batchtest todir="${excelant.reports.test}">
@@ -1868,6 +1922,7 @@ under the License.
                 <fileset dir="${main.lib}">
                     <include name="commons-codec-*.jar"/>
                     <include name="commons-logging-*.jar"/>
+                    <include name="commons-collections4-*.jar"/>
                     <include name="junit-*.jar"/>
                     <include name="log4j-*.jar"/>
                 </fileset>
@@ -2083,7 +2138,7 @@ under the License.
         </forbiddenapis>
     </target>
 
-    <target name="findbugs" depends="assemble">
+    <target name="findbugs" depends="jar">
         <downloadfile src="${findbugs.url}" dest="${findbugs.jar}"/>
 
         <property name="findbugs.home" value="build/findbugs" />
@@ -2103,11 +2158,13 @@ under the License.
     	   output="xml:withMessages"
     	   outputFile="build/findbugs.xml"
     	   effort="max"
+           failOnError="true"
            excludeFilter="src/resources/devtools/findbugs-filters.xml">
             <fileset dir="${dist.dir}/maven">
                 <include name="poi/poi-${version.id}.jar"/>
                 <include name="poi-scratchpad/poi-scratchpad-${version.id}.jar"/>
                 <include name="poi-ooxml/poi-ooxml-${version.id}.jar"/>
+                <include name="poi-excelant/poi-excelant-${version.id}.jar"/>
             </fileset>
             <auxClasspath path="${dsig.bouncycastle-pkix.jar}" />
             <auxClasspath path="${dsig.bouncycastle-prov.jar}" />
@@ -2117,9 +2174,11 @@ under the License.
             <auxClasspath path="${ooxml.security.jar}" />
             <auxClasspath path="${ooxml.curvesapi.jar}" />
             <auxClasspath path="${ooxml.xmlbeans26.jar}" />
+            <auxClasspath path="${main.commons-collections4.jar}" />
             <auxClasspath path="${main.commons-codec.jar}" />
             <auxClasspath path="${main.commons-logging.jar}" />
             <auxClasspath path="${main.junit.jar}" />
+            <auxClasspath path="${main.ant.jar}" />
             <sourcePath path="src/java" />
             <sourcePath path="src/ooxml/java" />
             <sourcePath path="src/scratchpad/src" />

Modified: poi/branches/hssf_cryptoapi/maven/poi.pom
URL: http://svn.apache.org/viewvc/poi/branches/hssf_cryptoapi/maven/poi.pom?rev=1755463&r1=1755462&r2=1755463&view=diff
==============================================================================
--- poi/branches/hssf_cryptoapi/maven/poi.pom (original)
+++ poi/branches/hssf_cryptoapi/maven/poi.pom Mon Aug  8 01:14:36 2016
@@ -91,6 +91,11 @@
       <scope>test</scope>
       <version>4.12</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-collections4</artifactId>
+      <version>4.1</version>
+    </dependency>
   </dependencies>
 
 </project>

Modified: poi/branches/hssf_cryptoapi/sonar/main/pom.xml
URL: http://svn.apache.org/viewvc/poi/branches/hssf_cryptoapi/sonar/main/pom.xml?rev=1755463&r1=1755462&r2=1755463&view=diff
==============================================================================
--- poi/branches/hssf_cryptoapi/sonar/main/pom.xml (original)
+++ poi/branches/hssf_cryptoapi/sonar/main/pom.xml Mon Aug  8 01:14:36 2016
@@ -111,6 +111,11 @@
 
     <dependencies>
         <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-collections4</artifactId>
+            <version>4.1</version>
+        </dependency>
+        <dependency>
             <groupId>commons-codec</groupId>
             <artifactId>commons-codec</artifactId>
             <version>1.10</version>

Modified: poi/branches/hssf_cryptoapi/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
URL: http://svn.apache.org/viewvc/poi/branches/hssf_cryptoapi/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java?rev=1755463&r1=1755462&r2=1755463&view=diff
==============================================================================
--- poi/branches/hssf_cryptoapi/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java (original)
+++ poi/branches/hssf_cryptoapi/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java Mon Aug  8 01:14:36 2016
@@ -34,184 +34,184 @@ import org.apache.poi.ss.formula.Formula
  * @author Jason Height (jheight at chariot dot net dot au)
  */
 public final class RowRecordsAggregate extends RecordAggregate {
-	private int _firstrow = -1;
-	private int _lastrow  = -1;
-	private final Map<Integer, RowRecord> _rowRecords;
-	private final ValueRecordsAggregate _valuesAgg;
-	private final List<Record> _unknownRecords;
-	private final SharedValueManager _sharedValueManager;
+    private int _firstrow = -1;
+    private int _lastrow  = -1;
+    private final Map<Integer, RowRecord> _rowRecords;
+    private final ValueRecordsAggregate _valuesAgg;
+    private final List<Record> _unknownRecords;
+    private final SharedValueManager _sharedValueManager;
 
-	// Cache values to speed up performance of
+    // Cache values to speed up performance of
     // getStartRowNumberForBlock / getEndRowNumberForBlock, see Bugzilla 47405
     private RowRecord[] _rowRecordValues = null;
 
-	/** Creates a new instance of ValueRecordsAggregate */
-	public RowRecordsAggregate() {
-		this(SharedValueManager.createEmpty());
-	}
-	private RowRecordsAggregate(SharedValueManager svm) {
-		if (svm == null) {
-			throw new IllegalArgumentException("SharedValueManager must be provided.");
-		}
-		_rowRecords = new TreeMap<Integer, RowRecord>();
-		_valuesAgg = new ValueRecordsAggregate();
-		_unknownRecords = new ArrayList<Record>();
-		_sharedValueManager = svm;
-	}
-
-	/**
-	 * @param rs record stream with all {@link SharedFormulaRecord}
-	 * {@link ArrayRecord}, {@link TableRecord} {@link MergeCellsRecord} Records removed
-	 * @param svm an initialised {@link SharedValueManager} (from the shared formula, array
-	 * and table records of the current sheet).  Never <code>null</code>.
-	 */
-	public RowRecordsAggregate(RecordStream rs, SharedValueManager svm) {
-		this(svm);
-		while(rs.hasNext()) {
-			Record rec = rs.getNext();
-			switch (rec.getSid()) {
-				case RowRecord.sid:
-					insertRow((RowRecord) rec);
-					continue;
+    /** Creates a new instance of ValueRecordsAggregate */
+    public RowRecordsAggregate() {
+        this(SharedValueManager.createEmpty());
+    }
+    private RowRecordsAggregate(SharedValueManager svm) {
+        if (svm == null) {
+            throw new IllegalArgumentException("SharedValueManager must be provided.");
+        }
+        _rowRecords = new TreeMap<Integer, RowRecord>();
+        _valuesAgg = new ValueRecordsAggregate();
+        _unknownRecords = new ArrayList<Record>();
+        _sharedValueManager = svm;
+    }
+
+    /**
+     * @param rs record stream with all {@link SharedFormulaRecord}
+     * {@link ArrayRecord}, {@link TableRecord} {@link MergeCellsRecord} Records removed
+     * @param svm an initialised {@link SharedValueManager} (from the shared formula, array
+     * and table records of the current sheet).  Never <code>null</code>.
+     */
+    public RowRecordsAggregate(RecordStream rs, SharedValueManager svm) {
+        this(svm);
+        while(rs.hasNext()) {
+            Record rec = rs.getNext();
+            switch (rec.getSid()) {
+                case RowRecord.sid:
+                    insertRow((RowRecord) rec);
+                    continue;
                 case DConRefRecord.sid:
                     addUnknownRecord(rec);
                     continue;
                 case DBCellRecord.sid:
-					// end of 'Row Block'.  Should only occur after cell records
-					// ignore DBCELL records because POI generates them upon re-serialization
-					continue;
-			}
-			if (rec instanceof UnknownRecord) {
-				// might need to keep track of where exactly these belong
-				addUnknownRecord(rec);
-				while (rs.peekNextSid() == ContinueRecord.sid) {
-					addUnknownRecord(rs.getNext());
-				}
-				continue;
-			}
-			if (rec instanceof MulBlankRecord) {
-				_valuesAgg.addMultipleBlanks((MulBlankRecord) rec);
-				continue;
-			}
-			if (!(rec instanceof CellValueRecordInterface)) {
-				throw new RuntimeException("Unexpected record type (" + rec.getClass().getName() + ")");
-			}
-			_valuesAgg.construct((CellValueRecordInterface)rec, rs, svm);
-		}
-	}
-	/**
-	 * Handles UnknownRecords which appear within the row/cell records
-	 */
-	private void addUnknownRecord(Record rec) {
-		// ony a few distinct record IDs are encountered by the existing POI test cases:
-		// 0x1065 // many
-		// 0x01C2 // several
-		// 0x0034 // few
-		// No documentation could be found for these
-
-		// keep the unknown records for re-serialization
-		_unknownRecords.add(rec);
-	}
-	public void insertRow(RowRecord row) {
-		// Integer integer = Integer.valueOf(row.getRowNumber());
-		_rowRecords.put(Integer.valueOf(row.getRowNumber()), row);
-		// Clear the cached values
-		_rowRecordValues = null; 
-		if ((row.getRowNumber() < _firstrow) || (_firstrow == -1)) {
-			_firstrow = row.getRowNumber();
-		}
-		if ((row.getRowNumber() > _lastrow) || (_lastrow == -1)) {
-			_lastrow = row.getRowNumber();
-		}
-	}
-
-	public void removeRow(RowRecord row) {
-		int rowIndex = row.getRowNumber();
-		_valuesAgg.removeAllCellsValuesForRow(rowIndex);
-		Integer key = Integer.valueOf(rowIndex);
-		RowRecord rr = _rowRecords.remove(key);
-		if (rr == null) {
-			throw new RuntimeException("Invalid row index (" + key.intValue() + ")");
-		}
-		if (row != rr) {
-			_rowRecords.put(key, rr);
-			throw new RuntimeException("Attempt to remove row that does not belong to this sheet");
-		}
-		
-		// Clear the cached values
-		_rowRecordValues = null;
-	}
+                    // end of 'Row Block'.  Should only occur after cell records
+                    // ignore DBCELL records because POI generates them upon re-serialization
+                    continue;
+            }
+            if (rec instanceof UnknownRecord) {
+                // might need to keep track of where exactly these belong
+                addUnknownRecord(rec);
+                while (rs.peekNextSid() == ContinueRecord.sid) {
+                    addUnknownRecord(rs.getNext());
+                }
+                continue;
+            }
+            if (rec instanceof MulBlankRecord) {
+                _valuesAgg.addMultipleBlanks((MulBlankRecord) rec);
+                continue;
+            }
+            if (!(rec instanceof CellValueRecordInterface)) {
+                throw new RuntimeException("Unexpected record type (" + rec.getClass().getName() + ")");
+            }
+            _valuesAgg.construct((CellValueRecordInterface)rec, rs, svm);
+        }
+    }
+    /**
+     * Handles UnknownRecords which appear within the row/cell records
+     */
+    private void addUnknownRecord(Record rec) {
+        // ony a few distinct record IDs are encountered by the existing POI test cases:
+        // 0x1065 // many
+        // 0x01C2 // several
+        // 0x0034 // few
+        // No documentation could be found for these
+
+        // keep the unknown records for re-serialization
+        _unknownRecords.add(rec);
+    }
+    public void insertRow(RowRecord row) {
+        // Integer integer = Integer.valueOf(row.getRowNumber());
+        _rowRecords.put(Integer.valueOf(row.getRowNumber()), row);
+        // Clear the cached values
+        _rowRecordValues = null; 
+        if ((row.getRowNumber() < _firstrow) || (_firstrow == -1)) {
+            _firstrow = row.getRowNumber();
+        }
+        if ((row.getRowNumber() > _lastrow) || (_lastrow == -1)) {
+            _lastrow = row.getRowNumber();
+        }
+    }
 
-	public RowRecord getRow(int rowIndex) {
+    public void removeRow(RowRecord row) {
+        int rowIndex = row.getRowNumber();
+        _valuesAgg.removeAllCellsValuesForRow(rowIndex);
+        Integer key = Integer.valueOf(rowIndex);
+        RowRecord rr = _rowRecords.remove(key);
+        if (rr == null) {
+            throw new RuntimeException("Invalid row index (" + key.intValue() + ")");
+        }
+        if (row != rr) {
+            _rowRecords.put(key, rr);
+            throw new RuntimeException("Attempt to remove row that does not belong to this sheet");
+        }
+        
+        // Clear the cached values
+        _rowRecordValues = null;
+    }
+
+    public RowRecord getRow(int rowIndex) {
         int maxrow = SpreadsheetVersion.EXCEL97.getLastRowIndex();
         if (rowIndex < 0 || rowIndex > maxrow) {
-			throw new IllegalArgumentException("The row number must be between 0 and " + maxrow + ", but had: " + rowIndex);
-		}
-		return _rowRecords.get(Integer.valueOf(rowIndex));
-	}
-
-	public int getPhysicalNumberOfRows()
-	{
-		return _rowRecords.size();
-	}
-
-	public int getFirstRowNum()
-	{
-		return _firstrow;
-	}
-
-	public int getLastRowNum()
-	{
-		return _lastrow;
-	}
-
-	/** Returns the number of row blocks.
-	 * <p/>The row blocks are goupings of rows that contain the DBCell record
-	 * after them
-	 */
-	public int getRowBlockCount() {
-	  int size = _rowRecords.size()/DBCellRecord.BLOCK_SIZE;
-	  if ((_rowRecords.size() % DBCellRecord.BLOCK_SIZE) != 0)
-		  size++;
-	  return size;
-	}
-
-	private int getRowBlockSize(int block) {
-	  return RowRecord.ENCODED_SIZE * getRowCountForBlock(block);
-	}
-
-	/** Returns the number of physical rows within a block*/
-	public int getRowCountForBlock(int block) {
-	  int startIndex = block * DBCellRecord.BLOCK_SIZE;
-	  int endIndex = startIndex + DBCellRecord.BLOCK_SIZE - 1;
-	  if (endIndex >= _rowRecords.size())
-		endIndex = _rowRecords.size()-1;
-
-	  return endIndex-startIndex+1;
-	}
-
-	/** Returns the physical row number of the first row in a block*/
-	private int getStartRowNumberForBlock(int block) {
-	    int startIndex = block * DBCellRecord.BLOCK_SIZE;
+            throw new IllegalArgumentException("The row number must be between 0 and " + maxrow + ", but had: " + rowIndex);
+        }
+        return _rowRecords.get(Integer.valueOf(rowIndex));
+    }
 
-        if(_rowRecordValues == null){
+    public int getPhysicalNumberOfRows()
+    {
+        return _rowRecords.size();
+    }
+
+    public int getFirstRowNum()
+    {
+        return _firstrow;
+    }
+
+    public int getLastRowNum()
+    {
+        return _lastrow;
+    }
+
+    /** Returns the number of row blocks.
+     * <p/>The row blocks are goupings of rows that contain the DBCell record
+     * after them
+     */
+    public int getRowBlockCount() {
+        int size = _rowRecords.size()/DBCellRecord.BLOCK_SIZE;
+        if ((_rowRecords.size() % DBCellRecord.BLOCK_SIZE) != 0)
+            size++;
+        return size;
+    }
+
+    private int getRowBlockSize(int block) {
+        return RowRecord.ENCODED_SIZE * getRowCountForBlock(block);
+    }
+
+    /** Returns the number of physical rows within a block*/
+    public int getRowCountForBlock(int block) {
+        int startIndex = block * DBCellRecord.BLOCK_SIZE;
+        int endIndex = startIndex + DBCellRecord.BLOCK_SIZE - 1;
+        if (endIndex >= _rowRecords.size())
+            endIndex = _rowRecords.size()-1;
+
+        return endIndex-startIndex+1;
+    }
+
+    /** Returns the physical row number of the first row in a block*/
+    private int getStartRowNumberForBlock(int block) {
+        int startIndex = block * DBCellRecord.BLOCK_SIZE;
+
+        if (_rowRecordValues == null) {
             _rowRecordValues = _rowRecords.values().toArray(new RowRecord[_rowRecords.size()]);
         }
 
         try {
             return _rowRecordValues[startIndex].getRowNumber();
         } catch(ArrayIndexOutOfBoundsException e) {
-		  throw new RuntimeException("Did not find start row for block " + block);
-	    }
-	}
-
-	/** Returns the physical row number of the end row in a block*/
-	private int getEndRowNumberForBlock(int block) {
-	  int endIndex = ((block + 1)*DBCellRecord.BLOCK_SIZE)-1;
-	  if (endIndex >= _rowRecords.size())
-		endIndex = _rowRecords.size()-1;
+            throw new RuntimeException("Did not find start row for block " + block);
+        }
+    }
+
+    /** Returns the physical row number of the end row in a block*/
+    private int getEndRowNumberForBlock(int block) {
+        int endIndex = ((block + 1)*DBCellRecord.BLOCK_SIZE)-1;
+        if (endIndex >= _rowRecords.size())
+            endIndex = _rowRecords.size()-1;
 
-        if(_rowRecordValues == null){
+        if (_rowRecordValues == null){
             _rowRecordValues = _rowRecords.values().toArray(new RowRecord[_rowRecords.size()]);
         }
 
@@ -219,287 +219,287 @@ public final class RowRecordsAggregate e
             return _rowRecordValues[endIndex].getRowNumber();
         } catch(ArrayIndexOutOfBoundsException e) {
             throw new RuntimeException("Did not find end row for block " + block);
-	  }
-	}
+      }
+    }
 
-	private int visitRowRecordsForBlock(int blockIndex, RecordVisitor rv) {
-		final int startIndex = blockIndex*DBCellRecord.BLOCK_SIZE;
-		final int endIndex = startIndex + DBCellRecord.BLOCK_SIZE;
-
-		Iterator<RowRecord> rowIterator = _rowRecords.values().iterator();
-
-		//Given that we basically iterate through the rows in order,
-		//For a performance improvement, it would be better to return an instance of
-		//an iterator and use that instance throughout, rather than recreating one and
-		//having to move it to the right position.
-		int i=0;
-		for (;i<startIndex;i++)
-		  rowIterator.next();
-		int result = 0;
-		while(rowIterator.hasNext() && (i++ < endIndex)) {
-		  Record rec = rowIterator.next();
-		  result += rec.getRecordSize();
-		  rv.visitRecord(rec);
-		}
-		return result;
-	}
+    private int visitRowRecordsForBlock(int blockIndex, RecordVisitor rv) {
+        final int startIndex = blockIndex*DBCellRecord.BLOCK_SIZE;
+        final int endIndex = startIndex + DBCellRecord.BLOCK_SIZE;
+
+        Iterator<RowRecord> rowIterator = _rowRecords.values().iterator();
+
+        //Given that we basically iterate through the rows in order,
+        //For a performance improvement, it would be better to return an instance of
+        //an iterator and use that instance throughout, rather than recreating one and
+        //having to move it to the right position.
+        int i=0;
+        for (;i<startIndex;i++)
+          rowIterator.next();
+        int result = 0;
+        while(rowIterator.hasNext() && (i++ < endIndex)) {
+          Record rec = rowIterator.next();
+          result += rec.getRecordSize();
+          rv.visitRecord(rec);
+        }
+        return result;
+    }
 
     @Override
     public void visitContainedRecords(RecordVisitor rv) {
 
-		PositionTrackingVisitor stv = new PositionTrackingVisitor(rv, 0);
-		//DBCells are serialized before row records.
-		final int blockCount = getRowBlockCount();
-		for (int blockIndex = 0; blockIndex < blockCount; blockIndex++) {
-			// Serialize a block of rows.
-			// Hold onto the position of the first row in the block
-			int pos=0;
-			// Hold onto the size of this block that was serialized
-			final int rowBlockSize = visitRowRecordsForBlock(blockIndex, rv);
-			pos += rowBlockSize;
-			// Serialize a block of cells for those rows
-			final int startRowNumber = getStartRowNumberForBlock(blockIndex);
-			final int endRowNumber = getEndRowNumberForBlock(blockIndex);
-			DBCellRecord.Builder dbcrBuilder = new DBCellRecord.Builder();
-			// Note: Cell references start from the second row...
-			int cellRefOffset = (rowBlockSize - RowRecord.ENCODED_SIZE);
-			for (int row = startRowNumber; row <= endRowNumber; row++) {
-				if (_valuesAgg.rowHasCells(row)) {
-					stv.setPosition(0);
-					_valuesAgg.visitCellsForRow(row, stv);
-					int rowCellSize = stv.getPosition();
-					pos += rowCellSize;
-					// Add the offset to the first cell for the row into the
-					// DBCellRecord.
-					dbcrBuilder.addCellOffset(cellRefOffset);
-					cellRefOffset = rowCellSize;
-				}
-			}
-			// Calculate Offset from the start of a DBCellRecord to the first Row
-			rv.visitRecord(dbcrBuilder.build(pos));
-		}
-		for (Record _unknownRecord : _unknownRecords) {
-			// Potentially breaking the file here since we don't know exactly where to write these records
-			rv.visitRecord(_unknownRecord);
-		}
-	}
-
-	public Iterator<RowRecord> getIterator() {
-		return _rowRecords.values().iterator();
-	}
-
-	public int findStartOfRowOutlineGroup(int row) {
-		// Find the start of the group.
-		RowRecord rowRecord = this.getRow( row );
-		int level = rowRecord.getOutlineLevel();
-		int currentRow = row;
-		while (currentRow >= 0 && this.getRow( currentRow ) != null) {
-			rowRecord = this.getRow( currentRow );
-			if (rowRecord.getOutlineLevel() < level) {
-				return currentRow + 1;
-			}
-			currentRow--;
-		}
-
-		return currentRow + 1;
-	}
-
-	public int findEndOfRowOutlineGroup(int row) {
-		int level = getRow( row ).getOutlineLevel();
-		int currentRow;
-		for (currentRow = row; currentRow < getLastRowNum(); currentRow++) {
-			if (getRow(currentRow) == null || getRow(currentRow).getOutlineLevel() < level) {
-				break;
-			}
-		}
-
-		return currentRow-1;
-	}
-
-	/**
-	 * Hide all rows at or below the current outline level
-	 * @return index of the <em>next<em> row after the last row that gets hidden
-	 */
-	private int writeHidden(RowRecord pRowRecord, int row) {
-		int rowIx = row;
-		RowRecord rowRecord = pRowRecord;
-		int level = rowRecord.getOutlineLevel();
-		while (rowRecord != null && getRow(rowIx).getOutlineLevel() >= level) {
-			rowRecord.setZeroHeight(true);
-			rowIx++;
-			rowRecord = getRow(rowIx);
-		}
-		return rowIx;
-	}
-
-	public void collapseRow(int rowNumber) {
-
-		// Find the start of the group.
-		int startRow = findStartOfRowOutlineGroup(rowNumber);
-		RowRecord rowRecord = getRow(startRow);
-
-		// Hide all the columns until the end of the group
-		int nextRowIx = writeHidden(rowRecord, startRow);
-
-		RowRecord row = getRow(nextRowIx);
-		if (row == null) {
-			row = createRow(nextRowIx);
-			insertRow(row);
-		}
-		// Write collapse field
-		row.setColapsed(true);
-	}
-
-	/**
-	 * Create a row record.
-	 *
-	 * @param rowNumber row number
-	 * @return RowRecord created for the passed in row number
-	 * @see org.apache.poi.hssf.record.RowRecord
-	 */
-	public static RowRecord createRow(int rowNumber) {
-		return new RowRecord(rowNumber);
-	}
-
-	public boolean isRowGroupCollapsed(int row) {
-		int collapseRow = findEndOfRowOutlineGroup(row) + 1;
-
-		return getRow(collapseRow) != null && getRow(collapseRow).getColapsed();
-	}
-
-	public void expandRow(int rowNumber) {
-		if (rowNumber == -1)
-			return;
-
-		// If it is already expanded do nothing.
-		if (!isRowGroupCollapsed(rowNumber)) {
-			return;
-		}
-
-		// Find the start of the group.
-		int startIdx = findStartOfRowOutlineGroup(rowNumber);
-		RowRecord row = getRow(startIdx);
-
-		// Find the end of the group.
-		int endIdx = findEndOfRowOutlineGroup(rowNumber);
-
-		// expand:
-		// collapsed bit must be unset
-		// hidden bit gets unset _if_ surrounding groups are expanded you can determine
-		//   this by looking at the hidden bit of the enclosing group.  You will have
-		//   to look at the start and the end of the current group to determine which
-		//   is the enclosing group
-		// hidden bit only is altered for this outline level.  ie.  don't un-collapse contained groups
-		if (!isRowGroupHiddenByParent(rowNumber)) {
-			for (int i = startIdx; i <= endIdx; i++) {
-				RowRecord otherRow = getRow(i);
-				if (row.getOutlineLevel() == otherRow.getOutlineLevel() || !isRowGroupCollapsed(i)) {
-					otherRow.setZeroHeight(false);
-				}
-			}
-		}
-
-		// Write collapse field
-		getRow(endIdx + 1).setColapsed(false);
-	}
-
-	public boolean isRowGroupHiddenByParent(int row) {
-		// Look out outline details of end
-		int endLevel;
-		boolean endHidden;
-		int endOfOutlineGroupIdx = findEndOfRowOutlineGroup(row);
-		if (getRow(endOfOutlineGroupIdx + 1) == null) {
-			endLevel = 0;
-			endHidden = false;
-		} else {
-			endLevel = getRow(endOfOutlineGroupIdx + 1).getOutlineLevel();
-			endHidden = getRow(endOfOutlineGroupIdx + 1).getZeroHeight();
-		}
-
-		// Look out outline details of start
-		int startLevel;
-		boolean startHidden;
-		int startOfOutlineGroupIdx = findStartOfRowOutlineGroup( row );
-		if (startOfOutlineGroupIdx - 1 < 0 || getRow(startOfOutlineGroupIdx - 1) == null) {
-			startLevel = 0;
-			startHidden = false;
-		} else {
-			startLevel = getRow(startOfOutlineGroupIdx - 1).getOutlineLevel();
-			startHidden = getRow(startOfOutlineGroupIdx - 1).getZeroHeight();
-		}
-
-		if (endLevel > startLevel) {
-			return endHidden;
-		}
-
-		return startHidden;
-	}
-	
-	/**
-	 * Returns an iterator for the cell values
-	 */
-	public Iterator<CellValueRecordInterface> getCellValueIterator() {
-		return _valuesAgg.iterator();
-	}
-
-	public IndexRecord createIndexRecord(int indexRecordOffset, int sizeOfInitialSheetRecords) {
-		IndexRecord result = new IndexRecord();
-		result.setFirstRow(_firstrow);
-		result.setLastRowAdd1(_lastrow + 1);
-		// Calculate the size of the records from the end of the BOF
-		// and up to the RowRecordsAggregate...
-
-		// Add the references to the DBCells in the IndexRecord (one for each block)
-		// Note: The offsets are relative to the Workbook BOF. Assume that this is
-		// 0 for now.....
-
-		int blockCount = getRowBlockCount();
-		// Calculate the size of this IndexRecord
-		int indexRecSize = IndexRecord.getRecordSizeForBlockCount(blockCount);
-
-		int currentOffset = indexRecordOffset + indexRecSize + sizeOfInitialSheetRecords;
-
-		for (int block = 0; block < blockCount; block++) {
-			// each row-block has a DBCELL record.
-			// The offset of each DBCELL record needs to be updated in the INDEX record
-
-			// account for row records in this row-block
-			currentOffset += getRowBlockSize(block);
-			// account for cell value records after those
-			currentOffset += _valuesAgg.getRowCellBlockSize(
-					getStartRowNumberForBlock(block), getEndRowNumberForBlock(block));
-
-			// currentOffset is now the location of the DBCELL record for this row-block
-			result.addDbcell(currentOffset);
-			// Add space required to write the DBCELL record (whose reference was just added).
-			currentOffset += (8 + (getRowCountForBlock(block) * 2));
-		}
-		return result;
-	}
-	public void insertCell(CellValueRecordInterface cvRec) {
-		_valuesAgg.insertCell(cvRec);
-	}
-	public void removeCell(CellValueRecordInterface cvRec) {
-		if (cvRec instanceof FormulaRecordAggregate) {
-			((FormulaRecordAggregate)cvRec).notifyFormulaChanging();
-		}
-		_valuesAgg.removeCell(cvRec);
-	}
-	public FormulaRecordAggregate createFormula(int row, int col) {
-		FormulaRecord fr = new FormulaRecord();
-		fr.setRow(row);
-		fr.setColumn((short) col);
-		return new FormulaRecordAggregate(fr, null, _sharedValueManager);
-	}
-	public void updateFormulasAfterRowShift(FormulaShifter formulaShifter, int currentExternSheetIndex) {
-		_valuesAgg.updateFormulasAfterRowShift(formulaShifter, currentExternSheetIndex);
-	}
-	public DimensionsRecord createDimensions() {
-		DimensionsRecord result = new DimensionsRecord();
-		result.setFirstRow(_firstrow);
-		result.setLastRow(_lastrow);
-		result.setFirstCol((short) _valuesAgg.getFirstCellNum());
-		result.setLastCol((short) _valuesAgg.getLastCellNum());
-		return result;
-	}
+        PositionTrackingVisitor stv = new PositionTrackingVisitor(rv, 0);
+        //DBCells are serialized before row records.
+        final int blockCount = getRowBlockCount();
+        for (int blockIndex = 0; blockIndex < blockCount; blockIndex++) {
+            // Serialize a block of rows.
+            // Hold onto the position of the first row in the block
+            int pos=0;
+            // Hold onto the size of this block that was serialized
+            final int rowBlockSize = visitRowRecordsForBlock(blockIndex, rv);
+            pos += rowBlockSize;
+            // Serialize a block of cells for those rows
+            final int startRowNumber = getStartRowNumberForBlock(blockIndex);
+            final int endRowNumber = getEndRowNumberForBlock(blockIndex);
+            DBCellRecord.Builder dbcrBuilder = new DBCellRecord.Builder();
+            // Note: Cell references start from the second row...
+            int cellRefOffset = (rowBlockSize - RowRecord.ENCODED_SIZE);
+            for (int row = startRowNumber; row <= endRowNumber; row++) {
+                if (_valuesAgg.rowHasCells(row)) {
+                    stv.setPosition(0);
+                    _valuesAgg.visitCellsForRow(row, stv);
+                    int rowCellSize = stv.getPosition();
+                    pos += rowCellSize;
+                    // Add the offset to the first cell for the row into the
+                    // DBCellRecord.
+                    dbcrBuilder.addCellOffset(cellRefOffset);
+                    cellRefOffset = rowCellSize;
+                }
+            }
+            // Calculate Offset from the start of a DBCellRecord to the first Row
+            rv.visitRecord(dbcrBuilder.build(pos));
+        }
+        for (Record _unknownRecord : _unknownRecords) {
+            // Potentially breaking the file here since we don't know exactly where to write these records
+            rv.visitRecord(_unknownRecord);
+        }
+    }
+
+    public Iterator<RowRecord> getIterator() {
+        return _rowRecords.values().iterator();
+    }
+
+    public int findStartOfRowOutlineGroup(int row) {
+        // Find the start of the group.
+        RowRecord rowRecord = this.getRow( row );
+        int level = rowRecord.getOutlineLevel();
+        int currentRow = row;
+        while (currentRow >= 0 && this.getRow( currentRow ) != null) {
+            rowRecord = this.getRow( currentRow );
+            if (rowRecord.getOutlineLevel() < level) {
+                return currentRow + 1;
+            }
+            currentRow--;
+        }
+
+        return currentRow + 1;
+    }
+
+    public int findEndOfRowOutlineGroup(int row) {
+        int level = getRow( row ).getOutlineLevel();
+        int currentRow;
+        for (currentRow = row; currentRow < getLastRowNum(); currentRow++) {
+            if (getRow(currentRow) == null || getRow(currentRow).getOutlineLevel() < level) {
+                break;
+            }
+        }
+
+        return currentRow-1;
+    }
+
+    /**
+     * Hide all rows at or below the current outline level
+     * @return index of the <em>next<em> row after the last row that gets hidden
+     */
+    private int writeHidden(RowRecord pRowRecord, int row) {
+        int rowIx = row;
+        RowRecord rowRecord = pRowRecord;
+        int level = rowRecord.getOutlineLevel();
+        while (rowRecord != null && getRow(rowIx).getOutlineLevel() >= level) {
+            rowRecord.setZeroHeight(true);
+            rowIx++;
+            rowRecord = getRow(rowIx);
+        }
+        return rowIx;
+    }
+
+    public void collapseRow(int rowNumber) {
+
+        // Find the start of the group.
+        int startRow = findStartOfRowOutlineGroup(rowNumber);
+        RowRecord rowRecord = getRow(startRow);
+
+        // Hide all the columns until the end of the group
+        int nextRowIx = writeHidden(rowRecord, startRow);
+
+        RowRecord row = getRow(nextRowIx);
+        if (row == null) {
+            row = createRow(nextRowIx);
+            insertRow(row);
+        }
+        // Write collapse field
+        row.setColapsed(true);
+    }
+
+    /**
+     * Create a row record.
+     *
+     * @param rowNumber row number
+     * @return RowRecord created for the passed in row number
+     * @see org.apache.poi.hssf.record.RowRecord
+     */
+    public static RowRecord createRow(int rowNumber) {
+        return new RowRecord(rowNumber);
+    }
+
+    public boolean isRowGroupCollapsed(int row) {
+        int collapseRow = findEndOfRowOutlineGroup(row) + 1;
+
+        return getRow(collapseRow) != null && getRow(collapseRow).getColapsed();
+    }
+
+    public void expandRow(int rowNumber) {
+        if (rowNumber == -1)
+            return;
+
+        // If it is already expanded do nothing.
+        if (!isRowGroupCollapsed(rowNumber)) {
+            return;
+        }
+
+        // Find the start of the group.
+        int startIdx = findStartOfRowOutlineGroup(rowNumber);
+        RowRecord row = getRow(startIdx);
+
+        // Find the end of the group.
+        int endIdx = findEndOfRowOutlineGroup(rowNumber);
+
+        // expand:
+        // collapsed bit must be unset
+        // hidden bit gets unset _if_ surrounding groups are expanded you can determine
+        //   this by looking at the hidden bit of the enclosing group.  You will have
+        //   to look at the start and the end of the current group to determine which
+        //   is the enclosing group
+        // hidden bit only is altered for this outline level.  ie.  don't un-collapse contained groups
+        if (!isRowGroupHiddenByParent(rowNumber)) {
+            for (int i = startIdx; i <= endIdx; i++) {
+                RowRecord otherRow = getRow(i);
+                if (row.getOutlineLevel() == otherRow.getOutlineLevel() || !isRowGroupCollapsed(i)) {
+                    otherRow.setZeroHeight(false);
+                }
+            }
+        }
+
+        // Write collapse field
+        getRow(endIdx + 1).setColapsed(false);
+    }
+
+    public boolean isRowGroupHiddenByParent(int row) {
+        // Look out outline details of end
+        int endLevel;
+        boolean endHidden;
+        int endOfOutlineGroupIdx = findEndOfRowOutlineGroup(row);
+        if (getRow(endOfOutlineGroupIdx + 1) == null) {
+            endLevel = 0;
+            endHidden = false;
+        } else {
+            endLevel = getRow(endOfOutlineGroupIdx + 1).getOutlineLevel();
+            endHidden = getRow(endOfOutlineGroupIdx + 1).getZeroHeight();
+        }
+
+        // Look out outline details of start
+        int startLevel;
+        boolean startHidden;
+        int startOfOutlineGroupIdx = findStartOfRowOutlineGroup( row );
+        if (startOfOutlineGroupIdx - 1 < 0 || getRow(startOfOutlineGroupIdx - 1) == null) {
+            startLevel = 0;
+            startHidden = false;
+        } else {
+            startLevel = getRow(startOfOutlineGroupIdx - 1).getOutlineLevel();
+            startHidden = getRow(startOfOutlineGroupIdx - 1).getZeroHeight();
+        }
+
+        if (endLevel > startLevel) {
+            return endHidden;
+        }
+
+        return startHidden;
+    }
+    
+    /**
+     * Returns an iterator for the cell values
+     */
+    public Iterator<CellValueRecordInterface> getCellValueIterator() {
+        return _valuesAgg.iterator();
+    }
+
+    public IndexRecord createIndexRecord(int indexRecordOffset, int sizeOfInitialSheetRecords) {
+        IndexRecord result = new IndexRecord();
+        result.setFirstRow(_firstrow);
+        result.setLastRowAdd1(_lastrow + 1);
+        // Calculate the size of the records from the end of the BOF
+        // and up to the RowRecordsAggregate...
+
+        // Add the references to the DBCells in the IndexRecord (one for each block)
+        // Note: The offsets are relative to the Workbook BOF. Assume that this is
+        // 0 for now.....
+
+        int blockCount = getRowBlockCount();
+        // Calculate the size of this IndexRecord
+        int indexRecSize = IndexRecord.getRecordSizeForBlockCount(blockCount);
+
+        int currentOffset = indexRecordOffset + indexRecSize + sizeOfInitialSheetRecords;
+
+        for (int block = 0; block < blockCount; block++) {
+            // each row-block has a DBCELL record.
+            // The offset of each DBCELL record needs to be updated in the INDEX record
+
+            // account for row records in this row-block
+            currentOffset += getRowBlockSize(block);
+            // account for cell value records after those
+            currentOffset += _valuesAgg.getRowCellBlockSize(
+                    getStartRowNumberForBlock(block), getEndRowNumberForBlock(block));
+
+            // currentOffset is now the location of the DBCELL record for this row-block
+            result.addDbcell(currentOffset);
+            // Add space required to write the DBCELL record (whose reference was just added).
+            currentOffset += (8 + (getRowCountForBlock(block) * 2));
+        }
+        return result;
+    }
+    public void insertCell(CellValueRecordInterface cvRec) {
+        _valuesAgg.insertCell(cvRec);
+    }
+    public void removeCell(CellValueRecordInterface cvRec) {
+        if (cvRec instanceof FormulaRecordAggregate) {
+            ((FormulaRecordAggregate)cvRec).notifyFormulaChanging();
+        }
+        _valuesAgg.removeCell(cvRec);
+    }
+    public FormulaRecordAggregate createFormula(int row, int col) {
+        FormulaRecord fr = new FormulaRecord();
+        fr.setRow(row);
+        fr.setColumn((short) col);
+        return new FormulaRecordAggregate(fr, null, _sharedValueManager);
+    }
+    public void updateFormulasAfterRowShift(FormulaShifter formulaShifter, int currentExternSheetIndex) {
+        _valuesAgg.updateFormulasAfterRowShift(formulaShifter, currentExternSheetIndex);
+    }
+    public DimensionsRecord createDimensions() {
+        DimensionsRecord result = new DimensionsRecord();
+        result.setFirstRow(_firstrow);
+        result.setLastRow(_lastrow);
+        result.setFirstCol((short) _valuesAgg.getFirstCellNum());
+        result.setLastCol((short) _valuesAgg.getLastCellNum());
+        return result;
+    }
 }

Modified: poi/branches/hssf_cryptoapi/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java
URL: http://svn.apache.org/viewvc/poi/branches/hssf_cryptoapi/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java?rev=1755463&r1=1755462&r2=1755463&view=diff
==============================================================================
--- poi/branches/hssf_cryptoapi/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java (original)
+++ poi/branches/hssf_cryptoapi/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java Mon Aug  8 01:14:36 2016
@@ -19,10 +19,10 @@ package org.apache.poi.hssf.usermodel;
 
 import java.util.Map;
 
+import org.apache.poi.ss.formula.BaseFormulaEvaluator;
 import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment;
 import org.apache.poi.ss.formula.IStabilityClassifier;
 import org.apache.poi.ss.formula.WorkbookEvaluator;
-import org.apache.poi.ss.formula.WorkbookEvaluatorProvider;
 import org.apache.poi.ss.formula.eval.BoolEval;
 import org.apache.poi.ss.formula.eval.ErrorEval;
 import org.apache.poi.ss.formula.eval.NumericValueEval;
@@ -33,8 +33,6 @@ import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.CellType;
 import org.apache.poi.ss.usermodel.CellValue;
 import org.apache.poi.ss.usermodel.FormulaEvaluator;
-import org.apache.poi.ss.usermodel.Row;
-import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.util.Internal;
 
@@ -45,362 +43,251 @@ import org.apache.poi.util.Internal;
  * cell values.  Be sure to call {@link #clearAllCachedResultValues()} if any workbook cells are changed between
  * calls to evaluate~ methods on this class.
  */
-public class HSSFFormulaEvaluator implements FormulaEvaluator, WorkbookEvaluatorProvider {
+public class HSSFFormulaEvaluator extends BaseFormulaEvaluator {
+    private final HSSFWorkbook _book;
 
-	private final WorkbookEvaluator _bookEvaluator;
-	private final HSSFWorkbook _book;
+    public HSSFFormulaEvaluator(HSSFWorkbook workbook) {
+        this(workbook, null);
+    }
+    /**
+     * @param workbook  The workbook to perform the formula evaluations in
+     * @param stabilityClassifier used to optimise caching performance. Pass <code>null</code>
+     * for the (conservative) assumption that any cell may have its definition changed after
+     * evaluation begins.
+     */
+    public HSSFFormulaEvaluator(HSSFWorkbook workbook, IStabilityClassifier stabilityClassifier) {
+        this(workbook, stabilityClassifier, null);
+    }
 
-	public HSSFFormulaEvaluator(HSSFWorkbook workbook) {
-		this(workbook, null);
-	}
-	/**
-	 * @param workbook  The workbook to perform the formula evaluations in
-	 * @param stabilityClassifier used to optimise caching performance. Pass <code>null</code>
-	 * for the (conservative) assumption that any cell may have its definition changed after
-	 * evaluation begins.
-	 */
-	public HSSFFormulaEvaluator(HSSFWorkbook workbook, IStabilityClassifier stabilityClassifier) {
-		this(workbook, stabilityClassifier, null);
-	}
+    /**
+     * @param workbook  The workbook to perform the formula evaluations in
+     * @param stabilityClassifier used to optimise caching performance. Pass <code>null</code>
+     * for the (conservative) assumption that any cell may have its definition changed after
+     * evaluation begins.
+     * @param udfFinder pass <code>null</code> for default (AnalysisToolPak only)
+     */
+    private HSSFFormulaEvaluator(HSSFWorkbook workbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) {
+        super(new WorkbookEvaluator(HSSFEvaluationWorkbook.create(workbook), stabilityClassifier, udfFinder));
+        _book = workbook;
+    }
 
-	/**
-	 * @param workbook  The workbook to perform the formula evaluations in
+    /**
+     * @param workbook  The workbook to perform the formula evaluations in
      * @param stabilityClassifier used to optimise caching performance. Pass <code>null</code>
      * for the (conservative) assumption that any cell may have its definition changed after
      * evaluation begins.
-	 * @param udfFinder pass <code>null</code> for default (AnalysisToolPak only)
-	 */
-	private HSSFFormulaEvaluator(HSSFWorkbook workbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) {
-		_book = workbook;
-		_bookEvaluator = new WorkbookEvaluator(HSSFEvaluationWorkbook.create(workbook), stabilityClassifier, udfFinder);
-	}
-
-	/**
-	 * @param workbook  The workbook to perform the formula evaluations in
-	 * @param stabilityClassifier used to optimise caching performance. Pass <code>null</code>
-	 * for the (conservative) assumption that any cell may have its definition changed after
-	 * evaluation begins.
-	 * @param udfFinder pass <code>null</code> for default (AnalysisToolPak only)
-	 */
-	public static HSSFFormulaEvaluator create(HSSFWorkbook workbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) {
-		return new HSSFFormulaEvaluator(workbook, stabilityClassifier, udfFinder);
-	}
-
-
-	/**
-	 * Coordinates several formula evaluators together so that formulas that involve external
-	 * references can be evaluated.
-	 * @param workbookNames the simple file names used to identify the workbooks in formulas
-	 * with external links (for example "MyData.xls" as used in a formula "[MyData.xls]Sheet1!A1")
-	 * @param evaluators all evaluators for the full set of workbooks required by the formulas.
-	 */
-	public static void setupEnvironment(String[] workbookNames, HSSFFormulaEvaluator[] evaluators) {
-		WorkbookEvaluator[] wbEvals = new WorkbookEvaluator[evaluators.length];
-		for (int i = 0; i < wbEvals.length; i++) {
-			wbEvals[i] = evaluators[i]._bookEvaluator;
-		}
-		CollaboratingWorkbooksEnvironment.setup(workbookNames, wbEvals);
-	}
+     * @param udfFinder pass <code>null</code> for default (AnalysisToolPak only)
+     */
+    public static HSSFFormulaEvaluator create(HSSFWorkbook workbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) {
+        return new HSSFFormulaEvaluator(workbook, stabilityClassifier, udfFinder);
+    }
 
-	@Override
+
+    /**
+     * Coordinates several formula evaluators together so that formulas that involve external
+     * references can be evaluated.
+     * @param workbookNames the simple file names used to identify the workbooks in formulas
+     * with external links (for example "MyData.xls" as used in a formula "[MyData.xls]Sheet1!A1")
+     * @param evaluators all evaluators for the full set of workbooks required by the formulas.
+     */
+    public static void setupEnvironment(String[] workbookNames, HSSFFormulaEvaluator[] evaluators) {
+        BaseFormulaEvaluator.setupEnvironment(workbookNames, evaluators);
+    }
+
+    @Override
     public void setupReferencedWorkbooks(Map<String, FormulaEvaluator> evaluators) {
         CollaboratingWorkbooksEnvironment.setupFormulaEvaluator(evaluators);
     }
-	
-    @Override
-    public WorkbookEvaluator _getWorkbookEvaluator() {
-        return _bookEvaluator;
+
+    /**
+     * Should be called to tell the cell value cache that the specified (value or formula) cell
+     * has changed.
+     * Failure to call this method after changing cell values will cause incorrect behaviour
+     * of the evaluate~ methods of this class
+     */
+    public void notifyUpdateCell(HSSFCell cell) {
+        _bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell(cell));
     }
-    
-	/**
-	 * Should be called whenever there are major changes (e.g. moving sheets) to input cells
-	 * in the evaluated workbook.  If performance is not critical, a single call to this method
-	 * may be used instead of many specific calls to the notify~ methods.
-	 *
-	 * Failure to call this method after changing cell values will cause incorrect behaviour
-	 * of the evaluate~ methods of this class
-	 */
-	@Override
-    public void clearAllCachedResultValues() {
-		_bookEvaluator.clearAllCachedResultValues();
-	}
-	/**
-	 * Should be called to tell the cell value cache that the specified (value or formula) cell
-	 * has changed.
-	 * Failure to call this method after changing cell values will cause incorrect behaviour
-	 * of the evaluate~ methods of this class
-	 */
-	public void notifyUpdateCell(HSSFCell cell) {
-		_bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell(cell));
-	}
     @Override
     public void notifyUpdateCell(Cell cell) {
         _bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell((HSSFCell)cell));
     }
-	/**
-	 * Should be called to tell the cell value cache that the specified cell has just been
-	 * deleted.
-	 * Failure to call this method after changing cell values will cause incorrect behaviour
-	 * of the evaluate~ methods of this class
-	 */
-	public void notifyDeleteCell(HSSFCell cell) {
-		_bookEvaluator.notifyDeleteCell(new HSSFEvaluationCell(cell));
-	}
-	@Override
+    /**
+     * Should be called to tell the cell value cache that the specified cell has just been
+     * deleted.
+     * Failure to call this method after changing cell values will cause incorrect behaviour
+     * of the evaluate~ methods of this class
+     */
+    public void notifyDeleteCell(HSSFCell cell) {
+        _bookEvaluator.notifyDeleteCell(new HSSFEvaluationCell(cell));
+    }
+    @Override
     public void notifyDeleteCell(Cell cell) {
-		_bookEvaluator.notifyDeleteCell(new HSSFEvaluationCell((HSSFCell)cell));
-	}
+        _bookEvaluator.notifyDeleteCell(new HSSFEvaluationCell((HSSFCell)cell));
+    }
 
-	/**
-	 * Should be called to tell the cell value cache that the specified (value or formula) cell
-	 * has changed.
-	 * Failure to call this method after changing cell values will cause incorrect behaviour
-	 * of the evaluate~ methods of this class
-	 */
-	@Override
+    /**
+     * Should be called to tell the cell value cache that the specified (value or formula) cell
+     * has changed.
+     * Failure to call this method after changing cell values will cause incorrect behaviour
+     * of the evaluate~ methods of this class
+     */
+    @Override
     public void notifySetFormula(Cell cell) {
-		_bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell((HSSFCell)cell));
-	}
+        _bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell((HSSFCell)cell));
+    }
+
+    /**
+     * If cell contains formula, it evaluates the formula, and saves the result of the formula. The
+     * cell remains as a formula cell. If the cell does not contain formula, rather than throwing an
+     * exception, this method returns {@link CellType#_NONE} and leaves the cell unchanged.
+     *
+     * Note that the type of the <em>formula result</em> is returned, so you know what kind of
+     * cached formula result is also stored with  the formula.
+     * <pre>
+     * CellType evaluatedCellType = evaluator.evaluateFormulaCell(cell);
+     * </pre>
+     * Be aware that your cell will hold both the formula, and the result. If you want the cell
+     * replaced with the result of the formula, use {@link #evaluateInCell(org.apache.poi.ss.usermodel.Cell)}
+     * @param cell The cell to evaluate
+     * @return {@link CellType#_NONE} for non-formula cells, or the type of the <em>formula result</em>
+     * @since POI 3.15 beta 3
+     * @deprecated POI 3.15 beta 3. Will be deleted when we make the CellType enum transition. See bug 59791.
+     */
+    @Internal
+    @Override
+    public CellType evaluateFormulaCellEnum(Cell cell) {
+        if (cell == null || cell.getCellTypeEnum() != CellType.FORMULA) {
+            return CellType._NONE;
+        }
+        CellValue cv = evaluateFormulaCellValue(cell);
+        // cell remains a formula cell, but the cached value is changed
+        setCellValue(cell, cv);
+        return cv.getCellType();
+    }
 
-	/**
-	 * If cell contains a formula, the formula is evaluated and returned,
-	 * else the CellValue simply copies the appropriate cell value from
-	 * the cell and also its cell type. This method should be preferred over
-	 * evaluateInCell() when the call should not modify the contents of the
-	 * original cell.
-	 *
-	 * @param cell may be <code>null</code> signifying that the cell is not present (or blank)
-	 * @return <code>null</code> if the supplied cell is <code>null</code> or blank
-	 */
-	@Override
-	public CellValue evaluate(Cell cell) {
-		if (cell == null) {
-			return null;
-		}
-
-		switch (cell.getCellTypeEnum()) {
-			case BOOLEAN:
-				return CellValue.valueOf(cell.getBooleanCellValue());
-			case ERROR:
-				return CellValue.getError(cell.getErrorCellValue());
-			case FORMULA:
-				return evaluateFormulaCellValue(cell);
-			case NUMERIC:
-				return new CellValue(cell.getNumericCellValue());
-			case STRING:
-				return new CellValue(cell.getRichStringCellValue().getString());
-			case BLANK:
-				return null;
-			default:
-				throw new IllegalStateException("Bad cell type (" + cell.getCellTypeEnum() + ")");
-		}
-		
-	}
-
-
-	/**
-	 * If cell contains formula, it evaluates the formula, and saves the result of the formula. The
-	 * cell remains as a formula cell. If the cell does not contain formula, this method returns -1
-	 * and leaves the cell unchanged.
-	 *
-	 * Note that the type of the <em>formula result</em> is returned, so you know what kind of
-	 * cached formula result is also stored with  the formula.
-	 * <pre>
-	 * int evaluatedCellType = evaluator.evaluateFormulaCell(cell);
-	 * </pre>
-	 * Be aware that your cell will hold both the formula, and the result. If you want the cell
-	 * replaced with the result of the formula, use {@link #evaluateInCell(org.apache.poi.ss.usermodel.Cell)}
-	 * @param cell The cell to evaluate
-	 * @return -1 for non-formula cells, or the type of the <em>formula result</em>
-	 */
-	@Override
-	public int evaluateFormulaCell(Cell cell) {
-		return evaluateFormulaCellEnum(cell).getCode();
-	}
-	
-	/**
-	 * If cell contains formula, it evaluates the formula, and saves the result of the formula. The
-	 * cell remains as a formula cell. If the cell does not contain formula, rather than throwing an
-	 * exception, this method returns {@link CellType#_NONE} and leaves the cell unchanged.
-	 *
-	 * Note that the type of the <em>formula result</em> is returned, so you know what kind of
-	 * cached formula result is also stored with  the formula.
-	 * <pre>
-	 * CellType evaluatedCellType = evaluator.evaluateFormulaCell(cell);
-	 * </pre>
-	 * Be aware that your cell will hold both the formula, and the result. If you want the cell
-	 * replaced with the result of the formula, use {@link #evaluateInCell(org.apache.poi.ss.usermodel.Cell)}
-	 * @param cell The cell to evaluate
-	 * @return {@link CellType#_NONE} for non-formula cells, or the type of the <em>formula result</em>
-	 * @since POI 3.15 beta 3
-	 * @deprecated POI 3.15 beta 3. Will be deleted when we make the CellType enum transition. See bug 59791.
-	 */
-	@Internal
-	@Override
-	public CellType evaluateFormulaCellEnum(Cell cell) {
-		if (cell == null || cell.getCellTypeEnum() != CellType.FORMULA) {
-			return CellType._NONE;
-		}
-		CellValue cv = evaluateFormulaCellValue(cell);
-		// cell remains a formula cell, but the cached value is changed
-		setCellValue(cell, cv);
-		return cv.getCellType();
-	}
-
-	/**
-	 * If cell contains formula, it evaluates the formula, and
-	 *  puts the formula result back into the cell, in place
-	 *  of the old formula.
-	 * Else if cell does not contain formula, this method leaves
-	 *  the cell unchanged.
-	 * Note that the same instance of HSSFCell is returned to
-	 * allow chained calls like:
-	 * <pre>
-	 * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
-	 * </pre>
-	 * Be aware that your cell value will be changed to hold the
-	 *  result of the formula. If you simply want the formula
-	 *  value computed for you, use {@link #evaluateFormulaCellEnum(Cell)}}
-	 */
-	@Override
-	public HSSFCell evaluateInCell(Cell cell) {
-		if (cell == null) {
-			return null;
-		}
-		HSSFCell result = (HSSFCell) cell;
-		if (cell.getCellTypeEnum() == CellType.FORMULA) {
-			CellValue cv = evaluateFormulaCellValue(cell);
-			setCellValue(cell, cv);
-			setCellType(cell, cv); // cell will no longer be a formula cell
-		}
-		return result;
-	}
-	private static void setCellType(Cell cell, CellValue cv) {
-		CellType cellType = cv.getCellType();
-		switch (cellType) {
-			case BOOLEAN:
-			case ERROR:
-			case NUMERIC:
-			case STRING:
-				cell.setCellType(cellType);
-				return;
-			case BLANK:
-				// never happens - blanks eventually get translated to zero
-			case FORMULA:
-				// this will never happen, we have already evaluated the formula
-			default:
-				throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
-		}
-		
-	}
-
-	private static void setCellValue(Cell cell, CellValue cv) {
-		CellType cellType = cv.getCellType();
-		switch (cellType) {
-			case BOOLEAN:
-				cell.setCellValue(cv.getBooleanValue());
-				break;
-			case ERROR:
-				cell.setCellErrorValue(cv.getErrorValue());
-				break;
-			case NUMERIC:
-				cell.setCellValue(cv.getNumberValue());
-				break;
-			case STRING:
-				cell.setCellValue(new HSSFRichTextString(cv.getStringValue()));
-				break;
-			case BLANK:
-				// never happens - blanks eventually get translated to zero
-			case FORMULA:
-				// this will never happen, we have already evaluated the formula
-			default:
-				throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
-		}
-	}
-
-	/**
-	 * Loops over all cells in all sheets of the supplied
-	 *  workbook.
-	 * For cells that contain formulas, their formulas are
-	 *  evaluated, and the results are saved. These cells
-	 *  remain as formula cells.
-	 * For cells that do not contain formulas, no changes
-	 *  are made.
-	 * This is a helpful wrapper around looping over all
-	 *  cells, and calling evaluateFormulaCell on each one.
-	 */
-	public static void evaluateAllFormulaCells(HSSFWorkbook wb) {
-	   evaluateAllFormulaCells(wb, new HSSFFormulaEvaluator(wb));
-	}
-	
-   /**
-    * Loops over all cells in all sheets of the supplied
-    *  workbook.
-    * For cells that contain formulas, their formulas are
-    *  evaluated, and the results are saved. These cells
-    *  remain as formula cells.
-    * For cells that do not contain formulas, no changes
-    *  are made.
-    * This is a helpful wrapper around looping over all
-    *  cells, and calling evaluateFormulaCell on each one.
-    */
-	public static void evaluateAllFormulaCells(Workbook wb) {
-      FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
-      evaluateAllFormulaCells(wb, evaluator);
-	}
-	private static void evaluateAllFormulaCells(Workbook wb, FormulaEvaluator evaluator) {
-      for(int i=0; i<wb.getNumberOfSheets(); i++) {
-         Sheet sheet = wb.getSheetAt(i);
-
-         for(Row r : sheet) {
-            for (Cell c : r) {
-               if (c.getCellTypeEnum() == CellType.FORMULA) {
-                  evaluator.evaluateFormulaCellEnum(c);
-               }
-            }
-         }
-      }
-	}
-	
-   /**
-    * Loops over all cells in all sheets of the supplied
-    *  workbook.
-    * For cells that contain formulas, their formulas are
-    *  evaluated, and the results are saved. These cells
-    *  remain as formula cells.
-    * For cells that do not contain formulas, no changes
-    *  are made.
-    * This is a helpful wrapper around looping over all
-    *  cells, and calling evaluateFormulaCell on each one.
-    */
-   @Override
-public void evaluateAll() {
-      evaluateAllFormulaCells(_book, this);
-   }
-
-	/**
-	 * Returns a CellValue wrapper around the supplied ValueEval instance.
-	 * @param cell
-	 */
-	private CellValue evaluateFormulaCellValue(Cell cell) {
-		ValueEval eval = _bookEvaluator.evaluate(new HSSFEvaluationCell((HSSFCell)cell));
-		if (eval instanceof BoolEval) {
-			BoolEval be = (BoolEval) eval;
-			return CellValue.valueOf(be.getBooleanValue());
-		}
-		if (eval instanceof NumericValueEval) {
-			NumericValueEval ne = (NumericValueEval) eval;
-			return new CellValue(ne.getNumberValue());
-		}
-		if (eval instanceof StringValueEval) {
-			StringValueEval ne = (StringValueEval) eval;
-			return new CellValue(ne.getStringValue());
-		}
-		if (eval instanceof ErrorEval) {
-			return CellValue.getError(((ErrorEval)eval).getErrorCode());
-		}
-		throw new RuntimeException("Unexpected eval class (" + eval.getClass().getName() + ")");
-	}
+    /**
+     * If cell contains formula, it evaluates the formula, and
+     *  puts the formula result back into the cell, in place
+     *  of the old formula.
+     * Else if cell does not contain formula, this method leaves
+     *  the cell unchanged.
+     * Note that the same instance of HSSFCell is returned to
+     * allow chained calls like:
+     * <pre>
+     * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
+     * </pre>
+     * Be aware that your cell value will be changed to hold the
+     *  result of the formula. If you simply want the formula
+     *  value computed for you, use {@link #evaluateFormulaCellEnum(Cell)}}
+     */
+    @Override
+    public HSSFCell evaluateInCell(Cell cell) {
+        if (cell == null) {
+            return null;
+        }
+        HSSFCell result = (HSSFCell) cell;
+        if (cell.getCellTypeEnum() == CellType.FORMULA) {
+            CellValue cv = evaluateFormulaCellValue(cell);
+            setCellValue(cell, cv);
+            setCellType(cell, cv); // cell will no longer be a formula cell
+        }
+        return result;
+    }
+
+    private static void setCellValue(Cell cell, CellValue cv) {
+        CellType cellType = cv.getCellType();
+        switch (cellType) {
+            case BOOLEAN:
+                cell.setCellValue(cv.getBooleanValue());
+                break;
+            case ERROR:
+                cell.setCellErrorValue(cv.getErrorValue());
+                break;
+            case NUMERIC:
+                cell.setCellValue(cv.getNumberValue());
+                break;
+            case STRING:
+                cell.setCellValue(new HSSFRichTextString(cv.getStringValue()));
+                break;
+            case BLANK:
+                // never happens - blanks eventually get translated to zero
+            case FORMULA:
+                // this will never happen, we have already evaluated the formula
+            default:
+                throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
+        }
+    }
+
+    /**
+     * Loops over all cells in all sheets of the supplied
+     *  workbook.
+     * For cells that contain formulas, their formulas are
+     *  evaluated, and the results are saved. These cells
+     *  remain as formula cells.
+     * For cells that do not contain formulas, no changes
+     *  are made.
+     * This is a helpful wrapper around looping over all
+     *  cells, and calling evaluateFormulaCell on each one.
+     */
+    public static void evaluateAllFormulaCells(HSSFWorkbook wb) {
+        evaluateAllFormulaCells(wb, new HSSFFormulaEvaluator(wb));
+    }
+
+    /**
+     * Loops over all cells in all sheets of the supplied
+     *  workbook.
+     * For cells that contain formulas, their formulas are
+     *  evaluated, and the results are saved. These cells
+     *  remain as formula cells.
+     * For cells that do not contain formulas, no changes
+     *  are made.
+     * This is a helpful wrapper around looping over all
+     *  cells, and calling evaluateFormulaCell on each one.
+     */
+    public static void evaluateAllFormulaCells(Workbook wb) {
+        BaseFormulaEvaluator.evaluateAllFormulaCells(wb);
+    }
+
+    /**
+     * Loops over all cells in all sheets of the supplied
+     *  workbook.
+     * For cells that contain formulas, their formulas are
+     *  evaluated, and the results are saved. These cells
+     *  remain as formula cells.
+     * For cells that do not contain formulas, no changes
+     *  are made.
+     * This is a helpful wrapper around looping over all
+     *  cells, and calling evaluateFormulaCell on each one.
+     */
+    @Override
+    public void evaluateAll() {
+        evaluateAllFormulaCells(_book, this);
+    }
+
+    /**
+     * Returns a CellValue wrapper around the supplied ValueEval instance.
+     * @param cell
+     */
+    protected CellValue evaluateFormulaCellValue(Cell cell) {
+        ValueEval eval = _bookEvaluator.evaluate(new HSSFEvaluationCell((HSSFCell)cell));
+        if (eval instanceof BoolEval) {
+            BoolEval be = (BoolEval) eval;
+            return CellValue.valueOf(be.getBooleanValue());
+        }
+        if (eval instanceof NumericValueEval) {
+            NumericValueEval ne = (NumericValueEval) eval;
+            return new CellValue(ne.getNumberValue());
+        }
+        if (eval instanceof StringValueEval) {
+            StringValueEval ne = (StringValueEval) eval;
+            return new CellValue(ne.getStringValue());
+        }
+        if (eval instanceof ErrorEval) {
+            return CellValue.getError(((ErrorEval)eval).getErrorCode());
+        }
+        throw new RuntimeException("Unexpected eval class (" + eval.getClass().getName() + ")");
+    }
 
     /** {@inheritDoc} */
     @Override

Modified: poi/branches/hssf_cryptoapi/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
URL: http://svn.apache.org/viewvc/poi/branches/hssf_cryptoapi/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java?rev=1755463&r1=1755462&r2=1755463&view=diff
==============================================================================
--- poi/branches/hssf_cryptoapi/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java (original)
+++ poi/branches/hssf_cryptoapi/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java Mon Aug  8 01:14:36 2016
@@ -92,6 +92,7 @@ import org.apache.poi.ss.formula.SheetNa
 import org.apache.poi.ss.formula.udf.AggregatingUDFFinder;
 import org.apache.poi.ss.formula.udf.IndexedUDFFinder;
 import org.apache.poi.ss.formula.udf.UDFFinder;
+import org.apache.poi.ss.usermodel.Name;
 import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.Workbook;
@@ -548,7 +549,7 @@ public final class HSSFWorkbook extends
      * the 'active' sheet (which is the sheet with focus).
      * Unselects sheets that are not in <code>indexes</code>.
      *
-     * @param indexes
+     * @param indexes Array of sheets to select, the index is 0-based.
      */
     public void setSelectedTabs(int[] indexes) {
         Collection<Integer> list = new ArrayList<Integer>(indexes.length);
@@ -563,7 +564,7 @@ public final class HSSFWorkbook extends
      * the 'active' sheet (which is the sheet with focus).
      * Unselects sheets that are not in <code>indexes</code>.
      *
-     * @param indexes
+     * @param indexes Collection of sheets to select, the index is 0-based.
      */
     public void setSelectedTabs(Collection<Integer> indexes) {
 
@@ -893,8 +894,7 @@ public final class HSSFWorkbook extends
      */
     @Override
     public Iterator<Sheet> sheetIterator() {
-        Iterator<Sheet> result = new SheetIterator<Sheet>();
-        return result;
+        return new SheetIterator<Sheet>();
     }
 
     /**
@@ -1280,9 +1280,9 @@ public final class HSSFWorkbook extends
 
     /**
      * Closes the underlying {@link NPOIFSFileSystem} from which
-     *  the Workbook was read, if any. Has no effect on Workbooks
-     *  opened from an InputStream, or newly created ones.
-     * <p>Once {@link #close()} has been called, no further 
+     *  the Workbook was read, if any.
+     *
+     * <p>Once this has been called, no further
      *  operations, updates or reads should be performed on the 
      *  Workbook.
      */
@@ -1531,6 +1531,11 @@ public final class HSSFWorkbook extends
         return names.get(nameIndex);
     }
 
+    @Override
+    public List<HSSFName> getAllNames() {
+        return Collections.unmodifiableList(names);
+    }
+
     public NameRecord getNameRecord(int nameIndex) {
         return getWorkbook().getNameRecord(nameIndex);
     }
@@ -1702,8 +1707,9 @@ public final class HSSFWorkbook extends
      *
      * @param name the name to remove.
      */
-    void removeName(HSSFName name) {
-      int index = getNameIndex(name);
+    @Override
+    public void removeName(Name name) {
+      int index = getNameIndex((HSSFName) name);
       removeName(index);
     }
 

Modified: poi/branches/hssf_cryptoapi/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java
URL: http://svn.apache.org/viewvc/poi/branches/hssf_cryptoapi/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java?rev=1755463&r1=1755462&r2=1755463&view=diff
==============================================================================
--- poi/branches/hssf_cryptoapi/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java (original)
+++ poi/branches/hssf_cryptoapi/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java Mon Aug  8 01:14:36 2016
@@ -374,20 +374,22 @@ public class CryptoFunctions {
         // SET Verifier TO 0x0000
         short verifier = 0;
 
-        // FOR EACH PasswordByte IN PasswordArray IN REVERSE ORDER
-        for (int i = arrByteChars.length-1; i >= 0; i--) {
-            // SET Verifier TO Intermediate3 BITWISE XOR PasswordByte
+        if (!"".equals(password)) {
+            // FOR EACH PasswordByte IN PasswordArray IN REVERSE ORDER
+            for (int i = arrByteChars.length-1; i >= 0; i--) {
+                // SET Verifier TO Intermediate3 BITWISE XOR PasswordByte
+                verifier = rotateLeftBase15Bit(verifier);
+                verifier ^= arrByteChars[i];
+            }
+    
+            // as we haven't prepended the password length into the input array
+            // we need to do it now separately ...
             verifier = rotateLeftBase15Bit(verifier);
-            verifier ^= arrByteChars[i];
+            verifier ^= arrByteChars.length;
+            
+            // RETURN Verifier BITWISE XOR 0xCE4B
+            verifier ^= 0xCE4B; // (0x8000 | ('N' << 8) | 'K')
         }
-
-        // as we haven't prepended the password length into the input array
-        // we need to do it now separately ...
-        verifier = rotateLeftBase15Bit(verifier);
-        verifier ^= arrByteChars.length;
-        
-        // RETURN Verifier BITWISE XOR 0xCE4B
-        verifier ^= 0xCE4B; // (0x8000 | ('N' << 8) | 'K')
         
         return verifier & 0xFFFF;
     }

Modified: poi/branches/hssf_cryptoapi/src/java/org/apache/poi/ss/formula/LazyRefEval.java
URL: http://svn.apache.org/viewvc/poi/branches/hssf_cryptoapi/src/java/org/apache/poi/ss/formula/LazyRefEval.java?rev=1755463&r1=1755462&r2=1755463&view=diff
==============================================================================
--- poi/branches/hssf_cryptoapi/src/java/org/apache/poi/ss/formula/LazyRefEval.java (original)
+++ poi/branches/hssf_cryptoapi/src/java/org/apache/poi/ss/formula/LazyRefEval.java Mon Aug  8 01:14:36 2016
@@ -27,7 +27,7 @@ import org.apache.poi.ss.util.CellRefere
 /**
  * Provides Lazy Evaluation to a 3D Reference
  */
-final class LazyRefEval extends RefEvalBase {
+public final class LazyRefEval extends RefEvalBase {
 	private final SheetRangeEvaluator _evaluator;
 
 	public LazyRefEval(int rowIndex, int columnIndex, SheetRangeEvaluator sre) {
@@ -47,14 +47,17 @@ final class LazyRefEval extends RefEvalB
 		return new LazyAreaEval(area, _evaluator);
 	}
 
+	public boolean isSubTotal() {
+		SheetRefEvaluator sheetEvaluator = _evaluator.getSheetEvaluator(getFirstSheetIndex());
+		return sheetEvaluator.isSubTotal(getRow(), getColumn());
+	}
+
 	public String toString() {
 		CellReference cr = new CellReference(getRow(), getColumn());
-		StringBuffer sb = new StringBuffer();
-		sb.append(getClass().getName()).append("[");
-		sb.append(_evaluator.getSheetNameRange());
-		sb.append('!');
-		sb.append(cr.formatAsString());
-		sb.append("]");
-		return sb.toString();
+		return getClass().getName() + "[" +
+				_evaluator.getSheetNameRange() +
+				'!' +
+				cr.formatAsString() +
+				"]";
 	}
 }




---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org