You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by jo...@apache.org on 2009/05/19 18:29:53 UTC
svn commit: r776377 [2/6] - in /poi/trunk/src/java/org/apache/poi: ddf/
hssf/model/ hssf/record/ hssf/record/aggregates/ hssf/record/cont/
hssf/record/formula/ hssf/record/formula/eval/ hssf/usermodel/ hssf/util/
poifs/dev/ ss/ ss/formula/ ss/formula/e...
Modified: poi/trunk/src/java/org/apache/poi/hssf/record/cont/ContinuableRecordOutput.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/cont/ContinuableRecordOutput.java?rev=776377&r1=776376&r2=776377&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/cont/ContinuableRecordOutput.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/cont/ContinuableRecordOutput.java Tue May 19 16:29:51 2009
@@ -1,257 +1,257 @@
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.record.cont;
-
-import org.apache.poi.hssf.record.ContinueRecord;
-import org.apache.poi.util.DelayableLittleEndianOutput;
-import org.apache.poi.util.LittleEndianOutput;
-import org.apache.poi.util.StringUtil;
-
-/**
- * An augmented {@link LittleEndianOutput} used for serialization of {@link ContinuableRecord}s.
- * This class keeps track of how much remaining space is available in the current BIFF record and
- * can start new {@link ContinueRecord}s as required.
- *
- * @author Josh Micich
- */
-public final class ContinuableRecordOutput implements LittleEndianOutput {
-
- private final LittleEndianOutput _out;
- private UnknownLengthRecordOutput _ulrOutput;
- private int _totalPreviousRecordsSize;
-
- ContinuableRecordOutput(LittleEndianOutput out, int sid) {
- _ulrOutput = new UnknownLengthRecordOutput(out, sid);
- _out = out;
- _totalPreviousRecordsSize = 0;
- }
-
- public static ContinuableRecordOutput createForCountingOnly() {
- return new ContinuableRecordOutput(NOPOutput, -777); // fake sid
- }
-
- /**
- * @return total number of bytes written so far (including all BIFF headers)
- */
- public int getTotalSize() {
- return _totalPreviousRecordsSize + _ulrOutput.getTotalSize();
- }
- /**
- * Terminates the last record (also updates its 'ushort size' field)
- */
- void terminate() {
- _ulrOutput.terminate();
- }
- /**
- * @return number of remaining bytes of space in current record
- */
- public int getAvailableSpace() {
- return _ulrOutput.getAvailableSpace();
- }
-
- /**
- * Terminates the current record and starts a new {@link ContinueRecord} (regardless
- * of how much space is still available in the current record).
- */
- public void writeContinue() {
- _ulrOutput.terminate();
- _totalPreviousRecordsSize += _ulrOutput.getTotalSize();
- _ulrOutput = new UnknownLengthRecordOutput(_out, ContinueRecord.sid);
- }
- public void writeContinueIfRequired(int requiredContinuousSize) {
- if (_ulrOutput.getAvailableSpace() < requiredContinuousSize) {
- writeContinue();
- }
- }
-
- /**
- * Writes the 'optionFlags' byte and encoded character data of a unicode string. This includes:
- * <ul>
- * <li>byte optionFlags</li>
- * <li>encoded character data (in "ISO-8859-1" or "UTF-16LE" encoding)</li>
- * </ul>
- *
- * Notes:
- * <ul>
- * <li>The value of the 'is16bitEncoded' flag is determined by the actual character data
- * of <tt>text</tt></li>
- * <li>The string options flag is never separated (by a {@link ContinueRecord}) from the
- * first chunk of character data it refers to.</li>
- * <li>The 'ushort length' field is assumed to have been explicitly written earlier. Hence,
- * there may be an intervening {@link ContinueRecord}</li>
- * </ul>
- */
- public void writeStringData(String text) {
- boolean is16bitEncoded = StringUtil.hasMultibyte(text);
- // calculate total size of the header and first encoded char
- int keepTogetherSize = 1 + 1; // ushort len, at least one character byte
- int optionFlags = 0x00;
- if (is16bitEncoded) {
- optionFlags |= 0x01;
- keepTogetherSize += 1; // one extra byte for first char
- }
- writeContinueIfRequired(keepTogetherSize);
- writeByte(optionFlags);
- writeCharacterData(text, is16bitEncoded);
- }
- /**
- * Writes a unicode string complete with header and character data. This includes:
- * <ul>
- * <li>ushort length</li>
- * <li>byte optionFlags</li>
- * <li>ushort numberOfRichTextRuns (optional)</li>
- * <li>ushort extendedDataSize (optional)</li>
- * <li>encoded character data (in "ISO-8859-1" or "UTF-16LE" encoding)</li>
- * </ul>
- *
- * The following bits of the 'optionFlags' byte will be set as appropriate:
- * <table border='1'>
- * <tr><th>Mask</th><th>Description</th></tr>
- * <tr><td>0x01</td><td>is16bitEncoded</td></tr>
- * <tr><td>0x04</td><td>hasExtendedData</td></tr>
- * <tr><td>0x08</td><td>isRichText</td></tr>
- * </table>
- * Notes:
- * <ul>
- * <li>The value of the 'is16bitEncoded' flag is determined by the actual character data
- * of <tt>text</tt></li>
- * <li>The string header fields are never separated (by a {@link ContinueRecord}) from the
- * first chunk of character data (i.e. the first character is always encoded in the same
- * record as the string header).</li>
- * </ul>
- */
- public void writeString(String text, int numberOfRichTextRuns, int extendedDataSize) {
- boolean is16bitEncoded = StringUtil.hasMultibyte(text);
- // calculate total size of the header and first encoded char
- int keepTogetherSize = 2 + 1 + 1; // ushort len, byte optionFlags, at least one character byte
- int optionFlags = 0x00;
- if (is16bitEncoded) {
- optionFlags |= 0x01;
- keepTogetherSize += 1; // one extra byte for first char
- }
- if (numberOfRichTextRuns > 0) {
- optionFlags |= 0x08;
- keepTogetherSize += 2;
- }
- if (extendedDataSize > 0) {
- optionFlags |= 0x04;
- keepTogetherSize += 4;
- }
- writeContinueIfRequired(keepTogetherSize);
- writeShort(text.length());
- writeByte(optionFlags);
- if (numberOfRichTextRuns > 0) {
- writeShort(numberOfRichTextRuns);
- }
- if (extendedDataSize > 0) {
- writeInt(extendedDataSize);
- }
- writeCharacterData(text, is16bitEncoded);
- }
-
-
- private void writeCharacterData(String text, boolean is16bitEncoded) {
- int nChars = text.length();
- int i=0;
- if (is16bitEncoded) {
- while(true) {
- int nWritableChars = Math.min(nChars-i, _ulrOutput.getAvailableSpace() / 2);
- for ( ; nWritableChars > 0; nWritableChars--) {
- _ulrOutput.writeShort(text.charAt(i++));
- }
- if (i >= nChars) {
- break;
- }
- writeContinue();
- writeByte(0x01);
- }
- } else {
- while(true) {
- int nWritableChars = Math.min(nChars-i, _ulrOutput.getAvailableSpace() / 1);
- for ( ; nWritableChars > 0; nWritableChars--) {
- _ulrOutput.writeByte(text.charAt(i++));
- }
- if (i >= nChars) {
- break;
- }
- writeContinue();
- writeByte(0x00);
- }
- }
- }
-
- public void write(byte[] b) {
- writeContinueIfRequired(b.length);
- _ulrOutput.write(b);
- }
- public void write(byte[] b, int offset, int len) {
- writeContinueIfRequired(len);
- _ulrOutput.write(b, offset, len);
- }
- public void writeByte(int v) {
- writeContinueIfRequired(1);
- _ulrOutput.writeByte(v);
- }
- public void writeDouble(double v) {
- writeContinueIfRequired(8);
- _ulrOutput.writeDouble(v);
- }
- public void writeInt(int v) {
- writeContinueIfRequired(4);
- _ulrOutput.writeInt(v);
- }
- public void writeLong(long v) {
- writeContinueIfRequired(8);
- _ulrOutput.writeLong(v);
- }
- public void writeShort(int v) {
- writeContinueIfRequired(2);
- _ulrOutput.writeShort(v);
- }
-
- /**
- * Allows optimised usage of {@link ContinuableRecordOutput} for sizing purposes only.
- */
- private static final LittleEndianOutput NOPOutput = new DelayableLittleEndianOutput() {
-
- public LittleEndianOutput createDelayedOutput(int size) {
- return this;
- }
- public void write(byte[] b) {
- // does nothing
- }
- public void write(byte[] b, int offset, int len) {
- // does nothing
- }
- public void writeByte(int v) {
- // does nothing
- }
- public void writeDouble(double v) {
- // does nothing
- }
- public void writeInt(int v) {
- // does nothing
- }
- public void writeLong(long v) {
- // does nothing
- }
- public void writeShort(int v) {
- // does nothing
- }
- };
-}
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.cont;
+
+import org.apache.poi.hssf.record.ContinueRecord;
+import org.apache.poi.util.DelayableLittleEndianOutput;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * An augmented {@link LittleEndianOutput} used for serialization of {@link ContinuableRecord}s.
+ * This class keeps track of how much remaining space is available in the current BIFF record and
+ * can start new {@link ContinueRecord}s as required.
+ *
+ * @author Josh Micich
+ */
+public final class ContinuableRecordOutput implements LittleEndianOutput {
+
+ private final LittleEndianOutput _out;
+ private UnknownLengthRecordOutput _ulrOutput;
+ private int _totalPreviousRecordsSize;
+
+ ContinuableRecordOutput(LittleEndianOutput out, int sid) {
+ _ulrOutput = new UnknownLengthRecordOutput(out, sid);
+ _out = out;
+ _totalPreviousRecordsSize = 0;
+ }
+
+ public static ContinuableRecordOutput createForCountingOnly() {
+ return new ContinuableRecordOutput(NOPOutput, -777); // fake sid
+ }
+
+ /**
+ * @return total number of bytes written so far (including all BIFF headers)
+ */
+ public int getTotalSize() {
+ return _totalPreviousRecordsSize + _ulrOutput.getTotalSize();
+ }
+ /**
+ * Terminates the last record (also updates its 'ushort size' field)
+ */
+ void terminate() {
+ _ulrOutput.terminate();
+ }
+ /**
+ * @return number of remaining bytes of space in current record
+ */
+ public int getAvailableSpace() {
+ return _ulrOutput.getAvailableSpace();
+ }
+
+ /**
+ * Terminates the current record and starts a new {@link ContinueRecord} (regardless
+ * of how much space is still available in the current record).
+ */
+ public void writeContinue() {
+ _ulrOutput.terminate();
+ _totalPreviousRecordsSize += _ulrOutput.getTotalSize();
+ _ulrOutput = new UnknownLengthRecordOutput(_out, ContinueRecord.sid);
+ }
+ public void writeContinueIfRequired(int requiredContinuousSize) {
+ if (_ulrOutput.getAvailableSpace() < requiredContinuousSize) {
+ writeContinue();
+ }
+ }
+
+ /**
+ * Writes the 'optionFlags' byte and encoded character data of a unicode string. This includes:
+ * <ul>
+ * <li>byte optionFlags</li>
+ * <li>encoded character data (in "ISO-8859-1" or "UTF-16LE" encoding)</li>
+ * </ul>
+ *
+ * Notes:
+ * <ul>
+ * <li>The value of the 'is16bitEncoded' flag is determined by the actual character data
+ * of <tt>text</tt></li>
+ * <li>The string options flag is never separated (by a {@link ContinueRecord}) from the
+ * first chunk of character data it refers to.</li>
+ * <li>The 'ushort length' field is assumed to have been explicitly written earlier. Hence,
+ * there may be an intervening {@link ContinueRecord}</li>
+ * </ul>
+ */
+ public void writeStringData(String text) {
+ boolean is16bitEncoded = StringUtil.hasMultibyte(text);
+ // calculate total size of the header and first encoded char
+ int keepTogetherSize = 1 + 1; // ushort len, at least one character byte
+ int optionFlags = 0x00;
+ if (is16bitEncoded) {
+ optionFlags |= 0x01;
+ keepTogetherSize += 1; // one extra byte for first char
+ }
+ writeContinueIfRequired(keepTogetherSize);
+ writeByte(optionFlags);
+ writeCharacterData(text, is16bitEncoded);
+ }
+ /**
+ * Writes a unicode string complete with header and character data. This includes:
+ * <ul>
+ * <li>ushort length</li>
+ * <li>byte optionFlags</li>
+ * <li>ushort numberOfRichTextRuns (optional)</li>
+ * <li>ushort extendedDataSize (optional)</li>
+ * <li>encoded character data (in "ISO-8859-1" or "UTF-16LE" encoding)</li>
+ * </ul>
+ *
+ * The following bits of the 'optionFlags' byte will be set as appropriate:
+ * <table border='1'>
+ * <tr><th>Mask</th><th>Description</th></tr>
+ * <tr><td>0x01</td><td>is16bitEncoded</td></tr>
+ * <tr><td>0x04</td><td>hasExtendedData</td></tr>
+ * <tr><td>0x08</td><td>isRichText</td></tr>
+ * </table>
+ * Notes:
+ * <ul>
+ * <li>The value of the 'is16bitEncoded' flag is determined by the actual character data
+ * of <tt>text</tt></li>
+ * <li>The string header fields are never separated (by a {@link ContinueRecord}) from the
+ * first chunk of character data (i.e. the first character is always encoded in the same
+ * record as the string header).</li>
+ * </ul>
+ */
+ public void writeString(String text, int numberOfRichTextRuns, int extendedDataSize) {
+ boolean is16bitEncoded = StringUtil.hasMultibyte(text);
+ // calculate total size of the header and first encoded char
+ int keepTogetherSize = 2 + 1 + 1; // ushort len, byte optionFlags, at least one character byte
+ int optionFlags = 0x00;
+ if (is16bitEncoded) {
+ optionFlags |= 0x01;
+ keepTogetherSize += 1; // one extra byte for first char
+ }
+ if (numberOfRichTextRuns > 0) {
+ optionFlags |= 0x08;
+ keepTogetherSize += 2;
+ }
+ if (extendedDataSize > 0) {
+ optionFlags |= 0x04;
+ keepTogetherSize += 4;
+ }
+ writeContinueIfRequired(keepTogetherSize);
+ writeShort(text.length());
+ writeByte(optionFlags);
+ if (numberOfRichTextRuns > 0) {
+ writeShort(numberOfRichTextRuns);
+ }
+ if (extendedDataSize > 0) {
+ writeInt(extendedDataSize);
+ }
+ writeCharacterData(text, is16bitEncoded);
+ }
+
+
+ private void writeCharacterData(String text, boolean is16bitEncoded) {
+ int nChars = text.length();
+ int i=0;
+ if (is16bitEncoded) {
+ while(true) {
+ int nWritableChars = Math.min(nChars-i, _ulrOutput.getAvailableSpace() / 2);
+ for ( ; nWritableChars > 0; nWritableChars--) {
+ _ulrOutput.writeShort(text.charAt(i++));
+ }
+ if (i >= nChars) {
+ break;
+ }
+ writeContinue();
+ writeByte(0x01);
+ }
+ } else {
+ while(true) {
+ int nWritableChars = Math.min(nChars-i, _ulrOutput.getAvailableSpace() / 1);
+ for ( ; nWritableChars > 0; nWritableChars--) {
+ _ulrOutput.writeByte(text.charAt(i++));
+ }
+ if (i >= nChars) {
+ break;
+ }
+ writeContinue();
+ writeByte(0x00);
+ }
+ }
+ }
+
+ public void write(byte[] b) {
+ writeContinueIfRequired(b.length);
+ _ulrOutput.write(b);
+ }
+ public void write(byte[] b, int offset, int len) {
+ writeContinueIfRequired(len);
+ _ulrOutput.write(b, offset, len);
+ }
+ public void writeByte(int v) {
+ writeContinueIfRequired(1);
+ _ulrOutput.writeByte(v);
+ }
+ public void writeDouble(double v) {
+ writeContinueIfRequired(8);
+ _ulrOutput.writeDouble(v);
+ }
+ public void writeInt(int v) {
+ writeContinueIfRequired(4);
+ _ulrOutput.writeInt(v);
+ }
+ public void writeLong(long v) {
+ writeContinueIfRequired(8);
+ _ulrOutput.writeLong(v);
+ }
+ public void writeShort(int v) {
+ writeContinueIfRequired(2);
+ _ulrOutput.writeShort(v);
+ }
+
+ /**
+ * Allows optimised usage of {@link ContinuableRecordOutput} for sizing purposes only.
+ */
+ private static final LittleEndianOutput NOPOutput = new DelayableLittleEndianOutput() {
+
+ public LittleEndianOutput createDelayedOutput(int size) {
+ return this;
+ }
+ public void write(byte[] b) {
+ // does nothing
+ }
+ public void write(byte[] b, int offset, int len) {
+ // does nothing
+ }
+ public void writeByte(int v) {
+ // does nothing
+ }
+ public void writeDouble(double v) {
+ // does nothing
+ }
+ public void writeInt(int v) {
+ // does nothing
+ }
+ public void writeLong(long v) {
+ // does nothing
+ }
+ public void writeShort(int v) {
+ // does nothing
+ }
+ };
+}
Modified: poi/trunk/src/java/org/apache/poi/hssf/record/cont/UnknownLengthRecordOutput.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/cont/UnknownLengthRecordOutput.java?rev=776377&r1=776376&r2=776377&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/cont/UnknownLengthRecordOutput.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/cont/UnknownLengthRecordOutput.java Tue May 19 16:29:51 2009
@@ -1,114 +1,114 @@
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.record.cont;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.util.DelayableLittleEndianOutput;
-import org.apache.poi.util.LittleEndianByteArrayOutputStream;
-import org.apache.poi.util.LittleEndianOutput;
-/**
- * Allows the writing of BIFF records when the 'ushort size' header field is not known in advance.
- * When the client is finished writing data, it calls {@link #terminate()}, at which point this
- * class updates the 'ushort size' with its final value.
- *
- * @author Josh Micich
- */
-final class UnknownLengthRecordOutput implements LittleEndianOutput {
- private static final int MAX_DATA_SIZE = RecordInputStream.MAX_RECORD_DATA_SIZE;
-
- private final LittleEndianOutput _originalOut;
- /** for writing the 'ushort size' field once its value is known */
- private final LittleEndianOutput _dataSizeOutput;
- private final byte[] _byteBuffer;
- private LittleEndianOutput _out;
- private int _size;
-
- public UnknownLengthRecordOutput(LittleEndianOutput out, int sid) {
- _originalOut = out;
- out.writeShort(sid);
- if (out instanceof DelayableLittleEndianOutput) {
- // optimisation
- DelayableLittleEndianOutput dleo = (DelayableLittleEndianOutput) out;
- _dataSizeOutput = dleo.createDelayedOutput(2);
- _byteBuffer = null;
- _out = out;
- } else {
- // otherwise temporarily write all subsequent data to a buffer
- _dataSizeOutput = out;
- _byteBuffer = new byte[RecordInputStream.MAX_RECORD_DATA_SIZE];
- _out = new LittleEndianByteArrayOutputStream(_byteBuffer, 0);
- }
- }
- /**
- * includes 4 byte header
- */
- public int getTotalSize() {
- return 4 + _size;
- }
- public int getAvailableSpace() {
- if (_out == null) {
- throw new IllegalStateException("Record already terminated");
- }
- return MAX_DATA_SIZE - _size;
- }
- /**
- * Finishes writing the current record and updates 'ushort size' field.<br/>
- * After this method is called, only {@link #getTotalSize()} may be called.
- */
- public void terminate() {
- if (_out == null) {
- throw new IllegalStateException("Record already terminated");
- }
- _dataSizeOutput.writeShort(_size);
- if (_byteBuffer != null) {
- _originalOut.write(_byteBuffer, 0, _size);
- _out = null;
- return;
- }
- _out = null;
- }
-
- public void write(byte[] b) {
- _out.write(b);
- _size += b.length;
- }
- public void write(byte[] b, int offset, int len) {
- _out.write(b, offset, len);
- _size += len;
- }
- public void writeByte(int v) {
- _out.writeByte(v);
- _size += 1;
- }
- public void writeDouble(double v) {
- _out.writeDouble(v);
- _size += 8;
- }
- public void writeInt(int v) {
- _out.writeInt(v);
- _size += 4;
- }
- public void writeLong(long v) {
- _out.writeLong(v);
- _size += 8;
- }
- public void writeShort(int v) {
- _out.writeShort(v);
- _size += 2;
- }
-}
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.cont;
+
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.DelayableLittleEndianOutput;
+import org.apache.poi.util.LittleEndianByteArrayOutputStream;
+import org.apache.poi.util.LittleEndianOutput;
+/**
+ * Allows the writing of BIFF records when the 'ushort size' header field is not known in advance.
+ * When the client is finished writing data, it calls {@link #terminate()}, at which point this
+ * class updates the 'ushort size' with its final value.
+ *
+ * @author Josh Micich
+ */
+final class UnknownLengthRecordOutput implements LittleEndianOutput {
+ private static final int MAX_DATA_SIZE = RecordInputStream.MAX_RECORD_DATA_SIZE;
+
+ private final LittleEndianOutput _originalOut;
+ /** for writing the 'ushort size' field once its value is known */
+ private final LittleEndianOutput _dataSizeOutput;
+ private final byte[] _byteBuffer;
+ private LittleEndianOutput _out;
+ private int _size;
+
+ public UnknownLengthRecordOutput(LittleEndianOutput out, int sid) {
+ _originalOut = out;
+ out.writeShort(sid);
+ if (out instanceof DelayableLittleEndianOutput) {
+ // optimisation
+ DelayableLittleEndianOutput dleo = (DelayableLittleEndianOutput) out;
+ _dataSizeOutput = dleo.createDelayedOutput(2);
+ _byteBuffer = null;
+ _out = out;
+ } else {
+ // otherwise temporarily write all subsequent data to a buffer
+ _dataSizeOutput = out;
+ _byteBuffer = new byte[RecordInputStream.MAX_RECORD_DATA_SIZE];
+ _out = new LittleEndianByteArrayOutputStream(_byteBuffer, 0);
+ }
+ }
+ /**
+ * includes 4 byte header
+ */
+ public int getTotalSize() {
+ return 4 + _size;
+ }
+ public int getAvailableSpace() {
+ if (_out == null) {
+ throw new IllegalStateException("Record already terminated");
+ }
+ return MAX_DATA_SIZE - _size;
+ }
+ /**
+ * Finishes writing the current record and updates 'ushort size' field.<br/>
+ * After this method is called, only {@link #getTotalSize()} may be called.
+ */
+ public void terminate() {
+ if (_out == null) {
+ throw new IllegalStateException("Record already terminated");
+ }
+ _dataSizeOutput.writeShort(_size);
+ if (_byteBuffer != null) {
+ _originalOut.write(_byteBuffer, 0, _size);
+ _out = null;
+ return;
+ }
+ _out = null;
+ }
+
+ public void write(byte[] b) {
+ _out.write(b);
+ _size += b.length;
+ }
+ public void write(byte[] b, int offset, int len) {
+ _out.write(b, offset, len);
+ _size += len;
+ }
+ public void writeByte(int v) {
+ _out.writeByte(v);
+ _size += 1;
+ }
+ public void writeDouble(double v) {
+ _out.writeDouble(v);
+ _size += 8;
+ }
+ public void writeInt(int v) {
+ _out.writeInt(v);
+ _size += 4;
+ }
+ public void writeLong(long v) {
+ _out.writeLong(v);
+ _size += 8;
+ }
+ public void writeShort(int v) {
+ _out.writeShort(v);
+ _size += 2;
+ }
+}
Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java?rev=776377&r1=776376&r2=776377&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java Tue May 19 16:29:51 2009
@@ -1,64 +1,64 @@
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.record.formula;
-
-import org.apache.poi.ss.util.AreaReference;
-import org.apache.poi.util.LittleEndianInput;
-import org.apache.poi.util.LittleEndianOutput;
-
-/**
- * Common superclass of 2-D area refs
- */
-public abstract class Area2DPtgBase extends AreaPtgBase {
- private final static int SIZE = 9;
-
- protected Area2DPtgBase(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
- super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
- }
- protected Area2DPtgBase(AreaReference ar) {
- super(ar);
- }
-
- protected Area2DPtgBase(LittleEndianInput in) {
- readCoordinates(in);
- }
-
- protected abstract byte getSid();
-
- public final void write(LittleEndianOutput out) {
- out.writeByte(getSid() + getPtgClass());
- writeCoordinates(out);
- }
-
- public final int getSize() {
- return SIZE;
- }
-
- public final String toFormulaString() {
- return formatReferenceAsString();
- }
-
- public final String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append(getClass().getName());
- sb.append(" [");
- sb.append(formatReferenceAsString());
- sb.append("]");
- return sb.toString();
- }
-}
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula;
+
+import org.apache.poi.ss.util.AreaReference;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Common superclass of 2-D area refs
+ */
+public abstract class Area2DPtgBase extends AreaPtgBase {
+ private final static int SIZE = 9;
+
+ protected Area2DPtgBase(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
+ super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
+ }
+ protected Area2DPtgBase(AreaReference ar) {
+ super(ar);
+ }
+
+ protected Area2DPtgBase(LittleEndianInput in) {
+ readCoordinates(in);
+ }
+
+ protected abstract byte getSid();
+
+ public final void write(LittleEndianOutput out) {
+ out.writeByte(getSid() + getPtgClass());
+ writeCoordinates(out);
+ }
+
+ public final int getSize() {
+ return SIZE;
+ }
+
+ public final String toFormulaString() {
+ return formatReferenceAsString();
+ }
+
+ public final String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append(" [");
+ sb.append(formatReferenceAsString());
+ sb.append("]");
+ return sb.toString();
+ }
+}
Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/RefPtg.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/RefPtg.java?rev=776377&r1=776376&r2=776377&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/RefPtg.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/RefPtg.java Tue May 19 16:29:51 2009
@@ -1,54 +1,54 @@
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.record.formula;
-
-import org.apache.poi.ss.util.CellReference;
-import org.apache.poi.util.LittleEndianInput;
-
-/**
- * ReferencePtg - handles references (such as A1, A2, IA4)
- * @author Andrew C. Oliver (acoliver@apache.org)
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-public final class RefPtg extends Ref2DPtgBase {
- public final static byte sid = 0x24;
-
- /**
- * Takes in a String representation of a cell reference and fills out the
- * numeric fields.
- */
- public RefPtg(String cellref) {
- super(new CellReference(cellref));
- }
-
- public RefPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
- super(row, column, isRowRelative, isColumnRelative);
- }
-
- public RefPtg(LittleEndianInput in) {
- super(in);
- }
-
- public RefPtg(CellReference cr) {
- super(cr);
- }
-
- protected byte getSid() {
- return sid;
- }
-}
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula;
+
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.util.LittleEndianInput;
+
+/**
+ * ReferencePtg - handles references (such as A1, A2, IA4)
+ * @author Andrew C. Oliver (acoliver@apache.org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class RefPtg extends Ref2DPtgBase {
+ public final static byte sid = 0x24;
+
+ /**
+ * Takes in a String representation of a cell reference and fills out the
+ * numeric fields.
+ */
+ public RefPtg(String cellref) {
+ super(new CellReference(cellref));
+ }
+
+ public RefPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
+ super(row, column, isRowRelative, isColumnRelative);
+ }
+
+ public RefPtg(LittleEndianInput in) {
+ super(in);
+ }
+
+ public RefPtg(CellReference cr) {
+ super(cr);
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+}
Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/ScalarConstantPtg.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/ScalarConstantPtg.java?rev=776377&r1=776376&r2=776377&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/ScalarConstantPtg.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/ScalarConstantPtg.java Tue May 19 16:29:51 2009
@@ -1,40 +1,40 @@
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.record.formula;
-
-
-/**
- * @author Josh Micich
- */
-abstract class ScalarConstantPtg extends Ptg {
- public boolean isBaseToken() {
- return true;
- }
-
- public final byte getDefaultOperandClass() {
- return Ptg.CLASS_VALUE;
- }
-
- public final String toString() {
- StringBuffer sb = new StringBuffer(64);
- sb.append(getClass().getName()).append(" [");
- sb.append(toFormulaString());
- sb.append("]");
- return sb.toString();
- }
-}
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula;
+
+
+/**
+ * @author Josh Micich
+ */
+abstract class ScalarConstantPtg extends Ptg {
+ public boolean isBaseToken() {
+ return true;
+ }
+
+ public final byte getDefaultOperandClass() {
+ return Ptg.CLASS_VALUE;
+ }
+
+ public final String toString() {
+ StringBuffer sb = new StringBuffer(64);
+ sb.append(getClass().getName()).append(" [");
+ sb.append(toFormulaString());
+ sb.append("]");
+ return sb.toString();
+ }
+}
Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/RefEvalBase.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/RefEvalBase.java?rev=776377&r1=776376&r2=776377&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/RefEvalBase.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/RefEvalBase.java Tue May 19 16:29:51 2009
@@ -1,40 +1,40 @@
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.record.formula.eval;
-
-/**
- * Common base class for implementors of {@link RefEval}
- *
- * @author Josh Micich
- */
-public abstract class RefEvalBase implements RefEval {
-
- private final int _rowIndex;
- private final int _columnIndex;
-
- protected RefEvalBase(int rowIndex, int columnIndex) {
- _rowIndex = rowIndex;
- _columnIndex = columnIndex;
- }
- public final int getRow() {
- return _rowIndex;
- }
- public final int getColumn() {
- return _columnIndex;
- }
-}
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula.eval;
+
+/**
+ * Common base class for implementors of {@link RefEval}
+ *
+ * @author Josh Micich
+ */
+public abstract class RefEvalBase implements RefEval {
+
+ private final int _rowIndex;
+ private final int _columnIndex;
+
+ protected RefEvalBase(int rowIndex, int columnIndex) {
+ _rowIndex = rowIndex;
+ _columnIndex = columnIndex;
+ }
+ public final int getRow() {
+ return _rowIndex;
+ }
+ public final int getColumn() {
+ return _columnIndex;
+ }
+}
Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java?rev=776377&r1=776376&r2=776377&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java Tue May 19 16:29:51 2009
@@ -1,162 +1,162 @@
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.usermodel;
-
-import org.apache.poi.hssf.model.HSSFFormulaParser;
-import org.apache.poi.hssf.model.Workbook;
-import org.apache.poi.hssf.record.NameRecord;
-import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
-import org.apache.poi.hssf.record.formula.NamePtg;
-import org.apache.poi.hssf.record.formula.NameXPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.ss.formula.*;
-import org.apache.poi.ss.SpreadsheetVersion;
-
-/**
- * Internal POI use only
- *
- * @author Josh Micich
- */
-public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, EvaluationWorkbook, FormulaParsingWorkbook {
-
- private final HSSFWorkbook _uBook;
- private final Workbook _iBook;
-
- public static HSSFEvaluationWorkbook create(HSSFWorkbook book) {
- if (book == null) {
- return null;
- }
- return new HSSFEvaluationWorkbook(book);
- }
-
- private HSSFEvaluationWorkbook(HSSFWorkbook book) {
- _uBook = book;
- _iBook = book.getWorkbook();
- }
-
- public int getExternalSheetIndex(String sheetName) {
- int sheetIndex = _uBook.getSheetIndex(sheetName);
- return _iBook.checkExternSheet(sheetIndex);
- }
- public int getExternalSheetIndex(String workbookName, String sheetName) {
- return _iBook.getExternalSheetIndex(workbookName, sheetName);
- }
-
- public NameXPtg getNameXPtg(String name) {
- return _iBook.getNameXPtg(name);
- }
-
- /**
- * Lookup a named range by its name.
- *
- * @param name the name to search
- * @param sheetIndex the 0-based index of the sheet this formula belongs to.
- * The sheet index is required to resolve sheet-level names. <code>-1</code> means workbook-global names
- */
- public EvaluationName getName(String name, int sheetIndex) {
- for(int i=0; i < _iBook.getNumNames(); i++) {
- NameRecord nr = _iBook.getNameRecord(i);
- if (nr.getSheetNumber() == sheetIndex+1 && name.equalsIgnoreCase(nr.getNameText())) {
- return new Name(nr, i);
- }
- }
- return sheetIndex == -1 ? null : getName(name, -1);
- }
-
- public int getSheetIndex(EvaluationSheet evalSheet) {
- HSSFSheet sheet = ((HSSFEvaluationSheet)evalSheet).getHSSFSheet();
- return _uBook.getSheetIndex(sheet);
- }
- public int getSheetIndex(String sheetName) {
- return _uBook.getSheetIndex(sheetName);
- }
-
- public String getSheetName(int sheetIndex) {
- return _uBook.getSheetName(sheetIndex);
- }
-
- public EvaluationSheet getSheet(int sheetIndex) {
- return new HSSFEvaluationSheet(_uBook.getSheetAt(sheetIndex));
- }
- public int convertFromExternSheetIndex(int externSheetIndex) {
- return _iBook.getSheetIndexFromExternSheetIndex(externSheetIndex);
- }
-
- public ExternalSheet getExternalSheet(int externSheetIndex) {
- return _iBook.getExternalSheet(externSheetIndex);
- }
-
- public String resolveNameXText(NameXPtg n) {
- return _iBook.resolveNameXText(n.getSheetRefIndex(), n.getNameIndex());
- }
-
- public String getSheetNameByExternSheet(int externSheetIndex) {
- return _iBook.findSheetNameFromExternSheet(externSheetIndex);
- }
- public String getNameText(NamePtg namePtg) {
- return _iBook.getNameRecord(namePtg.getIndex()).getNameText();
- }
- public EvaluationName getName(NamePtg namePtg) {
- int ix = namePtg.getIndex();
- return new Name(_iBook.getNameRecord(ix), ix);
- }
- public Ptg[] getFormulaTokens(EvaluationCell evalCell) {
- HSSFCell cell = ((HSSFEvaluationCell)evalCell).getHSSFCell();
- if (false) {
- // re-parsing the formula text also works, but is a waste of time
- // It is useful from time to time to run all unit tests with this code
- // to make sure that all formulas POI can evaluate can also be parsed.
- return HSSFFormulaParser.parse(cell.getCellFormula(), _uBook, FormulaType.CELL, _uBook.getSheetIndex(cell.getSheet()));
- }
- FormulaRecordAggregate fra = (FormulaRecordAggregate) cell.getCellValueRecord();
- return fra.getFormulaTokens();
- }
-
- private static final class Name implements EvaluationName {
-
- private final NameRecord _nameRecord;
- private final int _index;
-
- public Name(NameRecord nameRecord, int index) {
- _nameRecord = nameRecord;
- _index = index;
- }
- public Ptg[] getNameDefinition() {
- return _nameRecord.getNameDefinition();
- }
- public String getNameText() {
- return _nameRecord.getNameText();
- }
- public boolean hasFormula() {
- return _nameRecord.hasFormula();
- }
- public boolean isFunctionName() {
- return _nameRecord.isFunctionName();
- }
- public boolean isRange() {
- return _nameRecord.hasFormula(); // TODO - is this right?
- }
- public NamePtg createPtg() {
- return new NamePtg(_index);
- }
- }
-
- public SpreadsheetVersion getSpreadsheetVersion(){
- return SpreadsheetVersion.EXCEL97;
- }
-}
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.usermodel;
+
+import org.apache.poi.hssf.model.HSSFFormulaParser;
+import org.apache.poi.hssf.model.Workbook;
+import org.apache.poi.hssf.record.NameRecord;
+import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
+import org.apache.poi.hssf.record.formula.NamePtg;
+import org.apache.poi.hssf.record.formula.NameXPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.ss.formula.*;
+import org.apache.poi.ss.SpreadsheetVersion;
+
+/**
+ * Internal POI use only
+ *
+ * @author Josh Micich
+ */
+public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, EvaluationWorkbook, FormulaParsingWorkbook {
+
+ private final HSSFWorkbook _uBook;
+ private final Workbook _iBook;
+
+ public static HSSFEvaluationWorkbook create(HSSFWorkbook book) {
+ if (book == null) {
+ return null;
+ }
+ return new HSSFEvaluationWorkbook(book);
+ }
+
+ private HSSFEvaluationWorkbook(HSSFWorkbook book) {
+ _uBook = book;
+ _iBook = book.getWorkbook();
+ }
+
+ public int getExternalSheetIndex(String sheetName) {
+ int sheetIndex = _uBook.getSheetIndex(sheetName);
+ return _iBook.checkExternSheet(sheetIndex);
+ }
+ public int getExternalSheetIndex(String workbookName, String sheetName) {
+ return _iBook.getExternalSheetIndex(workbookName, sheetName);
+ }
+
+ public NameXPtg getNameXPtg(String name) {
+ return _iBook.getNameXPtg(name);
+ }
+
+ /**
+ * Lookup a named range by its name.
+ *
+ * @param name the name to search
+ * @param sheetIndex the 0-based index of the sheet this formula belongs to.
+ * The sheet index is required to resolve sheet-level names. <code>-1</code> means workbook-global names
+ */
+ public EvaluationName getName(String name, int sheetIndex) {
+ for(int i=0; i < _iBook.getNumNames(); i++) {
+ NameRecord nr = _iBook.getNameRecord(i);
+ if (nr.getSheetNumber() == sheetIndex+1 && name.equalsIgnoreCase(nr.getNameText())) {
+ return new Name(nr, i);
+ }
+ }
+ return sheetIndex == -1 ? null : getName(name, -1);
+ }
+
+ public int getSheetIndex(EvaluationSheet evalSheet) {
+ HSSFSheet sheet = ((HSSFEvaluationSheet)evalSheet).getHSSFSheet();
+ return _uBook.getSheetIndex(sheet);
+ }
+ public int getSheetIndex(String sheetName) {
+ return _uBook.getSheetIndex(sheetName);
+ }
+
+ public String getSheetName(int sheetIndex) {
+ return _uBook.getSheetName(sheetIndex);
+ }
+
+ public EvaluationSheet getSheet(int sheetIndex) {
+ return new HSSFEvaluationSheet(_uBook.getSheetAt(sheetIndex));
+ }
+ public int convertFromExternSheetIndex(int externSheetIndex) {
+ return _iBook.getSheetIndexFromExternSheetIndex(externSheetIndex);
+ }
+
+ public ExternalSheet getExternalSheet(int externSheetIndex) {
+ return _iBook.getExternalSheet(externSheetIndex);
+ }
+
+ public String resolveNameXText(NameXPtg n) {
+ return _iBook.resolveNameXText(n.getSheetRefIndex(), n.getNameIndex());
+ }
+
+ public String getSheetNameByExternSheet(int externSheetIndex) {
+ return _iBook.findSheetNameFromExternSheet(externSheetIndex);
+ }
+ public String getNameText(NamePtg namePtg) {
+ return _iBook.getNameRecord(namePtg.getIndex()).getNameText();
+ }
+ public EvaluationName getName(NamePtg namePtg) {
+ int ix = namePtg.getIndex();
+ return new Name(_iBook.getNameRecord(ix), ix);
+ }
+ public Ptg[] getFormulaTokens(EvaluationCell evalCell) {
+ HSSFCell cell = ((HSSFEvaluationCell)evalCell).getHSSFCell();
+ if (false) {
+ // re-parsing the formula text also works, but is a waste of time
+ // It is useful from time to time to run all unit tests with this code
+ // to make sure that all formulas POI can evaluate can also be parsed.
+ return HSSFFormulaParser.parse(cell.getCellFormula(), _uBook, FormulaType.CELL, _uBook.getSheetIndex(cell.getSheet()));
+ }
+ FormulaRecordAggregate fra = (FormulaRecordAggregate) cell.getCellValueRecord();
+ return fra.getFormulaTokens();
+ }
+
+ private static final class Name implements EvaluationName {
+
+ private final NameRecord _nameRecord;
+ private final int _index;
+
+ public Name(NameRecord nameRecord, int index) {
+ _nameRecord = nameRecord;
+ _index = index;
+ }
+ public Ptg[] getNameDefinition() {
+ return _nameRecord.getNameDefinition();
+ }
+ public String getNameText() {
+ return _nameRecord.getNameText();
+ }
+ public boolean hasFormula() {
+ return _nameRecord.hasFormula();
+ }
+ public boolean isFunctionName() {
+ return _nameRecord.isFunctionName();
+ }
+ public boolean isRange() {
+ return _nameRecord.hasFormula(); // TODO - is this right?
+ }
+ public NamePtg createPtg() {
+ return new NamePtg(_index);
+ }
+ }
+
+ public SpreadsheetVersion getSpreadsheetVersion(){
+ return SpreadsheetVersion.EXCEL97;
+ }
+}
Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java?rev=776377&r1=776376&r2=776377&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java Tue May 19 16:29:51 2009
@@ -1,315 +1,316 @@
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.usermodel;
-
-import java.util.Iterator;
-
-import org.apache.poi.hssf.record.formula.eval.BoolEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.StringEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-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.usermodel.Cell;
-import org.apache.poi.ss.usermodel.CellValue;
-import org.apache.poi.ss.usermodel.FormulaEvaluator;
-
-/**
- * Evaluates formula cells.<p/>
- *
- * For performance reasons, this class keeps a cache of all previously calculated intermediate
- * cell values. Be sure to call {@link #clearAllCachedResultValues()} if any workbook cells are changed between
- * calls to evaluate~ methods on this class.
- *
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- * @author Josh Micich
- */
-public class HSSFFormulaEvaluator implements FormulaEvaluator {
-
- private WorkbookEvaluator _bookEvaluator;
-
- /**
- * @deprecated (Sep 2008) HSSFSheet parameter is ignored
- */
- public HSSFFormulaEvaluator(HSSFSheet sheet, HSSFWorkbook workbook) {
- this(workbook);
- if (false) {
- sheet.toString(); // suppress unused parameter compiler warning
- }
- }
- public HSSFFormulaEvaluator(HSSFWorkbook workbook) {
- this(workbook, null);
- }
- /**
- * @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) {
- _bookEvaluator = new WorkbookEvaluator(HSSFEvaluationWorkbook.create(workbook), stabilityClassifier);
- }
-
- /**
- * 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);
- }
-
- /**
- * Does nothing
- * @deprecated (Aug 2008) - not needed, since the current row can be derived from the cell
- */
- public void setCurrentRow(HSSFRow row) {
- // do nothing
- if (false) {
- row.getClass(); // suppress unused parameter compiler warning
- }
- }
-
- /**
- * 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
- */
- 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));
- }
- /**
- * 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));
- }
- public void notifyDeleteCell(Cell 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
- */
- public void notifySetFormula(Cell cell) {
- _bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell((HSSFCell)cell));
- }
-
- /**
- * 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
- */
- public CellValue evaluate(Cell cell) {
- if (cell == null) {
- return null;
- }
-
- switch (cell.getCellType()) {
- case HSSFCell.CELL_TYPE_BOOLEAN:
- return CellValue.valueOf(cell.getBooleanCellValue());
- case HSSFCell.CELL_TYPE_ERROR:
- return CellValue.getError(cell.getErrorCellValue());
- case HSSFCell.CELL_TYPE_FORMULA:
- return evaluateFormulaCellValue(cell);
- case HSSFCell.CELL_TYPE_NUMERIC:
- return new CellValue(cell.getNumericCellValue());
- case HSSFCell.CELL_TYPE_STRING:
- return new CellValue(cell.getRichStringCellValue().getString());
- case HSSFCell.CELL_TYPE_BLANK:
- return null;
- }
- throw new IllegalStateException("Bad cell type (" + cell.getCellType() + ")");
- }
-
-
- /**
- * 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>
- */
- public int evaluateFormulaCell(Cell cell) {
- if (cell == null || cell.getCellType() != HSSFCell.CELL_TYPE_FORMULA) {
- return -1;
- }
- 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 #evaluateFormulaCell(Cell)}}
- */
- public HSSFCell evaluateInCell(Cell cell) {
- if (cell == null) {
- return null;
- }
- HSSFCell result = (HSSFCell) cell;
- if (cell.getCellType() == HSSFCell.CELL_TYPE_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) {
- int cellType = cv.getCellType();
- switch (cellType) {
- case HSSFCell.CELL_TYPE_BOOLEAN:
- case HSSFCell.CELL_TYPE_ERROR:
- case HSSFCell.CELL_TYPE_NUMERIC:
- case HSSFCell.CELL_TYPE_STRING:
- cell.setCellType(cellType);
- return;
- case HSSFCell.CELL_TYPE_BLANK:
- // never happens - blanks eventually get translated to zero
- case HSSFCell.CELL_TYPE_FORMULA:
- // this will never happen, we have already evaluated the formula
- }
- throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
- }
-
- private static void setCellValue(Cell cell, CellValue cv) {
- int cellType = cv.getCellType();
- switch (cellType) {
- case HSSFCell.CELL_TYPE_BOOLEAN:
- cell.setCellValue(cv.getBooleanValue());
- break;
- case HSSFCell.CELL_TYPE_ERROR:
- cell.setCellErrorValue(cv.getErrorValue());
- break;
- case HSSFCell.CELL_TYPE_NUMERIC:
- cell.setCellValue(cv.getNumberValue());
- break;
- case HSSFCell.CELL_TYPE_STRING:
- cell.setCellValue(new HSSFRichTextString(cv.getStringValue()));
- break;
- case HSSFCell.CELL_TYPE_BLANK:
- // never happens - blanks eventually get translated to zero
- case HSSFCell.CELL_TYPE_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) {
- HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb);
- for(int i=0; i<wb.getNumberOfSheets(); i++) {
- HSSFSheet sheet = wb.getSheetAt(i);
-
- for (Iterator rit = sheet.rowIterator(); rit.hasNext();) {
- HSSFRow r = (HSSFRow)rit.next();
-
- for (Iterator cit = r.cellIterator(); cit.hasNext();) {
- HSSFCell c = (HSSFCell)cit.next();
- if (c.getCellType() == HSSFCell.CELL_TYPE_FORMULA)
- evaluator.evaluateFormulaCell(c);
- }
- }
- }
- }
-
- /**
- * Returns a CellValue wrapper around the supplied ValueEval instance.
- * @param eval
- */
- private CellValue evaluateFormulaCellValue(Cell cell) {
- ValueEval eval = _bookEvaluator.evaluate(new HSSFEvaluationCell((HSSFCell)cell));
- if (eval instanceof NumberEval) {
- NumberEval ne = (NumberEval) eval;
- return new CellValue(ne.getNumberValue());
- }
- if (eval instanceof BoolEval) {
- BoolEval be = (BoolEval) eval;
- return CellValue.valueOf(be.getBooleanValue());
- }
- if (eval instanceof StringEval) {
- StringEval ne = (StringEval) 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() + ")");
- }
-}
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.usermodel;
+
+import java.util.Iterator;
+
+import org.apache.poi.hssf.record.formula.eval.BoolEval;
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.StringEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+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.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellValue;
+import org.apache.poi.ss.usermodel.FormulaEvaluator;
+import org.apache.poi.ss.usermodel.Row;
+
+/**
+ * Evaluates formula cells.<p/>
+ *
+ * For performance reasons, this class keeps a cache of all previously calculated intermediate
+ * cell values. Be sure to call {@link #clearAllCachedResultValues()} if any workbook cells are changed between
+ * calls to evaluate~ methods on this class.
+ *
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ * @author Josh Micich
+ */
+public class HSSFFormulaEvaluator implements FormulaEvaluator {
+
+ private WorkbookEvaluator _bookEvaluator;
+
+ /**
+ * @deprecated (Sep 2008) HSSFSheet parameter is ignored
+ */
+ public HSSFFormulaEvaluator(HSSFSheet sheet, HSSFWorkbook workbook) {
+ this(workbook);
+ if (false) {
+ sheet.toString(); // suppress unused parameter compiler warning
+ }
+ }
+ public HSSFFormulaEvaluator(HSSFWorkbook workbook) {
+ this(workbook, null);
+ }
+ /**
+ * @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) {
+ _bookEvaluator = new WorkbookEvaluator(HSSFEvaluationWorkbook.create(workbook), stabilityClassifier);
+ }
+
+ /**
+ * 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);
+ }
+
+ /**
+ * Does nothing
+ * @deprecated (Aug 2008) - not needed, since the current row can be derived from the cell
+ */
+ public void setCurrentRow(HSSFRow row) {
+ // do nothing
+ if (false) {
+ row.getClass(); // suppress unused parameter compiler warning
+ }
+ }
+
+ /**
+ * 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
+ */
+ 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));
+ }
+ /**
+ * 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));
+ }
+ public void notifyDeleteCell(Cell 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
+ */
+ public void notifySetFormula(Cell cell) {
+ _bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell((HSSFCell)cell));
+ }
+
+ /**
+ * 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
+ */
+ public CellValue evaluate(Cell cell) {
+ if (cell == null) {
+ return null;
+ }
+
+ switch (cell.getCellType()) {
+ case HSSFCell.CELL_TYPE_BOOLEAN:
+ return CellValue.valueOf(cell.getBooleanCellValue());
+ case HSSFCell.CELL_TYPE_ERROR:
+ return CellValue.getError(cell.getErrorCellValue());
+ case HSSFCell.CELL_TYPE_FORMULA:
+ return evaluateFormulaCellValue(cell);
+ case HSSFCell.CELL_TYPE_NUMERIC:
+ return new CellValue(cell.getNumericCellValue());
+ case HSSFCell.CELL_TYPE_STRING:
+ return new CellValue(cell.getRichStringCellValue().getString());
+ case HSSFCell.CELL_TYPE_BLANK:
+ return null;
+ }
+ throw new IllegalStateException("Bad cell type (" + cell.getCellType() + ")");
+ }
+
+
+ /**
+ * 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>
+ */
+ public int evaluateFormulaCell(Cell cell) {
+ if (cell == null || cell.getCellType() != HSSFCell.CELL_TYPE_FORMULA) {
+ return -1;
+ }
+ 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 #evaluateFormulaCell(Cell)}}
+ */
+ public HSSFCell evaluateInCell(Cell cell) {
+ if (cell == null) {
+ return null;
+ }
+ HSSFCell result = (HSSFCell) cell;
+ if (cell.getCellType() == HSSFCell.CELL_TYPE_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) {
+ int cellType = cv.getCellType();
+ switch (cellType) {
+ case HSSFCell.CELL_TYPE_BOOLEAN:
+ case HSSFCell.CELL_TYPE_ERROR:
+ case HSSFCell.CELL_TYPE_NUMERIC:
+ case HSSFCell.CELL_TYPE_STRING:
+ cell.setCellType(cellType);
+ return;
+ case HSSFCell.CELL_TYPE_BLANK:
+ // never happens - blanks eventually get translated to zero
+ case HSSFCell.CELL_TYPE_FORMULA:
+ // this will never happen, we have already evaluated the formula
+ }
+ throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
+ }
+
+ private static void setCellValue(Cell cell, CellValue cv) {
+ int cellType = cv.getCellType();
+ switch (cellType) {
+ case HSSFCell.CELL_TYPE_BOOLEAN:
+ cell.setCellValue(cv.getBooleanValue());
+ break;
+ case HSSFCell.CELL_TYPE_ERROR:
+ cell.setCellErrorValue(cv.getErrorValue());
+ break;
+ case HSSFCell.CELL_TYPE_NUMERIC:
+ cell.setCellValue(cv.getNumberValue());
+ break;
+ case HSSFCell.CELL_TYPE_STRING:
+ cell.setCellValue(new HSSFRichTextString(cv.getStringValue()));
+ break;
+ case HSSFCell.CELL_TYPE_BLANK:
+ // never happens - blanks eventually get translated to zero
+ case HSSFCell.CELL_TYPE_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) {
+ HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb);
+ for(int i=0; i<wb.getNumberOfSheets(); i++) {
+ HSSFSheet sheet = wb.getSheetAt(i);
+
+ for (Iterator<Row> rit = sheet.rowIterator(); rit.hasNext();) {
+ Row r = rit.next();
+
+ for (Iterator<Cell> cit = r.cellIterator(); cit.hasNext();) {
+ Cell c = cit.next();
+ if (c.getCellType() == HSSFCell.CELL_TYPE_FORMULA)
+ evaluator.evaluateFormulaCell(c);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns a CellValue wrapper around the supplied ValueEval instance.
+ * @param eval
+ */
+ private CellValue evaluateFormulaCellValue(Cell cell) {
+ ValueEval eval = _bookEvaluator.evaluate(new HSSFEvaluationCell((HSSFCell)cell));
+ if (eval instanceof NumberEval) {
+ NumberEval ne = (NumberEval) eval;
+ return new CellValue(ne.getNumberValue());
+ }
+ if (eval instanceof BoolEval) {
+ BoolEval be = (BoolEval) eval;
+ return CellValue.valueOf(be.getBooleanValue());
+ }
+ if (eval instanceof StringEval) {
+ StringEval ne = (StringEval) 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() + ")");
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org