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