From: Josh Micich Date: Tue, 19 May 2009 16:29:51 +0000 (+0000) Subject: Changed CRLF to LF in .java base src files. Minor reformatting fixes. X-Git-Tag: REL_3_5_BETA6~22 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=6a7fc37e734c70cc7bbc3a8c30657700cdc88a3b;p=poi.git Changed CRLF to LF in .java base src files. Minor reformatting fixes. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@776377 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/java/org/apache/poi/ddf/EscherPictBlip.java b/src/java/org/apache/poi/ddf/EscherPictBlip.java index 5920d97b98..8ab6d8c5c1 100644 --- a/src/java/org/apache/poi/ddf/EscherPictBlip.java +++ b/src/java/org/apache/poi/ddf/EscherPictBlip.java @@ -1,276 +1,276 @@ -/* -* 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.ddf; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -import java.awt.Dimension; -import java.awt.Rectangle; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.zip.InflaterInputStream; - -/** - * @author Daniel Noll - * @version $Id$ - */ -public class EscherPictBlip - extends EscherBlipRecord -{ - private static final POILogger log = POILogFactory.getLogger(EscherPictBlip.class); - - public static final short RECORD_ID_EMF = (short) 0xF018 + 2; - public static final short RECORD_ID_WMF = (short) 0xF018 + 3; - public static final short RECORD_ID_PICT = (short) 0xF018 + 4; - - private static final int HEADER_SIZE = 8; - - private byte[] field_1_UID; - private int field_2_cb; - private int field_3_rcBounds_x1; - private int field_3_rcBounds_y1; - private int field_3_rcBounds_x2; - private int field_3_rcBounds_y2; - private int field_4_ptSize_w; - private int field_4_ptSize_h; - private int field_5_cbSave; - private byte field_6_fCompression; - private byte field_7_fFilter; - - private byte[] raw_pictureData; - - /** - * This method deserializes the record from a byte array. - * - * @param data The byte array containing the escher record information - * @param offset The starting offset into data. - * @param recordFactory May be null since this is not a container record. - * @return The number of bytes read from the byte array. - */ - public int fillFields( byte[] data, int offset, EscherRecordFactory recordFactory ) - { - int bytesAfterHeader = readHeader( data, offset ); - int pos = offset + HEADER_SIZE; - - field_1_UID = new byte[16]; - System.arraycopy( data, pos, field_1_UID, 0, 16 ); pos += 16; - field_2_cb = LittleEndian.getInt( data, pos ); pos += 4; - field_3_rcBounds_x1 = LittleEndian.getInt( data, pos ); pos += 4; - field_3_rcBounds_y1 = LittleEndian.getInt( data, pos ); pos += 4; - field_3_rcBounds_x2 = LittleEndian.getInt( data, pos ); pos += 4; - field_3_rcBounds_y2 = LittleEndian.getInt( data, pos ); pos += 4; - field_4_ptSize_w = LittleEndian.getInt( data, pos ); pos += 4; - field_4_ptSize_h = LittleEndian.getInt( data, pos ); pos += 4; - field_5_cbSave = LittleEndian.getInt( data, pos ); pos += 4; - field_6_fCompression = data[pos]; pos++; - field_7_fFilter = data[pos]; pos++; - - raw_pictureData = new byte[field_5_cbSave]; - System.arraycopy( data, pos, raw_pictureData, 0, field_5_cbSave ); - - // 0 means DEFLATE compression - // 0xFE means no compression - if (field_6_fCompression == 0) - { - field_pictureData = inflatePictureData(raw_pictureData); - } - else - { - field_pictureData = raw_pictureData; - } - - return bytesAfterHeader + HEADER_SIZE; - } - - /** - * Serializes the record to an existing byte array. - * - * @param offset the offset within the byte array - * @param data the data array to serialize to - * @param listener a listener for begin and end serialization events. This - * is useful because the serialization is - * hierarchical/recursive and sometimes you need to be able - * break into that. - * @return the number of bytes written. - */ - public int serialize( int offset, byte[] data, EscherSerializationListener listener ) - { - listener.beforeRecordSerialize(offset, getRecordId(), this); - - int pos = offset; - LittleEndian.putShort( data, pos, getOptions() ); pos += 2; - LittleEndian.putShort( data, pos, getRecordId() ); pos += 2; - LittleEndian.putInt( data, getRecordSize() - HEADER_SIZE ); pos += 4; - - System.arraycopy( field_1_UID, 0, data, pos, 16 ); pos += 16; - LittleEndian.putInt( data, pos, field_2_cb ); pos += 4; - LittleEndian.putInt( data, pos, field_3_rcBounds_x1 ); pos += 4; - LittleEndian.putInt( data, pos, field_3_rcBounds_y1 ); pos += 4; - LittleEndian.putInt( data, pos, field_3_rcBounds_x2 ); pos += 4; - LittleEndian.putInt( data, pos, field_3_rcBounds_y2 ); pos += 4; - LittleEndian.putInt( data, pos, field_4_ptSize_w ); pos += 4; - LittleEndian.putInt( data, pos, field_4_ptSize_h ); pos += 4; - LittleEndian.putInt( data, pos, field_5_cbSave ); pos += 4; - data[pos] = field_6_fCompression; pos++; - data[pos] = field_7_fFilter; pos++; - - System.arraycopy( raw_pictureData, 0, data, pos, raw_pictureData.length ); - - listener.afterRecordSerialize(offset + getRecordSize(), getRecordId(), getRecordSize(), this); - return HEADER_SIZE + 16 + 1 + raw_pictureData.length; - } - - /** - * Decompresses the provided data, returning the inflated result. - * - * @param data the deflated picture data. - * @return the inflated picture data. - */ - private static byte[] inflatePictureData(byte[] data) - { - try - { - InflaterInputStream in = new InflaterInputStream( - new ByteArrayInputStream( data ) ); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - byte[] buf = new byte[4096]; - int readBytes; - while ((readBytes = in.read(buf)) > 0) - { - out.write(buf, 0, readBytes); - } - return out.toByteArray(); - } - catch ( IOException e ) - { - log.log(POILogger.INFO, "Possibly corrupt compression or non-compressed data", e); - return data; - } - } - - /** - * Returns the number of bytes that are required to serialize this record. - * - * @return Number of bytes - */ - public int getRecordSize() - { - return 8 + 50 + raw_pictureData.length; - } - - public byte[] getUID() - { - return field_1_UID; - } - - public void setUID( byte[] field_1_UID ) - { - this.field_1_UID = field_1_UID; - } - - public int getUncompressedSize() - { - return field_2_cb; - } - - public void setUncompressedSize(int uncompressedSize) - { - field_2_cb = uncompressedSize; - } - - public Rectangle getBounds() - { - return new Rectangle(field_3_rcBounds_x1, - field_3_rcBounds_y1, - field_3_rcBounds_x2 - field_3_rcBounds_x1, - field_3_rcBounds_y2 - field_3_rcBounds_y1); - } - - public void setBounds(Rectangle bounds) - { - field_3_rcBounds_x1 = bounds.x; - field_3_rcBounds_y1 = bounds.y; - field_3_rcBounds_x2 = bounds.x + bounds.width; - field_3_rcBounds_y2 = bounds.y + bounds.height; - } - - public Dimension getSizeEMU() - { - return new Dimension(field_4_ptSize_w, field_4_ptSize_h); - } - - public void setSizeEMU(Dimension sizeEMU) - { - field_4_ptSize_w = sizeEMU.width; - field_4_ptSize_h = sizeEMU.height; - } - - public int getCompressedSize() - { - return field_5_cbSave; - } - - public void setCompressedSize(int compressedSize) - { - field_5_cbSave = compressedSize; - } - - public boolean isCompressed() - { - return (field_6_fCompression == 0); - } - - public void setCompressed(boolean compressed) - { - field_6_fCompression = compressed ? 0 : (byte)0xFE; - } - - // filtering is always 254 according to available docs, so no point giving it a setter method. - - public String toString() - { - String nl = System.getProperty( "line.separator" ); - - String extraData; - ByteArrayOutputStream b = new ByteArrayOutputStream(); - try - { - HexDump.dump( this.field_pictureData, 0, b, 0 ); - extraData = b.toString(); - } - catch ( Exception e ) - { - extraData = e.toString(); - } - return getClass().getName() + ":" + nl + - " RecordId: 0x" + HexDump.toHex( getRecordId() ) + nl + - " Options: 0x" + HexDump.toHex( getOptions() ) + nl + - " UID: 0x" + HexDump.toHex( field_1_UID ) + nl + - " Uncompressed Size: " + HexDump.toHex( field_2_cb ) + nl + - " Bounds: " + getBounds() + nl + - " Size in EMU: " + getSizeEMU() + nl + - " Compressed Size: " + HexDump.toHex( field_5_cbSave ) + nl + - " Compression: " + HexDump.toHex( field_6_fCompression ) + nl + - " Filter: " + HexDump.toHex( field_7_fFilter ) + nl + - " Extra Data:" + nl + extraData; - } - -} +/* +* 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.ddf; + +import org.apache.poi.util.HexDump; +import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; + +import java.awt.Dimension; +import java.awt.Rectangle; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.zip.InflaterInputStream; + +/** + * @author Daniel Noll + * @version $Id$ + */ +public class EscherPictBlip + extends EscherBlipRecord +{ + private static final POILogger log = POILogFactory.getLogger(EscherPictBlip.class); + + public static final short RECORD_ID_EMF = (short) 0xF018 + 2; + public static final short RECORD_ID_WMF = (short) 0xF018 + 3; + public static final short RECORD_ID_PICT = (short) 0xF018 + 4; + + private static final int HEADER_SIZE = 8; + + private byte[] field_1_UID; + private int field_2_cb; + private int field_3_rcBounds_x1; + private int field_3_rcBounds_y1; + private int field_3_rcBounds_x2; + private int field_3_rcBounds_y2; + private int field_4_ptSize_w; + private int field_4_ptSize_h; + private int field_5_cbSave; + private byte field_6_fCompression; + private byte field_7_fFilter; + + private byte[] raw_pictureData; + + /** + * This method deserializes the record from a byte array. + * + * @param data The byte array containing the escher record information + * @param offset The starting offset into data. + * @param recordFactory May be null since this is not a container record. + * @return The number of bytes read from the byte array. + */ + public int fillFields( byte[] data, int offset, EscherRecordFactory recordFactory ) + { + int bytesAfterHeader = readHeader( data, offset ); + int pos = offset + HEADER_SIZE; + + field_1_UID = new byte[16]; + System.arraycopy( data, pos, field_1_UID, 0, 16 ); pos += 16; + field_2_cb = LittleEndian.getInt( data, pos ); pos += 4; + field_3_rcBounds_x1 = LittleEndian.getInt( data, pos ); pos += 4; + field_3_rcBounds_y1 = LittleEndian.getInt( data, pos ); pos += 4; + field_3_rcBounds_x2 = LittleEndian.getInt( data, pos ); pos += 4; + field_3_rcBounds_y2 = LittleEndian.getInt( data, pos ); pos += 4; + field_4_ptSize_w = LittleEndian.getInt( data, pos ); pos += 4; + field_4_ptSize_h = LittleEndian.getInt( data, pos ); pos += 4; + field_5_cbSave = LittleEndian.getInt( data, pos ); pos += 4; + field_6_fCompression = data[pos]; pos++; + field_7_fFilter = data[pos]; pos++; + + raw_pictureData = new byte[field_5_cbSave]; + System.arraycopy( data, pos, raw_pictureData, 0, field_5_cbSave ); + + // 0 means DEFLATE compression + // 0xFE means no compression + if (field_6_fCompression == 0) + { + field_pictureData = inflatePictureData(raw_pictureData); + } + else + { + field_pictureData = raw_pictureData; + } + + return bytesAfterHeader + HEADER_SIZE; + } + + /** + * Serializes the record to an existing byte array. + * + * @param offset the offset within the byte array + * @param data the data array to serialize to + * @param listener a listener for begin and end serialization events. This + * is useful because the serialization is + * hierarchical/recursive and sometimes you need to be able + * break into that. + * @return the number of bytes written. + */ + public int serialize( int offset, byte[] data, EscherSerializationListener listener ) + { + listener.beforeRecordSerialize(offset, getRecordId(), this); + + int pos = offset; + LittleEndian.putShort( data, pos, getOptions() ); pos += 2; + LittleEndian.putShort( data, pos, getRecordId() ); pos += 2; + LittleEndian.putInt( data, getRecordSize() - HEADER_SIZE ); pos += 4; + + System.arraycopy( field_1_UID, 0, data, pos, 16 ); pos += 16; + LittleEndian.putInt( data, pos, field_2_cb ); pos += 4; + LittleEndian.putInt( data, pos, field_3_rcBounds_x1 ); pos += 4; + LittleEndian.putInt( data, pos, field_3_rcBounds_y1 ); pos += 4; + LittleEndian.putInt( data, pos, field_3_rcBounds_x2 ); pos += 4; + LittleEndian.putInt( data, pos, field_3_rcBounds_y2 ); pos += 4; + LittleEndian.putInt( data, pos, field_4_ptSize_w ); pos += 4; + LittleEndian.putInt( data, pos, field_4_ptSize_h ); pos += 4; + LittleEndian.putInt( data, pos, field_5_cbSave ); pos += 4; + data[pos] = field_6_fCompression; pos++; + data[pos] = field_7_fFilter; pos++; + + System.arraycopy( raw_pictureData, 0, data, pos, raw_pictureData.length ); + + listener.afterRecordSerialize(offset + getRecordSize(), getRecordId(), getRecordSize(), this); + return HEADER_SIZE + 16 + 1 + raw_pictureData.length; + } + + /** + * Decompresses the provided data, returning the inflated result. + * + * @param data the deflated picture data. + * @return the inflated picture data. + */ + private static byte[] inflatePictureData(byte[] data) + { + try + { + InflaterInputStream in = new InflaterInputStream( + new ByteArrayInputStream( data ) ); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] buf = new byte[4096]; + int readBytes; + while ((readBytes = in.read(buf)) > 0) + { + out.write(buf, 0, readBytes); + } + return out.toByteArray(); + } + catch ( IOException e ) + { + log.log(POILogger.INFO, "Possibly corrupt compression or non-compressed data", e); + return data; + } + } + + /** + * Returns the number of bytes that are required to serialize this record. + * + * @return Number of bytes + */ + public int getRecordSize() + { + return 8 + 50 + raw_pictureData.length; + } + + public byte[] getUID() + { + return field_1_UID; + } + + public void setUID( byte[] field_1_UID ) + { + this.field_1_UID = field_1_UID; + } + + public int getUncompressedSize() + { + return field_2_cb; + } + + public void setUncompressedSize(int uncompressedSize) + { + field_2_cb = uncompressedSize; + } + + public Rectangle getBounds() + { + return new Rectangle(field_3_rcBounds_x1, + field_3_rcBounds_y1, + field_3_rcBounds_x2 - field_3_rcBounds_x1, + field_3_rcBounds_y2 - field_3_rcBounds_y1); + } + + public void setBounds(Rectangle bounds) + { + field_3_rcBounds_x1 = bounds.x; + field_3_rcBounds_y1 = bounds.y; + field_3_rcBounds_x2 = bounds.x + bounds.width; + field_3_rcBounds_y2 = bounds.y + bounds.height; + } + + public Dimension getSizeEMU() + { + return new Dimension(field_4_ptSize_w, field_4_ptSize_h); + } + + public void setSizeEMU(Dimension sizeEMU) + { + field_4_ptSize_w = sizeEMU.width; + field_4_ptSize_h = sizeEMU.height; + } + + public int getCompressedSize() + { + return field_5_cbSave; + } + + public void setCompressedSize(int compressedSize) + { + field_5_cbSave = compressedSize; + } + + public boolean isCompressed() + { + return (field_6_fCompression == 0); + } + + public void setCompressed(boolean compressed) + { + field_6_fCompression = compressed ? 0 : (byte)0xFE; + } + + // filtering is always 254 according to available docs, so no point giving it a setter method. + + public String toString() + { + String nl = System.getProperty( "line.separator" ); + + String extraData; + ByteArrayOutputStream b = new ByteArrayOutputStream(); + try + { + HexDump.dump( this.field_pictureData, 0, b, 0 ); + extraData = b.toString(); + } + catch ( Exception e ) + { + extraData = e.toString(); + } + return getClass().getName() + ":" + nl + + " RecordId: 0x" + HexDump.toHex( getRecordId() ) + nl + + " Options: 0x" + HexDump.toHex( getOptions() ) + nl + + " UID: 0x" + HexDump.toHex( field_1_UID ) + nl + + " Uncompressed Size: " + HexDump.toHex( field_2_cb ) + nl + + " Bounds: " + getBounds() + nl + + " Size in EMU: " + getSizeEMU() + nl + + " Compressed Size: " + HexDump.toHex( field_5_cbSave ) + nl + + " Compression: " + HexDump.toHex( field_6_fCompression ) + nl + + " Filter: " + HexDump.toHex( field_7_fFilter ) + nl + + " Extra Data:" + nl + extraData; + } + +} diff --git a/src/java/org/apache/poi/hssf/model/HSSFFormulaParser.java b/src/java/org/apache/poi/hssf/model/HSSFFormulaParser.java index f24441841b..026590d71d 100644 --- a/src/java/org/apache/poi/hssf/model/HSSFFormulaParser.java +++ b/src/java/org/apache/poi/hssf/model/HSSFFormulaParser.java @@ -1,82 +1,82 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.model; - -import org.apache.poi.hssf.record.formula.Ptg; -import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.formula.FormulaParser; -import org.apache.poi.ss.formula.FormulaParsingWorkbook; -import org.apache.poi.ss.formula.FormulaRenderer; -import org.apache.poi.ss.formula.FormulaType; - -/** - * HSSF wrapper for the {@link FormulaParser} and {@link FormulaRenderer} - * - * @author Josh Micich - */ -public final class HSSFFormulaParser { - - private static FormulaParsingWorkbook createParsingWorkbook(HSSFWorkbook book) { - return HSSFEvaluationWorkbook.create(book); - } - - private HSSFFormulaParser() { - // no instances of this class - } - - /** - * Convenience method for parsing cell formulas. see {@link #parse(String, HSSFWorkbook, int)} - */ - public static Ptg[] parse(String formula, HSSFWorkbook workbook) { - return parse(formula, workbook, FormulaType.CELL); - } - - /** - * @param formulaType a constant from {@link FormulaType} - * @return the parsed formula tokens - */ - public static Ptg[] parse(String formula, HSSFWorkbook workbook, int formulaType) { - return parse(formula, workbook, formulaType, -1); - } - - /** - * @param formula the formula to parse - * @param workbook the parent workbook - * @param formulaType a constant from {@link FormulaType} - * @param sheetIndex the 0-based index of the sheet this formula belongs to. - * The sheet index is required to resolve sheet-level names. -1 means that - * the scope of the name will be ignored and the parser will match named ranges only by name - * - * @return the parsed formula tokens - */ - public static Ptg[] parse(String formula, HSSFWorkbook workbook, int formulaType, int sheetIndex) { - return FormulaParser.parse(formula, createParsingWorkbook(workbook), formulaType, sheetIndex); - } - - /** - * Static method to convert an array of {@link Ptg}s in RPN order - * to a human readable string format in infix mode. - * @param book used for defined names and 3D references - * @param ptgs must not be null - * @return a human readable String - */ - public static String toFormulaString(HSSFWorkbook book, Ptg[] ptgs) { - return FormulaRenderer.toFormulaString(HSSFEvaluationWorkbook.create(book), ptgs); - } -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.model; + +import org.apache.poi.hssf.record.formula.Ptg; +import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.formula.FormulaParser; +import org.apache.poi.ss.formula.FormulaParsingWorkbook; +import org.apache.poi.ss.formula.FormulaRenderer; +import org.apache.poi.ss.formula.FormulaType; + +/** + * HSSF wrapper for the {@link FormulaParser} and {@link FormulaRenderer} + * + * @author Josh Micich + */ +public final class HSSFFormulaParser { + + private static FormulaParsingWorkbook createParsingWorkbook(HSSFWorkbook book) { + return HSSFEvaluationWorkbook.create(book); + } + + private HSSFFormulaParser() { + // no instances of this class + } + + /** + * Convenience method for parsing cell formulas. see {@link #parse(String, HSSFWorkbook, int)} + */ + public static Ptg[] parse(String formula, HSSFWorkbook workbook) { + return parse(formula, workbook, FormulaType.CELL); + } + + /** + * @param formulaType a constant from {@link FormulaType} + * @return the parsed formula tokens + */ + public static Ptg[] parse(String formula, HSSFWorkbook workbook, int formulaType) { + return parse(formula, workbook, formulaType, -1); + } + + /** + * @param formula the formula to parse + * @param workbook the parent workbook + * @param formulaType a constant from {@link FormulaType} + * @param sheetIndex the 0-based index of the sheet this formula belongs to. + * The sheet index is required to resolve sheet-level names. -1 means that + * the scope of the name will be ignored and the parser will match named ranges only by name + * + * @return the parsed formula tokens + */ + public static Ptg[] parse(String formula, HSSFWorkbook workbook, int formulaType, int sheetIndex) { + return FormulaParser.parse(formula, createParsingWorkbook(workbook), formulaType, sheetIndex); + } + + /** + * Static method to convert an array of {@link Ptg}s in RPN order + * to a human readable string format in infix mode. + * @param book used for defined names and 3D references + * @param ptgs must not be null + * @return a human readable String + */ + public static String toFormulaString(HSSFWorkbook book, Ptg[] ptgs) { + return FormulaRenderer.toFormulaString(HSSFEvaluationWorkbook.create(book), ptgs); + } +} diff --git a/src/java/org/apache/poi/hssf/record/ArrayRecord.java b/src/java/org/apache/poi/hssf/record/ArrayRecord.java index 35239bb238..0cf6f44e05 100644 --- a/src/java/org/apache/poi/hssf/record/ArrayRecord.java +++ b/src/java/org/apache/poi/hssf/record/ArrayRecord.java @@ -1,87 +1,87 @@ -/* ==================================================================== - 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; - -import org.apache.poi.hssf.record.formula.Ptg; -import org.apache.poi.ss.formula.Formula; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * ARRAY (0x0221)

- * - * Treated in a similar way to SharedFormulaRecord - * - * @author Josh Micich - */ -public final class ArrayRecord extends SharedValueRecordBase { - - public final static short sid = 0x0221; - private static final int OPT_ALWAYS_RECALCULATE = 0x0001; - private static final int OPT_CALCULATE_ON_OPEN = 0x0002; - - private int _options; - private int _field3notUsed; - private Formula _formula; - - public ArrayRecord(RecordInputStream in) { - super(in); - _options = in.readUShort(); - _field3notUsed = in.readInt(); - int formulaTokenLen = in.readUShort(); - int totalFormulaLen = in.available(); - _formula = Formula.read(formulaTokenLen, in, totalFormulaLen); - } - - public boolean isAlwaysRecalculate() { - return (_options & OPT_ALWAYS_RECALCULATE) != 0; - } - public boolean isCalculateOnOpen() { - return (_options & OPT_CALCULATE_ON_OPEN) != 0; - } - - protected int getExtraDataSize() { - return 2 + 4 - + _formula.getEncodedSize(); - } - protected void serializeExtraData(LittleEndianOutput out) { - out.writeShort(_options); - out.writeInt(_field3notUsed); - _formula.serialize(out); - } - - public short getSid() { - return sid; - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getName()).append(" [ARRAY]\n"); - sb.append(" range=").append(getRange().toString()).append("\n"); - sb.append(" options=").append(HexDump.shortToHex(_options)).append("\n"); - sb.append(" notUsed=").append(HexDump.intToHex(_field3notUsed)).append("\n"); - sb.append(" formula:").append("\n"); - Ptg[] ptgs = _formula.getTokens(); - for (int i = 0; i < ptgs.length; i++) { - Ptg ptg = ptgs[i]; - sb.append(ptg.toString()).append(ptg.getRVAType()).append("\n"); - } - 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; + +import org.apache.poi.hssf.record.formula.Ptg; +import org.apache.poi.ss.formula.Formula; +import org.apache.poi.util.HexDump; +import org.apache.poi.util.LittleEndianOutput; + +/** + * ARRAY (0x0221)

+ * + * Treated in a similar way to SharedFormulaRecord + * + * @author Josh Micich + */ +public final class ArrayRecord extends SharedValueRecordBase { + + public final static short sid = 0x0221; + private static final int OPT_ALWAYS_RECALCULATE = 0x0001; + private static final int OPT_CALCULATE_ON_OPEN = 0x0002; + + private int _options; + private int _field3notUsed; + private Formula _formula; + + public ArrayRecord(RecordInputStream in) { + super(in); + _options = in.readUShort(); + _field3notUsed = in.readInt(); + int formulaTokenLen = in.readUShort(); + int totalFormulaLen = in.available(); + _formula = Formula.read(formulaTokenLen, in, totalFormulaLen); + } + + public boolean isAlwaysRecalculate() { + return (_options & OPT_ALWAYS_RECALCULATE) != 0; + } + public boolean isCalculateOnOpen() { + return (_options & OPT_CALCULATE_ON_OPEN) != 0; + } + + protected int getExtraDataSize() { + return 2 + 4 + + _formula.getEncodedSize(); + } + protected void serializeExtraData(LittleEndianOutput out) { + out.writeShort(_options); + out.writeInt(_field3notUsed); + _formula.serialize(out); + } + + public short getSid() { + return sid; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(getClass().getName()).append(" [ARRAY]\n"); + sb.append(" range=").append(getRange().toString()).append("\n"); + sb.append(" options=").append(HexDump.shortToHex(_options)).append("\n"); + sb.append(" notUsed=").append(HexDump.intToHex(_field3notUsed)).append("\n"); + sb.append(" formula:").append("\n"); + Ptg[] ptgs = _formula.getTokens(); + for (int i = 0; i < ptgs.length; i++) { + Ptg ptg = ptgs[i]; + sb.append(ptg.toString()).append(ptg.getRVAType()).append("\n"); + } + sb.append("]"); + return sb.toString(); + } +} diff --git a/src/java/org/apache/poi/hssf/record/CellRecord.java b/src/java/org/apache/poi/hssf/record/CellRecord.java index 5f0646a9a0..9d9ed4fc9a 100644 --- a/src/java/org/apache/poi/hssf/record/CellRecord.java +++ b/src/java/org/apache/poi/hssf/record/CellRecord.java @@ -1,132 +1,132 @@ -/* ==================================================================== - 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; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Base class for all cell value records (implementors of {@link CellValueRecordInterface}). - * Subclasses are expected to manage the cell data values (of various types). - * - * @author Josh Micich - */ -public abstract class CellRecord extends StandardRecord implements CellValueRecordInterface { - private int _rowIndex; - private int _columnIndex; - private int _formatIndex; - - protected CellRecord() { - // fields uninitialised - } - - protected CellRecord(RecordInputStream in) { - _rowIndex = in.readUShort(); - _columnIndex = in.readUShort(); - _formatIndex = in.readUShort(); - } - - public final void setRow(int row) { - _rowIndex = row; - } - - public final void setColumn(short col) { - _columnIndex = col; - } - - /** - * set the index to the ExtendedFormat - * - * @see org.apache.poi.hssf.record.ExtendedFormatRecord - * @param xf index to the XF record - */ - public final void setXFIndex(short xf) { - _formatIndex = xf; - } - - public final int getRow() { - return _rowIndex; - } - - public final short getColumn() { - return (short) _columnIndex; - } - - /** - * get the index to the ExtendedFormat - * - * @see org.apache.poi.hssf.record.ExtendedFormatRecord - * @return index to the XF record - */ - public final short getXFIndex() { - return (short) _formatIndex; - } - - public final String toString() { - StringBuilder sb = new StringBuilder(); - String recordName = getRecordName(); - - sb.append("[").append(recordName).append("]\n"); - sb.append(" .row = ").append(HexDump.shortToHex(getRow())).append("\n"); - sb.append(" .col = ").append(HexDump.shortToHex(getColumn())).append("\n"); - sb.append(" .xfindex= ").append(HexDump.shortToHex(getXFIndex())).append("\n"); - appendValueText(sb); - sb.append("\n"); - sb.append("[/").append(recordName).append("]\n"); - return sb.toString(); - } - - /** - * Append specific debug info (used by {@link #toString()} for the value - * contained in this record. Trailing new-line should not be appended - * (superclass does that). - */ - protected abstract void appendValueText(StringBuilder sb); - - /** - * Gets the debug info BIFF record type name (used by {@link #toString()}. - */ - protected abstract String getRecordName(); - - /** - * writes out the value data for this cell record - */ - protected abstract void serializeValue(LittleEndianOutput out); - - /** - * @return the size (in bytes) of the value data for this cell record - */ - protected abstract int getValueDataSize(); - - public final void serialize(LittleEndianOutput out) { - out.writeShort(getRow()); - out.writeShort(getColumn()); - out.writeShort(getXFIndex()); - serializeValue(out); - } - - protected final int getDataSize() { - return 6 + getValueDataSize(); - } - - protected final void copyBaseFields(CellRecord rec) { - rec._rowIndex = _rowIndex; - rec._columnIndex = _columnIndex; - rec._formatIndex = _formatIndex; - } -} +/* ==================================================================== + 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; + +import org.apache.poi.util.HexDump; +import org.apache.poi.util.LittleEndianOutput; + +/** + * Base class for all cell value records (implementors of {@link CellValueRecordInterface}). + * Subclasses are expected to manage the cell data values (of various types). + * + * @author Josh Micich + */ +public abstract class CellRecord extends StandardRecord implements CellValueRecordInterface { + private int _rowIndex; + private int _columnIndex; + private int _formatIndex; + + protected CellRecord() { + // fields uninitialised + } + + protected CellRecord(RecordInputStream in) { + _rowIndex = in.readUShort(); + _columnIndex = in.readUShort(); + _formatIndex = in.readUShort(); + } + + public final void setRow(int row) { + _rowIndex = row; + } + + public final void setColumn(short col) { + _columnIndex = col; + } + + /** + * set the index to the ExtendedFormat + * + * @see org.apache.poi.hssf.record.ExtendedFormatRecord + * @param xf index to the XF record + */ + public final void setXFIndex(short xf) { + _formatIndex = xf; + } + + public final int getRow() { + return _rowIndex; + } + + public final short getColumn() { + return (short) _columnIndex; + } + + /** + * get the index to the ExtendedFormat + * + * @see org.apache.poi.hssf.record.ExtendedFormatRecord + * @return index to the XF record + */ + public final short getXFIndex() { + return (short) _formatIndex; + } + + public final String toString() { + StringBuilder sb = new StringBuilder(); + String recordName = getRecordName(); + + sb.append("[").append(recordName).append("]\n"); + sb.append(" .row = ").append(HexDump.shortToHex(getRow())).append("\n"); + sb.append(" .col = ").append(HexDump.shortToHex(getColumn())).append("\n"); + sb.append(" .xfindex= ").append(HexDump.shortToHex(getXFIndex())).append("\n"); + appendValueText(sb); + sb.append("\n"); + sb.append("[/").append(recordName).append("]\n"); + return sb.toString(); + } + + /** + * Append specific debug info (used by {@link #toString()} for the value + * contained in this record. Trailing new-line should not be appended + * (superclass does that). + */ + protected abstract void appendValueText(StringBuilder sb); + + /** + * Gets the debug info BIFF record type name (used by {@link #toString()}. + */ + protected abstract String getRecordName(); + + /** + * writes out the value data for this cell record + */ + protected abstract void serializeValue(LittleEndianOutput out); + + /** + * @return the size (in bytes) of the value data for this cell record + */ + protected abstract int getValueDataSize(); + + public final void serialize(LittleEndianOutput out) { + out.writeShort(getRow()); + out.writeShort(getColumn()); + out.writeShort(getXFIndex()); + serializeValue(out); + } + + protected final int getDataSize() { + return 6 + getValueDataSize(); + } + + protected final void copyBaseFields(CellRecord rec) { + rec._rowIndex = _rowIndex; + rec._columnIndex = _columnIndex; + rec._formatIndex = _formatIndex; + } +} diff --git a/src/java/org/apache/poi/hssf/record/HeaderFooterBase.java b/src/java/org/apache/poi/hssf/record/HeaderFooterBase.java index 92ccf944f1..84678b7b65 100644 --- a/src/java/org/apache/poi/hssf/record/HeaderFooterBase.java +++ b/src/java/org/apache/poi/hssf/record/HeaderFooterBase.java @@ -1,109 +1,109 @@ -/* ==================================================================== - 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; - -import org.apache.poi.util.LittleEndianOutput; -import org.apache.poi.util.StringUtil; - -/** - * Common header/footer base class - * - * @author Josh Micich - */ -abstract class HeaderFooterBase extends StandardRecord { - private boolean field_2_hasMultibyte; - private String field_3_text; - - protected HeaderFooterBase(String text) { - setText(text); - } - - protected HeaderFooterBase(RecordInputStream in) { - if (in.remaining() > 0) { - int field_1_footer_len = in.readShort(); - field_2_hasMultibyte = in.readByte() != 0x00; - - if (field_2_hasMultibyte) { - field_3_text = in.readUnicodeLEString(field_1_footer_len); - } else { - field_3_text = in.readCompressedUnicode(field_1_footer_len); - } - } else { - // Note - this is unusual: when the text is empty string, the whole record is empty (just the 4 byte BIFF header) - field_3_text = ""; - } - } - - /** - * set the footer string - * - * @param text string to display - */ - public final void setText(String text) { - if (text == null) { - throw new IllegalArgumentException("text must not be null"); - } - field_2_hasMultibyte = StringUtil.hasMultibyte(text); - field_3_text = text; - - // Check it'll fit into the space in the record - if (field_2_hasMultibyte) { - if (field_3_text.length() > 127) { - throw new IllegalArgumentException( - "Footer string too long (limit is 127 for unicode strings)"); - } - } else { - if (field_3_text.length() > 255) { - throw new IllegalArgumentException( - "Footer string too long (limit is 255 for non-unicode strings)"); - } - } - } - - /** - * get the length of the footer string - * - * @return length of the footer string - */ - private int getTextLength() { - return field_3_text.length(); - } - - public final String getText() { - return field_3_text; - } - - public final void serialize(LittleEndianOutput out) { - if (getTextLength() > 0) { - out.writeShort(getTextLength()); - out.writeByte(field_2_hasMultibyte ? 0x01 : 0x00); - if (field_2_hasMultibyte) { - StringUtil.putUnicodeLE(field_3_text, out); - } else { - StringUtil.putCompressedUnicode(field_3_text, out); - } - } - } - - protected final int getDataSize() { - if (getTextLength() < 1) { - return 0; - } - return 3 + getTextLength() * (field_2_hasMultibyte ? 2 : 1); - } -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record; + +import org.apache.poi.util.LittleEndianOutput; +import org.apache.poi.util.StringUtil; + +/** + * Common header/footer base class + * + * @author Josh Micich + */ +abstract class HeaderFooterBase extends StandardRecord { + private boolean field_2_hasMultibyte; + private String field_3_text; + + protected HeaderFooterBase(String text) { + setText(text); + } + + protected HeaderFooterBase(RecordInputStream in) { + if (in.remaining() > 0) { + int field_1_footer_len = in.readShort(); + field_2_hasMultibyte = in.readByte() != 0x00; + + if (field_2_hasMultibyte) { + field_3_text = in.readUnicodeLEString(field_1_footer_len); + } else { + field_3_text = in.readCompressedUnicode(field_1_footer_len); + } + } else { + // Note - this is unusual: when the text is empty string, the whole record is empty (just the 4 byte BIFF header) + field_3_text = ""; + } + } + + /** + * set the footer string + * + * @param text string to display + */ + public final void setText(String text) { + if (text == null) { + throw new IllegalArgumentException("text must not be null"); + } + field_2_hasMultibyte = StringUtil.hasMultibyte(text); + field_3_text = text; + + // Check it'll fit into the space in the record + if (field_2_hasMultibyte) { + if (field_3_text.length() > 127) { + throw new IllegalArgumentException( + "Footer string too long (limit is 127 for unicode strings)"); + } + } else { + if (field_3_text.length() > 255) { + throw new IllegalArgumentException( + "Footer string too long (limit is 255 for non-unicode strings)"); + } + } + } + + /** + * get the length of the footer string + * + * @return length of the footer string + */ + private int getTextLength() { + return field_3_text.length(); + } + + public final String getText() { + return field_3_text; + } + + public final void serialize(LittleEndianOutput out) { + if (getTextLength() > 0) { + out.writeShort(getTextLength()); + out.writeByte(field_2_hasMultibyte ? 0x01 : 0x00); + if (field_2_hasMultibyte) { + StringUtil.putUnicodeLE(field_3_text, out); + } else { + StringUtil.putCompressedUnicode(field_3_text, out); + } + } + } + + protected final int getDataSize() { + if (getTextLength() < 1) { + return 0; + } + return 3 + getTextLength() * (field_2_hasMultibyte ? 2 : 1); + } +} diff --git a/src/java/org/apache/poi/hssf/record/StandardRecord.java b/src/java/org/apache/poi/hssf/record/StandardRecord.java index 20fe141054..347578c872 100644 --- a/src/java/org/apache/poi/hssf/record/StandardRecord.java +++ b/src/java/org/apache/poi/hssf/record/StandardRecord.java @@ -1,57 +1,57 @@ -/* ==================================================================== - 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; - -import org.apache.poi.util.LittleEndianByteArrayOutputStream; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Subclasses of this class (the majority of BIFF records) are non-continuable. This allows for - * some simplification of serialization logic - * - * @author Josh Micich - */ -public abstract class StandardRecord extends Record { - protected abstract int getDataSize(); - public final int getRecordSize() { - return 4 + getDataSize(); - } - @Override - public final int serialize(int offset, byte[] data) { - int dataSize = getDataSize(); - int recSize = 4 + dataSize; - LittleEndianByteArrayOutputStream out = new LittleEndianByteArrayOutputStream(data, offset, recSize); - out.writeShort(getSid()); - out.writeShort(dataSize); - serialize(out); - if (out.getWriteIndex() - offset != recSize) { - throw new IllegalStateException("Error in serialization of (" + getClass().getName() + "): " - + "Incorrect number of bytes written - expected " - + recSize + " but got " + (out.getWriteIndex() - offset)); - } - return recSize; - } - - /** - * Write the data content of this BIFF record. The 'ushort sid' and 'ushort size' header fields - * have already been written by the superclass.
- * - * The subclass must write the exact number of bytes as reported by {@link org.apache.poi.hssf.record.Record#getRecordSize()}} - */ - protected abstract void serialize(LittleEndianOutput out); -} +/* ==================================================================== + 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; + +import org.apache.poi.util.LittleEndianByteArrayOutputStream; +import org.apache.poi.util.LittleEndianOutput; + +/** + * Subclasses of this class (the majority of BIFF records) are non-continuable. This allows for + * some simplification of serialization logic + * + * @author Josh Micich + */ +public abstract class StandardRecord extends Record { + protected abstract int getDataSize(); + public final int getRecordSize() { + return 4 + getDataSize(); + } + @Override + public final int serialize(int offset, byte[] data) { + int dataSize = getDataSize(); + int recSize = 4 + dataSize; + LittleEndianByteArrayOutputStream out = new LittleEndianByteArrayOutputStream(data, offset, recSize); + out.writeShort(getSid()); + out.writeShort(dataSize); + serialize(out); + if (out.getWriteIndex() - offset != recSize) { + throw new IllegalStateException("Error in serialization of (" + getClass().getName() + "): " + + "Incorrect number of bytes written - expected " + + recSize + " but got " + (out.getWriteIndex() - offset)); + } + return recSize; + } + + /** + * Write the data content of this BIFF record. The 'ushort sid' and 'ushort size' header fields + * have already been written by the superclass.
+ * + * The subclass must write the exact number of bytes as reported by {@link org.apache.poi.hssf.record.Record#getRecordSize()}} + */ + protected abstract void serialize(LittleEndianOutput out); +} diff --git a/src/java/org/apache/poi/hssf/record/aggregates/ChartSubstreamRecordAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/ChartSubstreamRecordAggregate.java index 9b1d14d562..a891488b9f 100644 --- a/src/java/org/apache/poi/hssf/record/aggregates/ChartSubstreamRecordAggregate.java +++ b/src/java/org/apache/poi/hssf/record/aggregates/ChartSubstreamRecordAggregate.java @@ -1,87 +1,87 @@ -/* ==================================================================== - 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.aggregates; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hssf.model.RecordStream; -import org.apache.poi.hssf.record.BOFRecord; -import org.apache.poi.hssf.record.EOFRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RecordBase; -import org.apache.poi.hssf.record.UnknownRecord; - -/** - * Manages the all the records associated with a chart sub-stream.
- * Includes the initial {@link BOFRecord} and final {@link EOFRecord}. - * - * @author Josh Micich - */ -public final class ChartSubstreamRecordAggregate extends RecordAggregate { - - private final BOFRecord _bofRec; - /** - * All the records between BOF and EOF - */ - private final List _recs; - private PageSettingsBlock _psBlock; - - public ChartSubstreamRecordAggregate(RecordStream rs) { - _bofRec = (BOFRecord) rs.getNext(); - List temp = new ArrayList(); - while (rs.peekNextClass() != EOFRecord.class) { - if (PageSettingsBlock.isComponentRecord(rs.peekNextSid())) { - if (_psBlock != null) { - if (rs.peekNextSid() == UnknownRecord.HEADER_FOOTER_089C) { - // test samples: 45538_classic_Footer.xls, 45538_classic_Header.xls - _psBlock.addLateHeaderFooter(rs.getNext()); - continue; - } - throw new IllegalStateException( - "Found more than one PageSettingsBlock in chart sub-stream"); - } - _psBlock = new PageSettingsBlock(rs); - temp.add(_psBlock); - continue; - } - temp.add(rs.getNext()); - } - _recs = temp; - Record eof = rs.getNext(); // no need to save EOF in field - if (!(eof instanceof EOFRecord)) { - throw new IllegalStateException("Bad chart EOF"); - } - } - - public void visitContainedRecords(RecordVisitor rv) { - if (_recs.isEmpty()) { - return; - } - rv.visitRecord(_bofRec); - for (int i = 0; i < _recs.size(); i++) { - RecordBase rb = _recs.get(i); - if (rb instanceof RecordAggregate) { - ((RecordAggregate) rb).visitContainedRecords(rv); - } else { - rv.visitRecord((Record) rb); - } - } - rv.visitRecord(EOFRecord.instance); - } -} +/* ==================================================================== + 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.aggregates; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.poi.hssf.model.RecordStream; +import org.apache.poi.hssf.record.BOFRecord; +import org.apache.poi.hssf.record.EOFRecord; +import org.apache.poi.hssf.record.Record; +import org.apache.poi.hssf.record.RecordBase; +import org.apache.poi.hssf.record.UnknownRecord; + +/** + * Manages the all the records associated with a chart sub-stream.
+ * Includes the initial {@link BOFRecord} and final {@link EOFRecord}. + * + * @author Josh Micich + */ +public final class ChartSubstreamRecordAggregate extends RecordAggregate { + + private final BOFRecord _bofRec; + /** + * All the records between BOF and EOF + */ + private final List _recs; + private PageSettingsBlock _psBlock; + + public ChartSubstreamRecordAggregate(RecordStream rs) { + _bofRec = (BOFRecord) rs.getNext(); + List temp = new ArrayList(); + while (rs.peekNextClass() != EOFRecord.class) { + if (PageSettingsBlock.isComponentRecord(rs.peekNextSid())) { + if (_psBlock != null) { + if (rs.peekNextSid() == UnknownRecord.HEADER_FOOTER_089C) { + // test samples: 45538_classic_Footer.xls, 45538_classic_Header.xls + _psBlock.addLateHeaderFooter(rs.getNext()); + continue; + } + throw new IllegalStateException( + "Found more than one PageSettingsBlock in chart sub-stream"); + } + _psBlock = new PageSettingsBlock(rs); + temp.add(_psBlock); + continue; + } + temp.add(rs.getNext()); + } + _recs = temp; + Record eof = rs.getNext(); // no need to save EOF in field + if (!(eof instanceof EOFRecord)) { + throw new IllegalStateException("Bad chart EOF"); + } + } + + public void visitContainedRecords(RecordVisitor rv) { + if (_recs.isEmpty()) { + return; + } + rv.visitRecord(_bofRec); + for (int i = 0; i < _recs.size(); i++) { + RecordBase rb = _recs.get(i); + if (rb instanceof RecordAggregate) { + ((RecordAggregate) rb).visitContainedRecords(rv); + } else { + rv.visitRecord((Record) rb); + } + } + rv.visitRecord(EOFRecord.instance); + } +} diff --git a/src/java/org/apache/poi/hssf/record/aggregates/DataValidityTable.java b/src/java/org/apache/poi/hssf/record/aggregates/DataValidityTable.java index f4861b011b..e2dfcd6d35 100644 --- a/src/java/org/apache/poi/hssf/record/aggregates/DataValidityTable.java +++ b/src/java/org/apache/poi/hssf/record/aggregates/DataValidityTable.java @@ -1,70 +1,70 @@ -/* ==================================================================== - 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.aggregates; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.hssf.model.RecordStream; -import org.apache.poi.hssf.record.DVALRecord; -import org.apache.poi.hssf.record.DVRecord; -import org.apache.poi.hssf.record.Record; - -/** - * Manages the DVALRecord and DVRecords for a single sheet
- * See OOO excelfileformat.pdf section 4.14 - * @author Josh Micich - */ -public final class DataValidityTable extends RecordAggregate { - - private final DVALRecord _headerRec; - /** - * The list of data validations for the current sheet. - * Note - this may be empty (contrary to OOO documentation) - */ - private final List _validationList; - - public DataValidityTable(RecordStream rs) { - _headerRec = (DVALRecord) rs.getNext(); - List temp = new ArrayList(); - while (rs.peekNextClass() == DVRecord.class) { - temp.add(rs.getNext()); - } - _validationList = temp; - } - - public DataValidityTable() { - _headerRec = new DVALRecord(); - _validationList = new ArrayList(); - } - - public void visitContainedRecords(RecordVisitor rv) { - if (_validationList.isEmpty()) { - return; - } - rv.visitRecord(_headerRec); - for (int i = 0; i < _validationList.size(); i++) { - rv.visitRecord((Record) _validationList.get(i)); - } - } - - public void addDataValidation(DVRecord dvRecord) { - _validationList.add(dvRecord); - _headerRec.setDVRecNo(_validationList.size()); - } -} +/* ==================================================================== + 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.aggregates; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.poi.hssf.model.RecordStream; +import org.apache.poi.hssf.record.DVALRecord; +import org.apache.poi.hssf.record.DVRecord; +import org.apache.poi.hssf.record.Record; + +/** + * Manages the DVALRecord and DVRecords for a single sheet
+ * See OOO excelfileformat.pdf section 4.14 + * @author Josh Micich + */ +public final class DataValidityTable extends RecordAggregate { + + private final DVALRecord _headerRec; + /** + * The list of data validations for the current sheet. + * Note - this may be empty (contrary to OOO documentation) + */ + private final List _validationList; + + public DataValidityTable(RecordStream rs) { + _headerRec = (DVALRecord) rs.getNext(); + List temp = new ArrayList(); + while (rs.peekNextClass() == DVRecord.class) { + temp.add(rs.getNext()); + } + _validationList = temp; + } + + public DataValidityTable() { + _headerRec = new DVALRecord(); + _validationList = new ArrayList(); + } + + public void visitContainedRecords(RecordVisitor rv) { + if (_validationList.isEmpty()) { + return; + } + rv.visitRecord(_headerRec); + for (int i = 0; i < _validationList.size(); i++) { + rv.visitRecord((Record) _validationList.get(i)); + } + } + + public void addDataValidation(DVRecord dvRecord) { + _validationList.add(dvRecord); + _headerRec.setDVRecNo(_validationList.size()); + } +} diff --git a/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java index 6eefb30e1c..fd458df967 100644 --- a/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java +++ b/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java @@ -1,115 +1,115 @@ -/* ==================================================================== - 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.aggregates; - -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RecordBase; - -/** - * RecordAggregates are groups of of BIFF Records that are typically stored - * together and/or updated together. Workbook / Sheet records are typically stored in a sequential - * list, which does not provide much structure to coordinate updates. - * - * @author Josh Micich - */ -public abstract class RecordAggregate extends RecordBase { - - /** - * Visit each of the atomic BIFF records contained in this {@link RecordAggregate} in the order - * that they should be written to file. Implementors may or may not return the actual - * {@link Record}s being used to manage POI's internal implementation. Callers should not - * assume either way, and therefore only attempt to modify those {@link Record}s after cloning - */ - public abstract void visitContainedRecords(RecordVisitor rv); - - public final int serialize(int offset, byte[] data) { - SerializingRecordVisitor srv = new SerializingRecordVisitor(data, offset); - visitContainedRecords(srv); - return srv.countBytesWritten(); - } - public int getRecordSize() { - RecordSizingVisitor rsv = new RecordSizingVisitor(); - visitContainedRecords(rsv); - return rsv.getTotalSize(); - } - - public interface RecordVisitor { - /** - * Implementors may call non-mutating methods on Record r. - * @param r must not be null - */ - void visitRecord(Record r); - } - - private static final class SerializingRecordVisitor implements RecordVisitor { - - private final byte[] _data; - private final int _startOffset; - private int _countBytesWritten; - - public SerializingRecordVisitor(byte[] data, int startOffset) { - _data = data; - _startOffset = startOffset; - _countBytesWritten = 0; - } - public int countBytesWritten() { - return _countBytesWritten; - } - public void visitRecord(Record r) { - int currentOffset = _startOffset + _countBytesWritten; - _countBytesWritten += r.serialize(currentOffset, _data); - } - } - private static final class RecordSizingVisitor implements RecordVisitor { - - private int _totalSize; - - public RecordSizingVisitor() { - _totalSize = 0; - } - public int getTotalSize() { - return _totalSize; - } - public void visitRecord(Record r) { - _totalSize += r.getRecordSize(); - } - } - /** - * A wrapper for {@link RecordVisitor} which accumulates the sizes of all - * records visited. - */ - public static final class PositionTrackingVisitor implements RecordVisitor { - private final RecordVisitor _rv; - private int _position; - - public PositionTrackingVisitor(RecordVisitor rv, int initialPosition) { - _rv = rv; - _position = initialPosition; - } - public void visitRecord(Record r) { - _position += r.getRecordSize(); - _rv.visitRecord(r); - } - public void setPosition(int position) { - _position = position; - } - public int getPosition() { - return _position; - } - } -} +/* ==================================================================== + 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.aggregates; + +import org.apache.poi.hssf.record.Record; +import org.apache.poi.hssf.record.RecordBase; + +/** + * RecordAggregates are groups of of BIFF Records that are typically stored + * together and/or updated together. Workbook / Sheet records are typically stored in a sequential + * list, which does not provide much structure to coordinate updates. + * + * @author Josh Micich + */ +public abstract class RecordAggregate extends RecordBase { + + /** + * Visit each of the atomic BIFF records contained in this {@link RecordAggregate} in the order + * that they should be written to file. Implementors may or may not return the actual + * {@link Record}s being used to manage POI's internal implementation. Callers should not + * assume either way, and therefore only attempt to modify those {@link Record}s after cloning + */ + public abstract void visitContainedRecords(RecordVisitor rv); + + public final int serialize(int offset, byte[] data) { + SerializingRecordVisitor srv = new SerializingRecordVisitor(data, offset); + visitContainedRecords(srv); + return srv.countBytesWritten(); + } + public int getRecordSize() { + RecordSizingVisitor rsv = new RecordSizingVisitor(); + visitContainedRecords(rsv); + return rsv.getTotalSize(); + } + + public interface RecordVisitor { + /** + * Implementors may call non-mutating methods on Record r. + * @param r must not be null + */ + void visitRecord(Record r); + } + + private static final class SerializingRecordVisitor implements RecordVisitor { + + private final byte[] _data; + private final int _startOffset; + private int _countBytesWritten; + + public SerializingRecordVisitor(byte[] data, int startOffset) { + _data = data; + _startOffset = startOffset; + _countBytesWritten = 0; + } + public int countBytesWritten() { + return _countBytesWritten; + } + public void visitRecord(Record r) { + int currentOffset = _startOffset + _countBytesWritten; + _countBytesWritten += r.serialize(currentOffset, _data); + } + } + private static final class RecordSizingVisitor implements RecordVisitor { + + private int _totalSize; + + public RecordSizingVisitor() { + _totalSize = 0; + } + public int getTotalSize() { + return _totalSize; + } + public void visitRecord(Record r) { + _totalSize += r.getRecordSize(); + } + } + /** + * A wrapper for {@link RecordVisitor} which accumulates the sizes of all + * records visited. + */ + public static final class PositionTrackingVisitor implements RecordVisitor { + private final RecordVisitor _rv; + private int _position; + + public PositionTrackingVisitor(RecordVisitor rv, int initialPosition) { + _rv = rv; + _position = initialPosition; + } + public void visitRecord(Record r) { + _position += r.getRecordSize(); + _rv.visitRecord(r); + } + public void setPosition(int position) { + _position = position; + } + public int getPosition() { + return _position; + } + } +} diff --git a/src/java/org/apache/poi/hssf/record/cont/ContinuableRecord.java b/src/java/org/apache/poi/hssf/record/cont/ContinuableRecord.java index 01fedd0294..3048054418 100644 --- a/src/java/org/apache/poi/hssf/record/cont/ContinuableRecord.java +++ b/src/java/org/apache/poi/hssf/record/cont/ContinuableRecord.java @@ -1,69 +1,69 @@ -/* ==================================================================== - 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.hssf.record.Record; -import org.apache.poi.util.LittleEndianByteArrayOutputStream; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Common superclass of all records that can produce {@link ContinueRecord}s while being serialized. - * - * @author Josh Micich - */ -public abstract class ContinuableRecord extends Record { - - protected ContinuableRecord() { - // no fields to initialise - } - /** - * Serializes this record's content to the supplied data output.
- * The standard BIFF header (ushort sid, ushort size) has been handled by the superclass, so - * only BIFF data should be written by this method. Simple data types can be written with the - * standard {@link LittleEndianOutput} methods. Methods from {@link ContinuableRecordOutput} - * can be used to serialize strings (with {@link ContinueRecord}s being written as required). - * If necessary, implementors can explicitly start {@link ContinueRecord}s (regardless of the - * amount of remaining space). - * - * @param out a data output stream - */ - protected abstract void serialize(ContinuableRecordOutput out); - - - /** - * @return the total length of the encoded record(s) - * (Note - if any {@link ContinueRecord} is required, this result includes the - * size of those too) - */ - public final int getRecordSize() { - ContinuableRecordOutput out = ContinuableRecordOutput.createForCountingOnly(); - serialize(out); - out.terminate(); - return out.getTotalSize(); - } - - public final int serialize(int offset, byte[] data) { - - LittleEndianOutput leo = new LittleEndianByteArrayOutputStream(data, offset); - ContinuableRecordOutput out = new ContinuableRecordOutput(leo, getSid()); - serialize(out); - out.terminate(); - return out.getTotalSize(); - } -} +/* ==================================================================== + 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.hssf.record.Record; +import org.apache.poi.util.LittleEndianByteArrayOutputStream; +import org.apache.poi.util.LittleEndianOutput; + +/** + * Common superclass of all records that can produce {@link ContinueRecord}s while being serialized. + * + * @author Josh Micich + */ +public abstract class ContinuableRecord extends Record { + + protected ContinuableRecord() { + // no fields to initialise + } + /** + * Serializes this record's content to the supplied data output.
+ * The standard BIFF header (ushort sid, ushort size) has been handled by the superclass, so + * only BIFF data should be written by this method. Simple data types can be written with the + * standard {@link LittleEndianOutput} methods. Methods from {@link ContinuableRecordOutput} + * can be used to serialize strings (with {@link ContinueRecord}s being written as required). + * If necessary, implementors can explicitly start {@link ContinueRecord}s (regardless of the + * amount of remaining space). + * + * @param out a data output stream + */ + protected abstract void serialize(ContinuableRecordOutput out); + + + /** + * @return the total length of the encoded record(s) + * (Note - if any {@link ContinueRecord} is required, this result includes the + * size of those too) + */ + public final int getRecordSize() { + ContinuableRecordOutput out = ContinuableRecordOutput.createForCountingOnly(); + serialize(out); + out.terminate(); + return out.getTotalSize(); + } + + public final int serialize(int offset, byte[] data) { + + LittleEndianOutput leo = new LittleEndianByteArrayOutputStream(data, offset); + ContinuableRecordOutput out = new ContinuableRecordOutput(leo, getSid()); + serialize(out); + out.terminate(); + return out.getTotalSize(); + } +} diff --git a/src/java/org/apache/poi/hssf/record/cont/ContinuableRecordOutput.java b/src/java/org/apache/poi/hssf/record/cont/ContinuableRecordOutput.java index 5d540365b7..26946c7cca 100644 --- a/src/java/org/apache/poi/hssf/record/cont/ContinuableRecordOutput.java +++ b/src/java/org/apache/poi/hssf/record/cont/ContinuableRecordOutput.java @@ -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: - *

- * - * Notes: - * - */ - 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: - * - * - * The following bits of the 'optionFlags' byte will be set as appropriate: - * - * - * - * - * - *
MaskDescription
0x01is16bitEncoded
0x04hasExtendedData
0x08isRichText
- * Notes: - * - */ - 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: + * + * + * Notes: + * + */ + 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: + * + * + * The following bits of the 'optionFlags' byte will be set as appropriate: + * + * + * + * + * + *
MaskDescription
0x01is16bitEncoded
0x04hasExtendedData
0x08isRichText
+ * Notes: + * + */ + 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 + } + }; +} diff --git a/src/java/org/apache/poi/hssf/record/cont/UnknownLengthRecordOutput.java b/src/java/org/apache/poi/hssf/record/cont/UnknownLengthRecordOutput.java index 9209566c23..322a5208fc 100644 --- a/src/java/org/apache/poi/hssf/record/cont/UnknownLengthRecordOutput.java +++ b/src/java/org/apache/poi/hssf/record/cont/UnknownLengthRecordOutput.java @@ -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.
- * 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.
+ * 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; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java b/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java index 57f2c919db..6383bb0661 100644 --- a/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java +++ b/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java @@ -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(); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/RefPtg.java b/src/java/org/apache/poi/hssf/record/formula/RefPtg.java index 859d0ff0a0..68b96d9bf5 100644 --- a/src/java/org/apache/poi/hssf/record/formula/RefPtg.java +++ b/src/java/org/apache/poi/hssf/record/formula/RefPtg.java @@ -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; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/ScalarConstantPtg.java b/src/java/org/apache/poi/hssf/record/formula/ScalarConstantPtg.java index 869e38d2e0..b36f4978e2 100644 --- a/src/java/org/apache/poi/hssf/record/formula/ScalarConstantPtg.java +++ b/src/java/org/apache/poi/hssf/record/formula/ScalarConstantPtg.java @@ -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(); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/RefEvalBase.java b/src/java/org/apache/poi/hssf/record/formula/eval/RefEvalBase.java index 6012e1b983..32cdc72e17 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/RefEvalBase.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/RefEvalBase.java @@ -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; + } +} diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java index 10805658a7..968daef664 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java @@ -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. -1 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. -1 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; + } +} diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java index aa1a0a5d04..a49fb9c684 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java @@ -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.

- * - * 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 null - * 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 null signifying that the cell is not present (or blank) - * @return null if the supplied cell is null 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 formula result is returned, so you know what kind of - * cached formula result is also stored with the formula. - *

-	 * int evaluatedCellType = evaluator.evaluateFormulaCell(cell);
-	 * 
- * Be aware that your cell will hold both the formula, and the result. If you want the cell - * replaced with the result of the formula, use {@link #evaluateInCell(org.apache.poi.ss.usermodel.Cell)} - * @param cell The cell to evaluate - * @return -1 for non-formula cells, or the type of the formula result - */ - 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: - *
-	 * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
-	 * 
- * Be aware that your cell value will be changed to hold the - * result of the formula. If you simply want the formula - * value computed for you, use {@link #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 + * + * 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 null + * 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 null signifying that the cell is not present (or blank) + * @return null if the supplied cell is null 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 formula result is returned, so you know what kind of + * cached formula result is also stored with the formula. + *
+	 * int evaluatedCellType = evaluator.evaluateFormulaCell(cell);
+	 * 
+ * Be aware that your cell will hold both the formula, and the result. If you want the cell + * replaced with the result of the formula, use {@link #evaluateInCell(org.apache.poi.ss.usermodel.Cell)} + * @param cell The cell to evaluate + * @return -1 for non-formula cells, or the type of the formula result + */ + 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: + *
+	 * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
+	 * 
+ * Be aware that your cell value will be changed to hold the + * result of the formula. If you simply want the formula + * value computed for you, use {@link #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 rit = sheet.rowIterator(); rit.hasNext();) { + Row r = rit.next(); + + for (Iterator 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() + ")"); + } +} diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java b/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java index 590e706b8b..9a812914d5 100755 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java @@ -1,220 +1,220 @@ -/* ==================================================================== - 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.record.HyperlinkRecord; -import org.apache.poi.ss.usermodel.Hyperlink; - -/** - * Represents an Excel hyperlink. - * - * @author Yegor Kozlov (yegor at apache dot org) - */ -public class HSSFHyperlink implements Hyperlink { - - /** - * Link to a existing file or web page - */ - public static final int LINK_URL = 1; - - /** - * Link to a place in this document - */ - public static final int LINK_DOCUMENT = 2; - - /** - * Link to an E-mail address - */ - public static final int LINK_EMAIL = 3; - - /** - * Link to a file - */ - public static final int LINK_FILE = 4; - - /** - * Low-level record object that stores the actual hyperlink data - */ - protected HyperlinkRecord record = null; - - /** - * If we create a new hypelrink remember its type - */ - protected int link_type; - - /** - * Construct a new hyperlink - * - * @param type the type of hyperlink to create - */ - public HSSFHyperlink( int type ) - { - this.link_type = type; - record = new HyperlinkRecord(); - switch(type){ - case LINK_URL: - case LINK_EMAIL: - record.newUrlLink(); - break; - case LINK_FILE: - record.newFileLink(); - break; - case LINK_DOCUMENT: - record.newDocumentLink(); - break; - } - } - - /** - * Initialize the hyperlink by a HyperlinkRecord record - * - * @param record - */ - protected HSSFHyperlink( HyperlinkRecord record ) - { - this.record = record; - } - - /** - * Return the row of the first cell that contains the hyperlink - * - * @return the 0-based row of the cell that contains the hyperlink - */ - public int getFirstRow(){ - return record.getFirstRow(); - } - - /** - * Set the row of the first cell that contains the hyperlink - * - * @param row the 0-based row of the first cell that contains the hyperlink - */ - public void setFirstRow(int row){ - record.setFirstRow(row); - } - - /** - * Return the row of the last cell that contains the hyperlink - * - * @return the 0-based row of the last cell that contains the hyperlink - */ - public int getLastRow(){ - return record.getLastRow(); - } - - /** - * Set the row of the last cell that contains the hyperlink - * - * @param row the 0-based row of the last cell that contains the hyperlink - */ - public void setLastRow(int row){ - record.setLastRow(row); - } - - /** - * Return the column of the first cell that contains the hyperlink - * - * @return the 0-based column of the first cell that contains the hyperlink - */ - public int getFirstColumn(){ - return record.getFirstColumn(); - } - - /** - * Set the column of the first cell that contains the hyperlink - * - * @param col the 0-based column of the first cell that contains the hyperlink - */ - public void setFirstColumn(int col){ - record.setFirstColumn((short)col); - } - - /** - * Return the column of the last cell that contains the hyperlink - * - * @return the 0-based column of the last cell that contains the hyperlink - */ - public int getLastColumn(){ - return record.getLastColumn(); - } - - /** - * Set the column of the last cell that contains the hyperlink - * - * @param col the 0-based column of the last cell that contains the hyperlink - */ - public void setLastColumn(int col){ - record.setLastColumn((short)col); - } - - /** - * Hypelink address. Depending on the hyperlink type it can be URL, e-mail, patrh to a file, etc. - * - * @return the address of this hyperlink - */ - public String getAddress(){ - return record.getAddress(); - } - public String getTextMark(){ - return record.getTextMark(); - } - public void setTextMark(String textMark) { - record.setTextMark(textMark); - } - public String getShortFilename(){ - return record.getShortFilename(); - } - public void setShortFilename(String shortFilename) { - record.setShortFilename(shortFilename); - } - - /** - * Hypelink address. Depending on the hyperlink type it can be URL, e-mail, patrh to a file, etc. - * - * @param address the address of this hyperlink - */ - public void setAddress(String address){ - record.setAddress(address); - } - - /** - * Return text label for this hyperlink - * - * @return text to display - */ - public String getLabel(){ - return record.getLabel(); - } - - /** - * Sets text label for this hyperlink - * - * @param label text label for this hyperlink - */ - public void setLabel(String label){ - record.setLabel(label); - } - - /** - * Return the type of this hyperlink - * - * @return the type of this hyperlink - */ - public int getType(){ - return link_type; - } -} +/* ==================================================================== + 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.record.HyperlinkRecord; +import org.apache.poi.ss.usermodel.Hyperlink; + +/** + * Represents an Excel hyperlink. + * + * @author Yegor Kozlov (yegor at apache dot org) + */ +public class HSSFHyperlink implements Hyperlink { + + /** + * Link to a existing file or web page + */ + public static final int LINK_URL = 1; + + /** + * Link to a place in this document + */ + public static final int LINK_DOCUMENT = 2; + + /** + * Link to an E-mail address + */ + public static final int LINK_EMAIL = 3; + + /** + * Link to a file + */ + public static final int LINK_FILE = 4; + + /** + * Low-level record object that stores the actual hyperlink data + */ + protected HyperlinkRecord record = null; + + /** + * If we create a new hypelrink remember its type + */ + protected int link_type; + + /** + * Construct a new hyperlink + * + * @param type the type of hyperlink to create + */ + public HSSFHyperlink( int type ) + { + this.link_type = type; + record = new HyperlinkRecord(); + switch(type){ + case LINK_URL: + case LINK_EMAIL: + record.newUrlLink(); + break; + case LINK_FILE: + record.newFileLink(); + break; + case LINK_DOCUMENT: + record.newDocumentLink(); + break; + } + } + + /** + * Initialize the hyperlink by a HyperlinkRecord record + * + * @param record + */ + protected HSSFHyperlink( HyperlinkRecord record ) + { + this.record = record; + } + + /** + * Return the row of the first cell that contains the hyperlink + * + * @return the 0-based row of the cell that contains the hyperlink + */ + public int getFirstRow(){ + return record.getFirstRow(); + } + + /** + * Set the row of the first cell that contains the hyperlink + * + * @param row the 0-based row of the first cell that contains the hyperlink + */ + public void setFirstRow(int row){ + record.setFirstRow(row); + } + + /** + * Return the row of the last cell that contains the hyperlink + * + * @return the 0-based row of the last cell that contains the hyperlink + */ + public int getLastRow(){ + return record.getLastRow(); + } + + /** + * Set the row of the last cell that contains the hyperlink + * + * @param row the 0-based row of the last cell that contains the hyperlink + */ + public void setLastRow(int row){ + record.setLastRow(row); + } + + /** + * Return the column of the first cell that contains the hyperlink + * + * @return the 0-based column of the first cell that contains the hyperlink + */ + public int getFirstColumn(){ + return record.getFirstColumn(); + } + + /** + * Set the column of the first cell that contains the hyperlink + * + * @param col the 0-based column of the first cell that contains the hyperlink + */ + public void setFirstColumn(int col){ + record.setFirstColumn((short)col); + } + + /** + * Return the column of the last cell that contains the hyperlink + * + * @return the 0-based column of the last cell that contains the hyperlink + */ + public int getLastColumn(){ + return record.getLastColumn(); + } + + /** + * Set the column of the last cell that contains the hyperlink + * + * @param col the 0-based column of the last cell that contains the hyperlink + */ + public void setLastColumn(int col){ + record.setLastColumn((short)col); + } + + /** + * Hypelink address. Depending on the hyperlink type it can be URL, e-mail, patrh to a file, etc. + * + * @return the address of this hyperlink + */ + public String getAddress(){ + return record.getAddress(); + } + public String getTextMark(){ + return record.getTextMark(); + } + public void setTextMark(String textMark) { + record.setTextMark(textMark); + } + public String getShortFilename(){ + return record.getShortFilename(); + } + public void setShortFilename(String shortFilename) { + record.setShortFilename(shortFilename); + } + + /** + * Hypelink address. Depending on the hyperlink type it can be URL, e-mail, patrh to a file, etc. + * + * @param address the address of this hyperlink + */ + public void setAddress(String address){ + record.setAddress(address); + } + + /** + * Return text label for this hyperlink + * + * @return text to display + */ + public String getLabel(){ + return record.getLabel(); + } + + /** + * Sets text label for this hyperlink + * + * @param label text label for this hyperlink + */ + public void setLabel(String label){ + record.setLabel(label); + } + + /** + * Return the type of this hyperlink + * + * @return the type of this hyperlink + */ + public int getType(){ + return link_type; + } +} diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java index ce6235a1af..ab539c22de 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java @@ -1,194 +1,193 @@ -/* ==================================================================== - 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.Sheet; -import org.apache.poi.hssf.record.CFRuleRecord; -import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate; -import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable; -import org.apache.poi.ss.util.Region; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.SpreadsheetVersion; - -/** - * The 'Conditional Formatting' facet of HSSFSheet - * - * @author Dmitriy Kumshayev - */ -public final class HSSFSheetConditionalFormatting { - - private final HSSFSheet _sheet; - private final ConditionalFormattingTable _conditionalFormattingTable; - - /* package */ HSSFSheetConditionalFormatting(HSSFSheet sheet) { - _sheet = sheet; - _conditionalFormattingTable = sheet.getSheet().getConditionalFormattingTable(); - } - - /** - * A factory method allowing to create a conditional formatting rule - * with a cell comparison operator

- * TODO - formulas containing cell references are currently not parsed properly - * - * @param comparisonOperation - a constant value from - * {@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator}:

- *

    - *
  • BETWEEN
  • - *
  • NOT_BETWEEN
  • - *
  • EQUAL
  • - *
  • NOT_EQUAL
  • - *
  • GT
  • - *
  • LT
  • - *
  • GE
  • - *
  • LE
  • - *
- *

- * @param formula1 - formula for the valued, compared with the cell - * @param formula2 - second formula (only used with - * {@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator#BETWEEN}) and - * {@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator#NOT_BETWEEN} operations) - */ - public HSSFConditionalFormattingRule createConditionalFormattingRule( - byte comparisonOperation, - String formula1, - String formula2) { - - HSSFWorkbook wb = _sheet.getWorkbook(); - CFRuleRecord rr = CFRuleRecord.create(_sheet, comparisonOperation, formula1, formula2); - return new HSSFConditionalFormattingRule(wb, rr); - } - - /** - * A factory method allowing to create a conditional formatting rule with a formula.
- * - * The formatting rules are applied by Excel when the value of the formula not equal to 0.

- * TODO - formulas containing cell references are currently not parsed properly - * @param formula - formula for the valued, compared with the cell - */ - public HSSFConditionalFormattingRule createConditionalFormattingRule(String formula) { - HSSFWorkbook wb = _sheet.getWorkbook(); - CFRuleRecord rr = CFRuleRecord.create(_sheet, formula); - return new HSSFConditionalFormattingRule(wb, rr); - } - - /** - * Adds a copy of HSSFConditionalFormatting object to the sheet - *

This method could be used to copy HSSFConditionalFormatting object - * from one sheet to another. For example: - *

-	 * HSSFConditionalFormatting cf = sheet.getConditionalFormattingAt(index);
-	 * newSheet.addConditionalFormatting(cf);
-	 * 
- * - * @param cf HSSFConditionalFormatting object - * @return index of the new Conditional Formatting object - */ - public int addConditionalFormatting( HSSFConditionalFormatting cf ) { - CFRecordsAggregate cfraClone = cf.getCFRecordsAggregate().cloneCFAggregate(); - - return _conditionalFormattingTable.add(cfraClone); - } - /** - * @deprecated use CellRangeAddress instead of Region - */ - public int addConditionalFormatting(Region[] regions, HSSFConditionalFormattingRule[] cfRules) { - return addConditionalFormatting(Region.convertRegionsToCellRanges(regions), cfRules); - } - /** - * Allows to add a new Conditional Formatting set to the sheet. - * - * @param regions - list of rectangular regions to apply conditional formatting rules - * @param cfRules - set of up to three conditional formatting rules - * - * @return index of the newly created Conditional Formatting object - */ - public int addConditionalFormatting(CellRangeAddress[] regions, HSSFConditionalFormattingRule[] cfRules) { - if (regions == null) { - throw new IllegalArgumentException("regions must not be null"); - } - for(CellRangeAddress range : regions) range.validate(SpreadsheetVersion.EXCEL97); - - if (cfRules == null) { - throw new IllegalArgumentException("cfRules must not be null"); - } - if (cfRules.length == 0) { - throw new IllegalArgumentException("cfRules must not be empty"); - } - if (cfRules.length > 3) { - throw new IllegalArgumentException("Number of rules must not exceed 3"); - } - - CFRuleRecord[] rules = new CFRuleRecord[cfRules.length]; - for (int i = 0; i != cfRules.length; i++) { - rules[i] = cfRules[i].getCfRuleRecord(); - } - CFRecordsAggregate cfra = new CFRecordsAggregate(regions, rules); - return _conditionalFormattingTable.add(cfra); - } - - public int addConditionalFormatting(CellRangeAddress[] regions, - HSSFConditionalFormattingRule rule1) - { - return addConditionalFormatting(regions, - new HSSFConditionalFormattingRule[] - { - rule1 - }); - } - - public int addConditionalFormatting(CellRangeAddress[] regions, - HSSFConditionalFormattingRule rule1, - HSSFConditionalFormattingRule rule2) - { - return addConditionalFormatting(regions, - new HSSFConditionalFormattingRule[] - { - rule1, rule2 - }); - } - - /** - * gets Conditional Formatting object at a particular index - * - * @param index - * of the Conditional Formatting object to fetch - * @return Conditional Formatting object - */ - public HSSFConditionalFormatting getConditionalFormattingAt(int index) { - CFRecordsAggregate cf = _conditionalFormattingTable.get(index); - if (cf == null) { - return null; - } - return new HSSFConditionalFormatting(_sheet.getWorkbook(), cf); - } - - /** - * @return number of Conditional Formatting objects of the sheet - */ - public int getNumConditionalFormattings() { - return _conditionalFormattingTable.size(); - } - - /** - * removes a Conditional Formatting object by index - * @param index of a Conditional Formatting object to remove - */ - public void removeConditionalFormatting(int index) { - _conditionalFormattingTable.remove(index); - } -} +/* ==================================================================== + 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.record.CFRuleRecord; +import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate; +import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable; +import org.apache.poi.ss.util.Region; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.SpreadsheetVersion; + +/** + * The 'Conditional Formatting' facet of HSSFSheet + * + * @author Dmitriy Kumshayev + */ +public final class HSSFSheetConditionalFormatting { + + private final HSSFSheet _sheet; + private final ConditionalFormattingTable _conditionalFormattingTable; + + /* package */ HSSFSheetConditionalFormatting(HSSFSheet sheet) { + _sheet = sheet; + _conditionalFormattingTable = sheet.getSheet().getConditionalFormattingTable(); + } + + /** + * A factory method allowing to create a conditional formatting rule + * with a cell comparison operator

+ * TODO - formulas containing cell references are currently not parsed properly + * + * @param comparisonOperation - a constant value from + * {@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator}:

+ *

    + *
  • BETWEEN
  • + *
  • NOT_BETWEEN
  • + *
  • EQUAL
  • + *
  • NOT_EQUAL
  • + *
  • GT
  • + *
  • LT
  • + *
  • GE
  • + *
  • LE
  • + *
+ *

+ * @param formula1 - formula for the valued, compared with the cell + * @param formula2 - second formula (only used with + * {@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator#BETWEEN}) and + * {@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator#NOT_BETWEEN} operations) + */ + public HSSFConditionalFormattingRule createConditionalFormattingRule( + byte comparisonOperation, + String formula1, + String formula2) { + + HSSFWorkbook wb = _sheet.getWorkbook(); + CFRuleRecord rr = CFRuleRecord.create(_sheet, comparisonOperation, formula1, formula2); + return new HSSFConditionalFormattingRule(wb, rr); + } + + /** + * A factory method allowing to create a conditional formatting rule with a formula.
+ * + * The formatting rules are applied by Excel when the value of the formula not equal to 0.

+ * TODO - formulas containing cell references are currently not parsed properly + * @param formula - formula for the valued, compared with the cell + */ + public HSSFConditionalFormattingRule createConditionalFormattingRule(String formula) { + HSSFWorkbook wb = _sheet.getWorkbook(); + CFRuleRecord rr = CFRuleRecord.create(_sheet, formula); + return new HSSFConditionalFormattingRule(wb, rr); + } + + /** + * Adds a copy of HSSFConditionalFormatting object to the sheet + *

This method could be used to copy HSSFConditionalFormatting object + * from one sheet to another. For example: + *

+	 * HSSFConditionalFormatting cf = sheet.getConditionalFormattingAt(index);
+	 * newSheet.addConditionalFormatting(cf);
+	 * 
+ * + * @param cf HSSFConditionalFormatting object + * @return index of the new Conditional Formatting object + */ + public int addConditionalFormatting( HSSFConditionalFormatting cf ) { + CFRecordsAggregate cfraClone = cf.getCFRecordsAggregate().cloneCFAggregate(); + + return _conditionalFormattingTable.add(cfraClone); + } + /** + * @deprecated use CellRangeAddress instead of Region + */ + public int addConditionalFormatting(Region[] regions, HSSFConditionalFormattingRule[] cfRules) { + return addConditionalFormatting(Region.convertRegionsToCellRanges(regions), cfRules); + } + /** + * Allows to add a new Conditional Formatting set to the sheet. + * + * @param regions - list of rectangular regions to apply conditional formatting rules + * @param cfRules - set of up to three conditional formatting rules + * + * @return index of the newly created Conditional Formatting object + */ + public int addConditionalFormatting(CellRangeAddress[] regions, HSSFConditionalFormattingRule[] cfRules) { + if (regions == null) { + throw new IllegalArgumentException("regions must not be null"); + } + for(CellRangeAddress range : regions) range.validate(SpreadsheetVersion.EXCEL97); + + if (cfRules == null) { + throw new IllegalArgumentException("cfRules must not be null"); + } + if (cfRules.length == 0) { + throw new IllegalArgumentException("cfRules must not be empty"); + } + if (cfRules.length > 3) { + throw new IllegalArgumentException("Number of rules must not exceed 3"); + } + + CFRuleRecord[] rules = new CFRuleRecord[cfRules.length]; + for (int i = 0; i != cfRules.length; i++) { + rules[i] = cfRules[i].getCfRuleRecord(); + } + CFRecordsAggregate cfra = new CFRecordsAggregate(regions, rules); + return _conditionalFormattingTable.add(cfra); + } + + public int addConditionalFormatting(CellRangeAddress[] regions, + HSSFConditionalFormattingRule rule1) + { + return addConditionalFormatting(regions, + new HSSFConditionalFormattingRule[] + { + rule1 + }); + } + + public int addConditionalFormatting(CellRangeAddress[] regions, + HSSFConditionalFormattingRule rule1, + HSSFConditionalFormattingRule rule2) + { + return addConditionalFormatting(regions, + new HSSFConditionalFormattingRule[] + { + rule1, rule2 + }); + } + + /** + * gets Conditional Formatting object at a particular index + * + * @param index + * of the Conditional Formatting object to fetch + * @return Conditional Formatting object + */ + public HSSFConditionalFormatting getConditionalFormattingAt(int index) { + CFRecordsAggregate cf = _conditionalFormattingTable.get(index); + if (cf == null) { + return null; + } + return new HSSFConditionalFormatting(_sheet.getWorkbook(), cf); + } + + /** + * @return number of Conditional Formatting objects of the sheet + */ + public int getNumConditionalFormattings() { + return _conditionalFormattingTable.size(); + } + + /** + * removes a Conditional Formatting object by index + * @param index of a Conditional Formatting object to remove + */ + public void removeConditionalFormatting(int index) { + _conditionalFormattingTable.remove(index); + } +} diff --git a/src/java/org/apache/poi/hssf/util/CellRangeAddress.java b/src/java/org/apache/poi/hssf/util/CellRangeAddress.java index da8d56c091..d2316fe884 100644 --- a/src/java/org/apache/poi/hssf/util/CellRangeAddress.java +++ b/src/java/org/apache/poi/hssf/util/CellRangeAddress.java @@ -1,38 +1,38 @@ -/* ==================================================================== - 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.util; - -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.SelectionRecord; - -/** - * See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'

- * - * Note - {@link SelectionRecord} uses the BIFF5 version of this structure - * @deprecated use {@link org.apache.poi.ss.util.CellRangeAddress} - * @author Dragos Buleandra (dragos.buleandra@trade2b.ro) - */ -public class CellRangeAddress extends org.apache.poi.ss.util.CellRangeAddress { - - public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) { - super(firstRow, lastRow, firstCol, lastCol); - } - public CellRangeAddress(RecordInputStream in) { - super(in); - } -} +/* ==================================================================== + 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.util; + +import org.apache.poi.hssf.record.RecordInputStream; +import org.apache.poi.hssf.record.SelectionRecord; + +/** + * See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'

+ * + * Note - {@link SelectionRecord} uses the BIFF5 version of this structure + * @deprecated use {@link org.apache.poi.ss.util.CellRangeAddress} + * @author Dragos Buleandra (dragos.buleandra@trade2b.ro) + */ +public class CellRangeAddress extends org.apache.poi.ss.util.CellRangeAddress { + + public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) { + super(firstRow, lastRow, firstCol, lastCol); + } + public CellRangeAddress(RecordInputStream in) { + super(in); + } +} diff --git a/src/java/org/apache/poi/hssf/util/CellRangeAddress8Bit.java b/src/java/org/apache/poi/hssf/util/CellRangeAddress8Bit.java index 43de0cf28a..cada8bfe5b 100644 --- a/src/java/org/apache/poi/hssf/util/CellRangeAddress8Bit.java +++ b/src/java/org/apache/poi/hssf/util/CellRangeAddress8Bit.java @@ -1,73 +1,73 @@ -/* ==================================================================== - 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.util; - -import org.apache.poi.ss.util.CellRangeAddressBase; -import org.apache.poi.util.LittleEndianByteArrayOutputStream; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'

- * - * Like {@link CellRangeAddress} except column fields are 8-bit. - * - * @author Josh Micich - */ -public final class CellRangeAddress8Bit extends CellRangeAddressBase { - - public static final int ENCODED_SIZE = 6; - - public CellRangeAddress8Bit(int firstRow, int lastRow, int firstCol, int lastCol) { - super(firstRow, lastRow, firstCol, lastCol); - } - - public CellRangeAddress8Bit(LittleEndianInput in) { - super(readUShortAndCheck(in), in.readUShort(), in.readUByte(), in.readUByte()); - } - - private static int readUShortAndCheck(LittleEndianInput in) { - if (in.available() < ENCODED_SIZE) { - // Ran out of data - throw new RuntimeException("Ran out of data reading CellRangeAddress"); - } - return in.readUShort(); - } - - /** - * @deprecated use {@link #serialize(LittleEndianOutput)} - */ - public int serialize(int offset, byte[] data) { - serialize(new LittleEndianByteArrayOutputStream(data, offset, ENCODED_SIZE)); - return ENCODED_SIZE; - } - public void serialize(LittleEndianOutput out) { - out.writeShort(getFirstRow()); - out.writeShort(getLastRow()); - out.writeByte(getFirstColumn()); - out.writeByte(getLastColumn()); - } - - public CellRangeAddress8Bit copy() { - return new CellRangeAddress8Bit(getFirstRow(), getLastRow(), getFirstColumn(), getLastColumn()); - } - - public static int getEncodedSize(int numberOfItems) { - return numberOfItems * ENCODED_SIZE; - } -} +/* ==================================================================== + 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.util; + +import org.apache.poi.ss.util.CellRangeAddressBase; +import org.apache.poi.util.LittleEndianByteArrayOutputStream; +import org.apache.poi.util.LittleEndianInput; +import org.apache.poi.util.LittleEndianOutput; + +/** + * See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'

+ * + * Like {@link CellRangeAddress} except column fields are 8-bit. + * + * @author Josh Micich + */ +public final class CellRangeAddress8Bit extends CellRangeAddressBase { + + public static final int ENCODED_SIZE = 6; + + public CellRangeAddress8Bit(int firstRow, int lastRow, int firstCol, int lastCol) { + super(firstRow, lastRow, firstCol, lastCol); + } + + public CellRangeAddress8Bit(LittleEndianInput in) { + super(readUShortAndCheck(in), in.readUShort(), in.readUByte(), in.readUByte()); + } + + private static int readUShortAndCheck(LittleEndianInput in) { + if (in.available() < ENCODED_SIZE) { + // Ran out of data + throw new RuntimeException("Ran out of data reading CellRangeAddress"); + } + return in.readUShort(); + } + + /** + * @deprecated use {@link #serialize(LittleEndianOutput)} + */ + public int serialize(int offset, byte[] data) { + serialize(new LittleEndianByteArrayOutputStream(data, offset, ENCODED_SIZE)); + return ENCODED_SIZE; + } + public void serialize(LittleEndianOutput out) { + out.writeShort(getFirstRow()); + out.writeShort(getLastRow()); + out.writeByte(getFirstColumn()); + out.writeByte(getLastColumn()); + } + + public CellRangeAddress8Bit copy() { + return new CellRangeAddress8Bit(getFirstRow(), getLastRow(), getFirstColumn(), getLastColumn()); + } + + public static int getEncodedSize(int numberOfItems) { + return numberOfItems * ENCODED_SIZE; + } +} diff --git a/src/java/org/apache/poi/poifs/dev/POIFSDump.java b/src/java/org/apache/poi/poifs/dev/POIFSDump.java index 5028bab720..ace19d8d18 100755 --- a/src/java/org/apache/poi/poifs/dev/POIFSDump.java +++ b/src/java/org/apache/poi/poifs/dev/POIFSDump.java @@ -1,74 +1,74 @@ -/* ==================================================================== - 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.poifs.dev; - -import org.apache.poi.poifs.filesystem.*; - -import java.io.FileInputStream; -import java.io.File; -import java.io.IOException; -import java.io.FileOutputStream; -import java.util.Iterator; - -/** - * - * Dump internal structure of a OLE2 file into file system - * - * @author Yegor Kozlov - */ -public class POIFSDump { - - public static void main(String[] args) throws Exception { - for (int i = 0; i < args.length; i++) { - System.out.println("Dumping " + args[i]); - FileInputStream is = new FileInputStream(args[i]); - POIFSFileSystem fs = new POIFSFileSystem(is); - is.close(); - - DirectoryEntry root = fs.getRoot(); - File file = new File(root.getName()); - file.mkdir(); - - dump(root, file); - } - } - - - public static void dump(DirectoryEntry root, File parent) throws IOException { - for(Iterator it = root.getEntries(); it.hasNext();){ - Entry entry = (Entry)it.next(); - if(entry instanceof DocumentNode){ - DocumentNode node = (DocumentNode)entry; - DocumentInputStream is = new DocumentInputStream(node); - byte[] bytes = new byte[node.getSize()]; - is.read(bytes); - is.close(); - - FileOutputStream out = new FileOutputStream(new File(parent, node.getName().trim())); - out.write(bytes); - out.close(); - } else if (entry instanceof DirectoryEntry){ - DirectoryEntry dir = (DirectoryEntry)entry; - File file = new File(parent, entry.getName()); - file.mkdir(); - dump(dir, file); - } else { - System.err.println("Skipping unsupported POIFS entry: " + entry); - } - } - } -} +/* ==================================================================== + 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.poifs.dev; + +import org.apache.poi.poifs.filesystem.*; + +import java.io.FileInputStream; +import java.io.File; +import java.io.IOException; +import java.io.FileOutputStream; +import java.util.Iterator; + +/** + * + * Dump internal structure of a OLE2 file into file system + * + * @author Yegor Kozlov + */ +public class POIFSDump { + + public static void main(String[] args) throws Exception { + for (int i = 0; i < args.length; i++) { + System.out.println("Dumping " + args[i]); + FileInputStream is = new FileInputStream(args[i]); + POIFSFileSystem fs = new POIFSFileSystem(is); + is.close(); + + DirectoryEntry root = fs.getRoot(); + File file = new File(root.getName()); + file.mkdir(); + + dump(root, file); + } + } + + + public static void dump(DirectoryEntry root, File parent) throws IOException { + for(Iterator it = root.getEntries(); it.hasNext();){ + Entry entry = (Entry)it.next(); + if(entry instanceof DocumentNode){ + DocumentNode node = (DocumentNode)entry; + DocumentInputStream is = new DocumentInputStream(node); + byte[] bytes = new byte[node.getSize()]; + is.read(bytes); + is.close(); + + FileOutputStream out = new FileOutputStream(new File(parent, node.getName().trim())); + out.write(bytes); + out.close(); + } else if (entry instanceof DirectoryEntry){ + DirectoryEntry dir = (DirectoryEntry)entry; + File file = new File(parent, entry.getName()); + file.mkdir(); + dump(dir, file); + } else { + System.err.println("Skipping unsupported POIFS entry: " + entry); + } + } + } +} diff --git a/src/java/org/apache/poi/ss/SpreadsheetVersion.java b/src/java/org/apache/poi/ss/SpreadsheetVersion.java index 4a7b2bbe4f..316e5af06f 100755 --- a/src/java/org/apache/poi/ss/SpreadsheetVersion.java +++ b/src/java/org/apache/poi/ss/SpreadsheetVersion.java @@ -1,120 +1,119 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss; - -import org.apache.poi.ss.util.CellReference; - -/** - * This enum allows spreadsheets from multiple Excel versions to be handled by the common code. - * Properties of this enum correspond to attributes of the spreadsheet that are easily - * discernable to the user. It is not intended to deal with low-level issues like file formats. - *

- * - * @author Josh Micich - * @author Yegor Kozlov - */ -public enum SpreadsheetVersion { - /** - * Excel97 format aka BIFF8 - *

    - *
  • The total number of available columns is 256 (2^8)
  • - *
  • The total number of available rows is 64k (2^16)
  • - *
  • The maximum number of arguments to a function is 30
  • - *
  • Number of conditional format conditions on a cell is 3
  • - *
- */ - EXCEL97(0x10000, 0x0100, 30, 3), - - /** - * Excel2007 - * - *
    - *
  • The total number of available columns is 16K (2^14)
  • - *
  • The total number of available rows is 1M (2^20)
  • - *
  • The maximum number of arguments to a function is 255
  • - *
  • Number of conditional format conditions on a cell is unlimited - * (actually limited by available memory in Excel)
  • - *
      - */ - EXCEL2007(0x100000, 0x4000, 255, Integer.MAX_VALUE); - - private final int _maxRows; - private final int _maxColumns; - private final int _maxFunctionArgs; - private final int _maxCondFormats; - - private SpreadsheetVersion(int maxRows, int maxColumns, int maxFunctionArgs, int maxCondFormats) { - _maxRows = maxRows; - _maxColumns = maxColumns; - _maxFunctionArgs = maxFunctionArgs; - _maxCondFormats = maxCondFormats; - } - - /** - * @return the maximum number of usable rows in each spreadsheet - */ - public int getMaxRows() { - return _maxRows; - } - - /** - * @return the last (maximum) valid row index, equals to getMaxRows() - 1 - */ - public int getLastRowIndex() { - return _maxRows - 1; - } - - /** - * @return the maximum number of usable columns in each spreadsheet - */ - public int getMaxColumns() { - return _maxColumns; - } - - /** - * @return the last (maximum) valid column index, equals to getMaxColumns() - 1 - */ - public int getLastColumnIndex() { - return _maxColumns - 1; - } - - /** - * @return the maximum number arguments that can be passed to a multi-arg - * function (e.g. COUNTIF) - */ - public int getMaxFunctionArgs() { - return _maxFunctionArgs; - } - - /** - * - * @return the maximum number of conditional format conditions on a cell - */ - public int getMaxConditionalFormats() { - return _maxCondFormats; - } - - /** - * - * @return the last valid column index in a ALPHA-26 representation - * ( IV or XFD). - */ - public String getLastColumnName() { - return CellReference.convertNumToColString(getLastColumnIndex()); - } -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss; + +import org.apache.poi.ss.util.CellReference; + +/** + * This enum allows spreadsheets from multiple Excel versions to be handled by the common code. + * Properties of this enum correspond to attributes of the spreadsheet that are easily + * discernable to the user. It is not intended to deal with low-level issues like file formats. + *

      + * + * @author Josh Micich + * @author Yegor Kozlov + */ +public enum SpreadsheetVersion { + /** + * Excel97 format aka BIFF8 + *

        + *
      • The total number of available columns is 256 (2^8)
      • + *
      • The total number of available rows is 64k (2^16)
      • + *
      • The maximum number of arguments to a function is 30
      • + *
      • Number of conditional format conditions on a cell is 3
      • + *
      + */ + EXCEL97(0x10000, 0x0100, 30, 3), + + /** + * Excel2007 + * + *
        + *
      • The total number of available columns is 16K (2^14)
      • + *
      • The total number of available rows is 1M (2^20)
      • + *
      • The maximum number of arguments to a function is 255
      • + *
      • Number of conditional format conditions on a cell is unlimited + * (actually limited by available memory in Excel)
      • + *
          + */ + EXCEL2007(0x100000, 0x4000, 255, Integer.MAX_VALUE); + + private final int _maxRows; + private final int _maxColumns; + private final int _maxFunctionArgs; + private final int _maxCondFormats; + + private SpreadsheetVersion(int maxRows, int maxColumns, int maxFunctionArgs, int maxCondFormats) { + _maxRows = maxRows; + _maxColumns = maxColumns; + _maxFunctionArgs = maxFunctionArgs; + _maxCondFormats = maxCondFormats; + } + + /** + * @return the maximum number of usable rows in each spreadsheet + */ + public int getMaxRows() { + return _maxRows; + } + + /** + * @return the last (maximum) valid row index, equals to getMaxRows() - 1 + */ + public int getLastRowIndex() { + return _maxRows - 1; + } + + /** + * @return the maximum number of usable columns in each spreadsheet + */ + public int getMaxColumns() { + return _maxColumns; + } + + /** + * @return the last (maximum) valid column index, equals to getMaxColumns() - 1 + */ + public int getLastColumnIndex() { + return _maxColumns - 1; + } + + /** + * @return the maximum number arguments that can be passed to a multi-arg function (e.g. COUNTIF) + */ + public int getMaxFunctionArgs() { + return _maxFunctionArgs; + } + + /** + * + * @return the maximum number of conditional format conditions on a cell + */ + public int getMaxConditionalFormats() { + return _maxCondFormats; + } + + /** + * + * @return the last valid column index in a ALPHA-26 representation + * (IV or XFD). + */ + public String getLastColumnName() { + return CellReference.convertNumToColString(getLastColumnIndex()); + } +} diff --git a/src/java/org/apache/poi/ss/formula/CellEvaluationFrame.java b/src/java/org/apache/poi/ss/formula/CellEvaluationFrame.java index a9f79e9e64..186fe6e1c8 100644 --- a/src/java/org/apache/poi/ss/formula/CellEvaluationFrame.java +++ b/src/java/org/apache/poi/ss/formula/CellEvaluationFrame.java @@ -1,77 +1,77 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import java.util.HashSet; -import java.util.Set; - -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * Stores details about the current evaluation of a cell.
          - */ -final class CellEvaluationFrame { - - private final FormulaCellCacheEntry _cce; - private final Set _sensitiveInputCells; - private FormulaUsedBlankCellSet _usedBlankCellGroup; - - public CellEvaluationFrame(FormulaCellCacheEntry cce) { - _cce = cce; - _sensitiveInputCells = new HashSet(); - } - public CellCacheEntry getCCE() { - return _cce; - } - - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append("]"); - return sb.toString(); - } - /** - * @param inputCell a cell directly used by the formula of this evaluation frame - */ - public void addSensitiveInputCell(CellCacheEntry inputCell) { - _sensitiveInputCells.add(inputCell); - } - /** - * @return never null, (possibly empty) array of all cells directly used while - * evaluating the formula of this frame. - */ - private CellCacheEntry[] getSensitiveInputCells() { - int nItems = _sensitiveInputCells.size(); - if (nItems < 1) { - return CellCacheEntry.EMPTY_ARRAY; - } - CellCacheEntry[] result = new CellCacheEntry[nItems]; - _sensitiveInputCells.toArray(result); - return result; - } - public void addUsedBlankCell(int bookIndex, int sheetIndex, int rowIndex, int columnIndex) { - if (_usedBlankCellGroup == null) { - _usedBlankCellGroup = new FormulaUsedBlankCellSet(); - } - _usedBlankCellGroup.addCell(bookIndex, sheetIndex, rowIndex, columnIndex); - } - - public void updateFormulaResult(ValueEval result) { - _cce.updateFormulaResult(result, getSensitiveInputCells(), _usedBlankCellGroup); - } -} \ No newline at end of file +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.formula; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * Stores details about the current evaluation of a cell.
          + */ +final class CellEvaluationFrame { + + private final FormulaCellCacheEntry _cce; + private final Set _sensitiveInputCells; + private FormulaUsedBlankCellSet _usedBlankCellGroup; + + public CellEvaluationFrame(FormulaCellCacheEntry cce) { + _cce = cce; + _sensitiveInputCells = new HashSet(); + } + public CellCacheEntry getCCE() { + return _cce; + } + + public String toString() { + StringBuffer sb = new StringBuffer(64); + sb.append(getClass().getName()).append(" ["); + sb.append("]"); + return sb.toString(); + } + /** + * @param inputCell a cell directly used by the formula of this evaluation frame + */ + public void addSensitiveInputCell(CellCacheEntry inputCell) { + _sensitiveInputCells.add(inputCell); + } + /** + * @return never null, (possibly empty) array of all cells directly used while + * evaluating the formula of this frame. + */ + private CellCacheEntry[] getSensitiveInputCells() { + int nItems = _sensitiveInputCells.size(); + if (nItems < 1) { + return CellCacheEntry.EMPTY_ARRAY; + } + CellCacheEntry[] result = new CellCacheEntry[nItems]; + _sensitiveInputCells.toArray(result); + return result; + } + public void addUsedBlankCell(int bookIndex, int sheetIndex, int rowIndex, int columnIndex) { + if (_usedBlankCellGroup == null) { + _usedBlankCellGroup = new FormulaUsedBlankCellSet(); + } + _usedBlankCellGroup.addCell(bookIndex, sheetIndex, rowIndex, columnIndex); + } + + public void updateFormulaResult(ValueEval result) { + _cce.updateFormulaResult(result, getSensitiveInputCells(), _usedBlankCellGroup); + } +} diff --git a/src/java/org/apache/poi/ss/formula/EvaluationName.java b/src/java/org/apache/poi/ss/formula/EvaluationName.java index ae8624c7b8..7d6688bb82 100644 --- a/src/java/org/apache/poi/ss/formula/EvaluationName.java +++ b/src/java/org/apache/poi/ss/formula/EvaluationName.java @@ -1,41 +1,41 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.hssf.record.formula.NamePtg; -import org.apache.poi.hssf.record.formula.Ptg; -/** - * Abstracts a name record for formula evaluation.
          - * - * For POI internal use only - * - * @author Josh Micich - */ -public interface EvaluationName { - - String getNameText(); - - boolean isFunctionName(); - - boolean hasFormula(); - - Ptg[] getNameDefinition(); - - boolean isRange(); - NamePtg createPtg(); -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.formula; + +import org.apache.poi.hssf.record.formula.NamePtg; +import org.apache.poi.hssf.record.formula.Ptg; +/** + * Abstracts a name record for formula evaluation.
          + * + * For POI internal use only + * + * @author Josh Micich + */ +public interface EvaluationName { + + String getNameText(); + + boolean isFunctionName(); + + boolean hasFormula(); + + Ptg[] getNameDefinition(); + + boolean isRange(); + NamePtg createPtg(); +} diff --git a/src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java b/src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java index 45b0c918f2..28f31eb497 100644 --- a/src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java +++ b/src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java @@ -1,65 +1,65 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.hssf.record.formula.NamePtg; -import org.apache.poi.hssf.record.formula.NameXPtg; -import org.apache.poi.hssf.record.formula.Ptg; - -/** - * Abstracts a workbook for the purpose of formula evaluation.
          - * - * For POI internal use only - * - * @author Josh Micich - */ -public interface EvaluationWorkbook { - String getSheetName(int sheetIndex); - /** - * @return -1 if the specified sheet is from a different book - */ - int getSheetIndex(EvaluationSheet sheet); - int getSheetIndex(String sheetName); - - EvaluationSheet getSheet(int sheetIndex); - - /** - * @return null if externSheetIndex refers to a sheet inside the current workbook - */ - ExternalSheet getExternalSheet(int externSheetIndex); - int convertFromExternSheetIndex(int externSheetIndex); - EvaluationName getName(NamePtg namePtg); - String resolveNameXText(NameXPtg ptg); - Ptg[] getFormulaTokens(EvaluationCell cell); - - class ExternalSheet { - private final String _workbookName; - private final String _sheetName; - - public ExternalSheet(String workbookName, String sheetName) { - _workbookName = workbookName; - _sheetName = sheetName; - } - public String getWorkbookName() { - return _workbookName; - } - public String getSheetName() { - return _sheetName; - } - } -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.formula; + +import org.apache.poi.hssf.record.formula.NamePtg; +import org.apache.poi.hssf.record.formula.NameXPtg; +import org.apache.poi.hssf.record.formula.Ptg; + +/** + * Abstracts a workbook for the purpose of formula evaluation.
          + * + * For POI internal use only + * + * @author Josh Micich + */ +public interface EvaluationWorkbook { + String getSheetName(int sheetIndex); + /** + * @return -1 if the specified sheet is from a different book + */ + int getSheetIndex(EvaluationSheet sheet); + int getSheetIndex(String sheetName); + + EvaluationSheet getSheet(int sheetIndex); + + /** + * @return null if externSheetIndex refers to a sheet inside the current workbook + */ + ExternalSheet getExternalSheet(int externSheetIndex); + int convertFromExternSheetIndex(int externSheetIndex); + EvaluationName getName(NamePtg namePtg); + String resolveNameXText(NameXPtg ptg); + Ptg[] getFormulaTokens(EvaluationCell cell); + + class ExternalSheet { + private final String _workbookName; + private final String _sheetName; + + public ExternalSheet(String workbookName, String sheetName) { + _workbookName = workbookName; + _sheetName = sheetName; + } + public String getWorkbookName() { + return _workbookName; + } + public String getSheetName() { + return _sheetName; + } + } +} diff --git a/src/java/org/apache/poi/ss/formula/Formula.java b/src/java/org/apache/poi/ss/formula/Formula.java index f2cef2cb42..0eb8a7f6dc 100644 --- a/src/java/org/apache/poi/ss/formula/Formula.java +++ b/src/java/org/apache/poi/ss/formula/Formula.java @@ -1,197 +1,197 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import java.util.Arrays; - -import org.apache.poi.hssf.record.ArrayRecord; -import org.apache.poi.hssf.record.SharedFormulaRecord; -import org.apache.poi.hssf.record.TableRecord; -import org.apache.poi.hssf.record.formula.ExpPtg; -import org.apache.poi.hssf.record.formula.Ptg; -import org.apache.poi.hssf.record.formula.TblPtg; -import org.apache.poi.hssf.util.CellReference; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.LittleEndianByteArrayInputStream; -import org.apache.poi.util.LittleEndianInput; -import org.apache.poi.util.LittleEndianOutput; - -/** - * Encapsulates an encoded formula token array. - * - * @author Josh Micich - */ -public class Formula { - - private static final Formula EMPTY = new Formula(new byte[0], 0); - - /** immutable */ - private final byte[] _byteEncoding; - private final int _encodedTokenLen; - - private Formula(byte[] byteEncoding, int encodedTokenLen) { - _byteEncoding = byteEncoding; - _encodedTokenLen = encodedTokenLen; - if (false) { // set to true to eagerly check Ptg decoding - LittleEndianByteArrayInputStream in = new LittleEndianByteArrayInputStream(byteEncoding); - Ptg.readTokens(encodedTokenLen, in); - int nUnusedBytes = _byteEncoding.length - in.getReadIndex(); - if (nUnusedBytes > 0) { - // TODO - this seems to occur when IntersectionPtg is present - // This example file "IntersectionPtg.xls" - // used by test: TestIntersectionPtg.testReading() - // has 10 bytes unused at the end of the formula - // 10 extra bytes are just 0x01 and 0x00 - System.out.println(nUnusedBytes + " unused bytes at end of formula"); - } - } - } - /** - * Convenience method for {@link #read(int, LittleEndianInput, int)} - */ - public static Formula read(int encodedTokenLen, LittleEndianInput in) { - return read(encodedTokenLen, in, encodedTokenLen); - } - /** - * When there are no array constants present, encodedTokenLen==totalEncodedLen - * @param encodedTokenLen number of bytes in the stream taken by the plain formula tokens - * @param totalEncodedLen the total number of bytes in the formula (includes trailing encoding - * for array constants, but does not include 2 bytes for initial ushort encodedTokenLen field. - * @return A new formula object as read from the stream. Possibly empty, never null. - */ - public static Formula read(int encodedTokenLen, LittleEndianInput in, int totalEncodedLen) { - byte[] byteEncoding = new byte[totalEncodedLen]; - in.readFully(byteEncoding); - return new Formula(byteEncoding, encodedTokenLen); - } - - public Ptg[] getTokens() { - LittleEndianInput in = new LittleEndianByteArrayInputStream(_byteEncoding); - return Ptg.readTokens(_encodedTokenLen, in); - } - /** - * Writes The formula encoding is includes: - *
            - *
          • ushort tokenDataLen
          • - *
          • tokenData
          • - *
          • arrayConstantData (if present)
          • - *
          - */ - public void serialize(LittleEndianOutput out) { - out.writeShort(_encodedTokenLen); - out.write(_byteEncoding); - } - - public void serializeTokens(LittleEndianOutput out) { - out.write(_byteEncoding, 0, _encodedTokenLen); - } - public void serializeArrayConstantData(LittleEndianOutput out) { - int len = _byteEncoding.length-_encodedTokenLen; - out.write(_byteEncoding, _encodedTokenLen, len); - } - - - /** - * @return total formula encoding length. The formula encoding includes: - *
            - *
          • ushort tokenDataLen
          • - *
          • tokenData
          • - *
          • arrayConstantData (optional)
          • - *
          - * Note - this value is different to tokenDataLength - */ - public int getEncodedSize() { - return 2 + _byteEncoding.length; - } - /** - * This method is often used when the formula length does not appear immediately before - * the encoded token data. - * - * @return the encoded length of the plain formula tokens. This does not include - * the leading ushort field, nor any trailing array constant data. - */ - public int getEncodedTokenSize() { - return _encodedTokenLen; - } - - /** - * Creates a {@link Formula} object from a supplied {@link Ptg} array. - * Handles nulls OK. - * @param ptgs may be null - * @return Never null (Possibly empty if the supplied ptgs is null) - */ - public static Formula create(Ptg[] ptgs) { - if (ptgs == null || ptgs.length < 1) { - return EMPTY; - } - int totalSize = Ptg.getEncodedSize(ptgs); - byte[] encodedData = new byte[totalSize]; - Ptg.serializePtgs(ptgs, encodedData, 0); - int encodedTokenLen = Ptg.getEncodedSizeWithoutArrayData(ptgs); - return new Formula(encodedData, encodedTokenLen); - } - /** - * Gets the {@link Ptg} array from the supplied {@link Formula}. - * Handles nulls OK. - * - * @param formula may be null - * @return possibly null (if the supplied formula is null) - */ - public static Ptg[] getTokens(Formula formula) { - if (formula == null) { - return null; - } - return formula.getTokens(); - } - - public Formula copy() { - // OK to return this because immutable - return this; - } - - /** - * Gets the locator for the corresponding {@link SharedFormulaRecord}, {@link ArrayRecord} or - * {@link TableRecord} if this formula belongs to such a grouping. The {@link CellReference} - * returned by this method will match the top left corner of the range of that grouping. - * The return value is usually not the same as the location of the cell containing this formula. - * - * @return the firstRow & firstColumn of an array formula or shared formula that this formula - * belongs to. null if this formula is not part of an array or shared formula. - */ - public CellReference getExpReference() { - byte[] data = _byteEncoding; - if (data.length != 5) { - // tExp and tTbl are always 5 bytes long, and the only ptg in the formula - return null; - } - switch (data[0]) { - case ExpPtg.sid: - break; - case TblPtg.sid: - break; - default: - return null; - } - int firstRow = LittleEndian.getUShort(data, 1); - int firstColumn = LittleEndian.getUShort(data, 3); - return new CellReference(firstRow, firstColumn); - } - public boolean isSame(Formula other) { - return Arrays.equals(_byteEncoding, other._byteEncoding); - } -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.formula; + +import java.util.Arrays; + +import org.apache.poi.hssf.record.ArrayRecord; +import org.apache.poi.hssf.record.SharedFormulaRecord; +import org.apache.poi.hssf.record.TableRecord; +import org.apache.poi.hssf.record.formula.ExpPtg; +import org.apache.poi.hssf.record.formula.Ptg; +import org.apache.poi.hssf.record.formula.TblPtg; +import org.apache.poi.hssf.util.CellReference; +import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.LittleEndianByteArrayInputStream; +import org.apache.poi.util.LittleEndianInput; +import org.apache.poi.util.LittleEndianOutput; + +/** + * Encapsulates an encoded formula token array. + * + * @author Josh Micich + */ +public class Formula { + + private static final Formula EMPTY = new Formula(new byte[0], 0); + + /** immutable */ + private final byte[] _byteEncoding; + private final int _encodedTokenLen; + + private Formula(byte[] byteEncoding, int encodedTokenLen) { + _byteEncoding = byteEncoding; + _encodedTokenLen = encodedTokenLen; + if (false) { // set to true to eagerly check Ptg decoding + LittleEndianByteArrayInputStream in = new LittleEndianByteArrayInputStream(byteEncoding); + Ptg.readTokens(encodedTokenLen, in); + int nUnusedBytes = _byteEncoding.length - in.getReadIndex(); + if (nUnusedBytes > 0) { + // TODO - this seems to occur when IntersectionPtg is present + // This example file "IntersectionPtg.xls" + // used by test: TestIntersectionPtg.testReading() + // has 10 bytes unused at the end of the formula + // 10 extra bytes are just 0x01 and 0x00 + System.out.println(nUnusedBytes + " unused bytes at end of formula"); + } + } + } + /** + * Convenience method for {@link #read(int, LittleEndianInput, int)} + */ + public static Formula read(int encodedTokenLen, LittleEndianInput in) { + return read(encodedTokenLen, in, encodedTokenLen); + } + /** + * When there are no array constants present, encodedTokenLen==totalEncodedLen + * @param encodedTokenLen number of bytes in the stream taken by the plain formula tokens + * @param totalEncodedLen the total number of bytes in the formula (includes trailing encoding + * for array constants, but does not include 2 bytes for initial ushort encodedTokenLen field. + * @return A new formula object as read from the stream. Possibly empty, never null. + */ + public static Formula read(int encodedTokenLen, LittleEndianInput in, int totalEncodedLen) { + byte[] byteEncoding = new byte[totalEncodedLen]; + in.readFully(byteEncoding); + return new Formula(byteEncoding, encodedTokenLen); + } + + public Ptg[] getTokens() { + LittleEndianInput in = new LittleEndianByteArrayInputStream(_byteEncoding); + return Ptg.readTokens(_encodedTokenLen, in); + } + /** + * Writes The formula encoding is includes: + *
            + *
          • ushort tokenDataLen
          • + *
          • tokenData
          • + *
          • arrayConstantData (if present)
          • + *
          + */ + public void serialize(LittleEndianOutput out) { + out.writeShort(_encodedTokenLen); + out.write(_byteEncoding); + } + + public void serializeTokens(LittleEndianOutput out) { + out.write(_byteEncoding, 0, _encodedTokenLen); + } + public void serializeArrayConstantData(LittleEndianOutput out) { + int len = _byteEncoding.length-_encodedTokenLen; + out.write(_byteEncoding, _encodedTokenLen, len); + } + + + /** + * @return total formula encoding length. The formula encoding includes: + *
            + *
          • ushort tokenDataLen
          • + *
          • tokenData
          • + *
          • arrayConstantData (optional)
          • + *
          + * Note - this value is different to tokenDataLength + */ + public int getEncodedSize() { + return 2 + _byteEncoding.length; + } + /** + * This method is often used when the formula length does not appear immediately before + * the encoded token data. + * + * @return the encoded length of the plain formula tokens. This does not include + * the leading ushort field, nor any trailing array constant data. + */ + public int getEncodedTokenSize() { + return _encodedTokenLen; + } + + /** + * Creates a {@link Formula} object from a supplied {@link Ptg} array. + * Handles nulls OK. + * @param ptgs may be null + * @return Never null (Possibly empty if the supplied ptgs is null) + */ + public static Formula create(Ptg[] ptgs) { + if (ptgs == null || ptgs.length < 1) { + return EMPTY; + } + int totalSize = Ptg.getEncodedSize(ptgs); + byte[] encodedData = new byte[totalSize]; + Ptg.serializePtgs(ptgs, encodedData, 0); + int encodedTokenLen = Ptg.getEncodedSizeWithoutArrayData(ptgs); + return new Formula(encodedData, encodedTokenLen); + } + /** + * Gets the {@link Ptg} array from the supplied {@link Formula}. + * Handles nulls OK. + * + * @param formula may be null + * @return possibly null (if the supplied formula is null) + */ + public static Ptg[] getTokens(Formula formula) { + if (formula == null) { + return null; + } + return formula.getTokens(); + } + + public Formula copy() { + // OK to return this because immutable + return this; + } + + /** + * Gets the locator for the corresponding {@link SharedFormulaRecord}, {@link ArrayRecord} or + * {@link TableRecord} if this formula belongs to such a grouping. The {@link CellReference} + * returned by this method will match the top left corner of the range of that grouping. + * The return value is usually not the same as the location of the cell containing this formula. + * + * @return the firstRow & firstColumn of an array formula or shared formula that this formula + * belongs to. null if this formula is not part of an array or shared formula. + */ + public CellReference getExpReference() { + byte[] data = _byteEncoding; + if (data.length != 5) { + // tExp and tTbl are always 5 bytes long, and the only ptg in the formula + return null; + } + switch (data[0]) { + case ExpPtg.sid: + break; + case TblPtg.sid: + break; + default: + return null; + } + int firstRow = LittleEndian.getUShort(data, 1); + int firstColumn = LittleEndian.getUShort(data, 3); + return new CellReference(firstRow, firstColumn); + } + public boolean isSame(Formula other) { + return Arrays.equals(_byteEncoding, other._byteEncoding); + } +} diff --git a/src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java b/src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java index 2ecd69be9a..83f7c99a96 100644 --- a/src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java +++ b/src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java @@ -1,55 +1,55 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.hssf.record.formula.NameXPtg; -import org.apache.poi.ss.SpreadsheetVersion; - -/** - * Abstracts a workbook for the purpose of formula parsing.
          - * - * For POI internal use only - * - * @author Josh Micich - */ -public interface FormulaParsingWorkbook { - /** - * named range name matching is case insensitive - */ - EvaluationName getName(String name, int sheetIndex); - - NameXPtg getNameXPtg(String name); - - /** - * gets the externSheet index for a sheet from this workbook - */ - int getExternalSheetIndex(String sheetName); - /** - * gets the externSheet index for a sheet from an external workbook - * @param workbookName e.g. "Budget.xls" - * @param sheetName a name of a sheet in that workbook - */ - int getExternalSheetIndex(String workbookName, String sheetName); - - /** - * Returns an enum holding spreadhseet properties specific to an Excel version ( - * max column and row numbers, max arguments to a function, etc.) - */ - SpreadsheetVersion getSpreadsheetVersion(); - -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.formula; + +import org.apache.poi.hssf.record.formula.NameXPtg; +import org.apache.poi.ss.SpreadsheetVersion; + +/** + * Abstracts a workbook for the purpose of formula parsing.
          + * + * For POI internal use only + * + * @author Josh Micich + */ +public interface FormulaParsingWorkbook { + /** + * named range name matching is case insensitive + */ + EvaluationName getName(String name, int sheetIndex); + + NameXPtg getNameXPtg(String name); + + /** + * gets the externSheet index for a sheet from this workbook + */ + int getExternalSheetIndex(String sheetName); + /** + * gets the externSheet index for a sheet from an external workbook + * @param workbookName e.g. "Budget.xls" + * @param sheetName a name of a sheet in that workbook + */ + int getExternalSheetIndex(String workbookName, String sheetName); + + /** + * Returns an enum holding spreadhseet properties specific to an Excel version ( + * max column and row numbers, max arguments to a function, etc.) + */ + SpreadsheetVersion getSpreadsheetVersion(); + +} diff --git a/src/java/org/apache/poi/ss/formula/FormulaRenderer.java b/src/java/org/apache/poi/ss/formula/FormulaRenderer.java index df078809cf..76dce7f55e 100644 --- a/src/java/org/apache/poi/ss/formula/FormulaRenderer.java +++ b/src/java/org/apache/poi/ss/formula/FormulaRenderer.java @@ -1,131 +1,131 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import java.util.Stack; - -import org.apache.poi.hssf.record.formula.AttrPtg; -import org.apache.poi.hssf.record.formula.MemAreaPtg; -import org.apache.poi.hssf.record.formula.MemErrPtg; -import org.apache.poi.hssf.record.formula.MemFuncPtg; -import org.apache.poi.hssf.record.formula.OperationPtg; -import org.apache.poi.hssf.record.formula.ParenthesisPtg; -import org.apache.poi.hssf.record.formula.Ptg; - -/** - * Common logic for rendering formulas.
          - * - * For POI internal use only - * - * @author Josh Micich - */ -public class FormulaRenderer { - - /** - * Static method to convert an array of {@link Ptg}s in RPN order - * to a human readable string format in infix mode. - * @param book used for defined names and 3D references - * @param ptgs must not be null - * @return a human readable String - */ - public static String toFormulaString(FormulaRenderingWorkbook book, Ptg[] ptgs) { - if (ptgs == null || ptgs.length == 0) { - throw new IllegalArgumentException("ptgs must not be null"); - } - Stack stack = new Stack(); - - for (int i=0 ; i < ptgs.length; i++) { - Ptg ptg = ptgs[i]; - // TODO - what about MemNoMemPtg? - if(ptg instanceof MemAreaPtg || ptg instanceof MemFuncPtg || ptg instanceof MemErrPtg) { - // marks the start of a list of area expressions which will be naturally combined - // by their trailing operators (e.g. UnionPtg) - // TODO - put comment and throw exception in toFormulaString() of these classes - continue; - } - if (ptg instanceof ParenthesisPtg) { - String contents = stack.pop(); - stack.push ("(" + contents + ")"); - continue; - } - if (ptg instanceof AttrPtg) { - AttrPtg attrPtg = ((AttrPtg) ptg); - if (attrPtg.isOptimizedIf() || attrPtg.isOptimizedChoose() || attrPtg.isGoto()) { - continue; - } - if (attrPtg.isSpace()) { - // POI currently doesn't render spaces in formulas - continue; - // but if it ever did, care must be taken: - // tAttrSpace comes *before* the operand it applies to, which may be consistent - // with how the formula text appears but is against the RPN ordering assumed here - } - if (attrPtg.isSemiVolatile()) { - // similar to tAttrSpace - RPN is violated - continue; - } - if (attrPtg.isSum()) { - String[] operands = getOperands(stack, attrPtg.getNumberOfOperands()); - stack.push(attrPtg.toFormulaString(operands)); - continue; - } - throw new RuntimeException("Unexpected tAttr: " + attrPtg.toString()); - } - - if (ptg instanceof WorkbookDependentFormula) { - WorkbookDependentFormula optg = (WorkbookDependentFormula) ptg; - stack.push(optg.toFormulaString(book)); - continue; - } - if (! (ptg instanceof OperationPtg)) { - stack.push(ptg.toFormulaString()); - continue; - } - - OperationPtg o = (OperationPtg) ptg; - String[] operands = getOperands(stack, o.getNumberOfOperands()); - stack.push(o.toFormulaString(operands)); - } - if(stack.isEmpty()) { - // inspection of the code above reveals that every stack.pop() is followed by a - // stack.push(). So this is either an internal error or impossible. - throw new IllegalStateException("Stack underflow"); - } - String result = stack.pop(); - if(!stack.isEmpty()) { - // Might be caused by some tokens like AttrPtg and Mem*Ptg, which really shouldn't - // put anything on the stack - throw new IllegalStateException("too much stuff left on the stack"); - } - return result; - } - - private static String[] getOperands(Stack stack, int nOperands) { - String[] operands = new String[nOperands]; - - for (int j = nOperands-1; j >= 0; j--) { // reverse iteration because args were pushed in-order - if(stack.isEmpty()) { - String msg = "Too few arguments supplied to operation. Expected (" + nOperands - + ") operands but got (" + (nOperands - j - 1) + ")"; - throw new IllegalStateException(msg); - } - operands[j] = stack.pop(); - } - return operands; - } -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.formula; + +import java.util.Stack; + +import org.apache.poi.hssf.record.formula.AttrPtg; +import org.apache.poi.hssf.record.formula.MemAreaPtg; +import org.apache.poi.hssf.record.formula.MemErrPtg; +import org.apache.poi.hssf.record.formula.MemFuncPtg; +import org.apache.poi.hssf.record.formula.OperationPtg; +import org.apache.poi.hssf.record.formula.ParenthesisPtg; +import org.apache.poi.hssf.record.formula.Ptg; + +/** + * Common logic for rendering formulas.
          + * + * For POI internal use only + * + * @author Josh Micich + */ +public class FormulaRenderer { + + /** + * Static method to convert an array of {@link Ptg}s in RPN order + * to a human readable string format in infix mode. + * @param book used for defined names and 3D references + * @param ptgs must not be null + * @return a human readable String + */ + public static String toFormulaString(FormulaRenderingWorkbook book, Ptg[] ptgs) { + if (ptgs == null || ptgs.length == 0) { + throw new IllegalArgumentException("ptgs must not be null"); + } + Stack stack = new Stack(); + + for (int i=0 ; i < ptgs.length; i++) { + Ptg ptg = ptgs[i]; + // TODO - what about MemNoMemPtg? + if(ptg instanceof MemAreaPtg || ptg instanceof MemFuncPtg || ptg instanceof MemErrPtg) { + // marks the start of a list of area expressions which will be naturally combined + // by their trailing operators (e.g. UnionPtg) + // TODO - put comment and throw exception in toFormulaString() of these classes + continue; + } + if (ptg instanceof ParenthesisPtg) { + String contents = stack.pop(); + stack.push ("(" + contents + ")"); + continue; + } + if (ptg instanceof AttrPtg) { + AttrPtg attrPtg = ((AttrPtg) ptg); + if (attrPtg.isOptimizedIf() || attrPtg.isOptimizedChoose() || attrPtg.isGoto()) { + continue; + } + if (attrPtg.isSpace()) { + // POI currently doesn't render spaces in formulas + continue; + // but if it ever did, care must be taken: + // tAttrSpace comes *before* the operand it applies to, which may be consistent + // with how the formula text appears but is against the RPN ordering assumed here + } + if (attrPtg.isSemiVolatile()) { + // similar to tAttrSpace - RPN is violated + continue; + } + if (attrPtg.isSum()) { + String[] operands = getOperands(stack, attrPtg.getNumberOfOperands()); + stack.push(attrPtg.toFormulaString(operands)); + continue; + } + throw new RuntimeException("Unexpected tAttr: " + attrPtg.toString()); + } + + if (ptg instanceof WorkbookDependentFormula) { + WorkbookDependentFormula optg = (WorkbookDependentFormula) ptg; + stack.push(optg.toFormulaString(book)); + continue; + } + if (! (ptg instanceof OperationPtg)) { + stack.push(ptg.toFormulaString()); + continue; + } + + OperationPtg o = (OperationPtg) ptg; + String[] operands = getOperands(stack, o.getNumberOfOperands()); + stack.push(o.toFormulaString(operands)); + } + if(stack.isEmpty()) { + // inspection of the code above reveals that every stack.pop() is followed by a + // stack.push(). So this is either an internal error or impossible. + throw new IllegalStateException("Stack underflow"); + } + String result = stack.pop(); + if(!stack.isEmpty()) { + // Might be caused by some tokens like AttrPtg and Mem*Ptg, which really shouldn't + // put anything on the stack + throw new IllegalStateException("too much stuff left on the stack"); + } + return result; + } + + private static String[] getOperands(Stack stack, int nOperands) { + String[] operands = new String[nOperands]; + + for (int j = nOperands-1; j >= 0; j--) { // reverse iteration because args were pushed in-order + if(stack.isEmpty()) { + String msg = "Too few arguments supplied to operation. Expected (" + nOperands + + ") operands but got (" + (nOperands - j - 1) + ")"; + throw new IllegalStateException(msg); + } + operands[j] = stack.pop(); + } + return operands; + } +} diff --git a/src/java/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java b/src/java/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java index c9b95f6b1c..b0dcb38512 100644 --- a/src/java/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java +++ b/src/java/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java @@ -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.ss.formula; - -import org.apache.poi.hssf.record.formula.NamePtg; -import org.apache.poi.hssf.record.formula.NameXPtg; -import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet; - -/** - * Abstracts a workbook for the purpose of converting formula to text.
          - * - * For POI internal use only - * - * @author Josh Micich - */ -public interface FormulaRenderingWorkbook { - - /** - * @return null if externSheetIndex refers to a sheet inside the current workbook - */ - ExternalSheet getExternalSheet(int externSheetIndex); - String getSheetNameByExternSheet(int externSheetIndex); - String resolveNameXText(NameXPtg nameXPtg); - String getNameText(NamePtg namePtg); -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.formula; + +import org.apache.poi.hssf.record.formula.NamePtg; +import org.apache.poi.hssf.record.formula.NameXPtg; +import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet; + +/** + * Abstracts a workbook for the purpose of converting formula to text.
          + * + * For POI internal use only + * + * @author Josh Micich + */ +public interface FormulaRenderingWorkbook { + + /** + * @return null if externSheetIndex refers to a sheet inside the current workbook + */ + ExternalSheet getExternalSheet(int externSheetIndex); + String getSheetNameByExternSheet(int externSheetIndex); + String resolveNameXText(NameXPtg nameXPtg); + String getNameText(NamePtg namePtg); +} diff --git a/src/java/org/apache/poi/ss/formula/FormulaType.java b/src/java/org/apache/poi/ss/formula/FormulaType.java index 3b47030d47..b770019907 100644 --- a/src/java/org/apache/poi/ss/formula/FormulaType.java +++ b/src/java/org/apache/poi/ss/formula/FormulaType.java @@ -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.ss.formula; - -/** - * Enumeration of various formula types.
          - * - * For POI internal use only - * - * @author Josh Micich - */ -public final class FormulaType { - private FormulaType() { - // no instances of this class - } - public static final int CELL = 0; - public static final int SHARED = 1; - public static final int ARRAY =2; - public static final int CONDFORMAT = 3; - public static final int NAMEDRANGE = 4; - // this constant is currently very specific. The exact differences from general data - // validation formulas or conditional format formulas is not known yet - public static final int DATAVALIDATION_LIST = 5; - -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.formula; + +/** + * Enumeration of various formula types.
          + * + * For POI internal use only + * + * @author Josh Micich + */ +public final class FormulaType { + private FormulaType() { + // no instances of this class + } + public static final int CELL = 0; + public static final int SHARED = 1; + public static final int ARRAY =2; + public static final int CONDFORMAT = 3; + public static final int NAMEDRANGE = 4; + // this constant is currently very specific. The exact differences from general data + // validation formulas or conditional format formulas is not known yet + public static final int DATAVALIDATION_LIST = 5; + +} diff --git a/src/java/org/apache/poi/ss/formula/LazyRefEval.java b/src/java/org/apache/poi/ss/formula/LazyRefEval.java index f25e86fc40..69f0834f50 100644 --- a/src/java/org/apache/poi/ss/formula/LazyRefEval.java +++ b/src/java/org/apache/poi/ss/formula/LazyRefEval.java @@ -1,68 +1,68 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.hssf.record.formula.AreaI; -import org.apache.poi.hssf.record.formula.Ref3DPtg; -import org.apache.poi.hssf.record.formula.RefPtg; -import org.apache.poi.hssf.record.formula.AreaI.OffsetArea; -import org.apache.poi.hssf.record.formula.eval.AreaEval; -import org.apache.poi.hssf.record.formula.eval.RefEvalBase; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.util.CellReference; - -/** -* -* @author Josh Micich -*/ -final class LazyRefEval extends RefEvalBase { - - private final SheetRefEvaluator _evaluator; - - public LazyRefEval(RefPtg ptg, SheetRefEvaluator sre) { - super(ptg.getRow(), ptg.getColumn()); - _evaluator = sre; - } - public LazyRefEval(Ref3DPtg ptg, SheetRefEvaluator sre) { - super(ptg.getRow(), ptg.getColumn()); - _evaluator = sre; - } - - public ValueEval getInnerValueEval() { - return _evaluator.getEvalForCell(getRow(), getColumn()); - } - - public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) { - - AreaI area = new OffsetArea(getRow(), getColumn(), - relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx); - - return new LazyAreaEval(area, _evaluator); - } - - public String toString() { - CellReference cr = new CellReference(getRow(), getColumn()); - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getName()).append("["); - sb.append(_evaluator.getSheetName()); - sb.append('!'); - sb.append(cr.formatAsString()); - 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.ss.formula; + +import org.apache.poi.hssf.record.formula.AreaI; +import org.apache.poi.hssf.record.formula.Ref3DPtg; +import org.apache.poi.hssf.record.formula.RefPtg; +import org.apache.poi.hssf.record.formula.AreaI.OffsetArea; +import org.apache.poi.hssf.record.formula.eval.AreaEval; +import org.apache.poi.hssf.record.formula.eval.RefEvalBase; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.util.CellReference; + +/** +* +* @author Josh Micich +*/ +final class LazyRefEval extends RefEvalBase { + + private final SheetRefEvaluator _evaluator; + + public LazyRefEval(RefPtg ptg, SheetRefEvaluator sre) { + super(ptg.getRow(), ptg.getColumn()); + _evaluator = sre; + } + public LazyRefEval(Ref3DPtg ptg, SheetRefEvaluator sre) { + super(ptg.getRow(), ptg.getColumn()); + _evaluator = sre; + } + + public ValueEval getInnerValueEval() { + return _evaluator.getEvalForCell(getRow(), getColumn()); + } + + public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) { + + AreaI area = new OffsetArea(getRow(), getColumn(), + relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx); + + return new LazyAreaEval(area, _evaluator); + } + + public String toString() { + CellReference cr = new CellReference(getRow(), getColumn()); + StringBuffer sb = new StringBuffer(); + sb.append(getClass().getName()).append("["); + sb.append(_evaluator.getSheetName()); + sb.append('!'); + sb.append(cr.formatAsString()); + sb.append("]"); + return sb.toString(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/SheetRefEvaluator.java b/src/java/org/apache/poi/ss/formula/SheetRefEvaluator.java index bf636a4da3..b2a6ed123d 100644 --- a/src/java/org/apache/poi/ss/formula/SheetRefEvaluator.java +++ b/src/java/org/apache/poi/ss/formula/SheetRefEvaluator.java @@ -1,48 +1,48 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -import org.apache.poi.hssf.record.formula.eval.ValueEval; -/** - * - * - * @author Josh Micich - */ -final class SheetRefEvaluator { - - private final WorkbookEvaluator _bookEvaluator; - private final EvaluationTracker _tracker; - private final EvaluationSheet _sheet; - private final int _sheetIndex; - - public SheetRefEvaluator(WorkbookEvaluator bookEvaluator, EvaluationTracker tracker, - EvaluationWorkbook _workbook, int sheetIndex) { - _bookEvaluator = bookEvaluator; - _tracker = tracker; - _sheet = _workbook.getSheet(sheetIndex); - _sheetIndex = sheetIndex; - } - - public String getSheetName() { - return _bookEvaluator.getSheetName(_sheetIndex); - } - - public ValueEval getEvalForCell(int rowIndex, int columnIndex) { - return _bookEvaluator.evaluateReference(_sheet, _sheetIndex, rowIndex, columnIndex, _tracker); - } -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.formula; + +import org.apache.poi.hssf.record.formula.eval.ValueEval; +/** + * + * + * @author Josh Micich + */ +final class SheetRefEvaluator { + + private final WorkbookEvaluator _bookEvaluator; + private final EvaluationTracker _tracker; + private final EvaluationSheet _sheet; + private final int _sheetIndex; + + public SheetRefEvaluator(WorkbookEvaluator bookEvaluator, EvaluationTracker tracker, + EvaluationWorkbook _workbook, int sheetIndex) { + _bookEvaluator = bookEvaluator; + _tracker = tracker; + _sheet = _workbook.getSheet(sheetIndex); + _sheetIndex = sheetIndex; + } + + public String getSheetName() { + return _bookEvaluator.getSheetName(_sheetIndex); + } + + public ValueEval getEvalForCell(int rowIndex, int columnIndex) { + return _bookEvaluator.evaluateReference(_sheet, _sheetIndex, rowIndex, columnIndex, _tracker); + } +} diff --git a/src/java/org/apache/poi/ss/formula/WorkbookDependentFormula.java b/src/java/org/apache/poi/ss/formula/WorkbookDependentFormula.java index 3dc2c525d5..4beaaa3b08 100644 --- a/src/java/org/apache/poi/ss/formula/WorkbookDependentFormula.java +++ b/src/java/org/apache/poi/ss/formula/WorkbookDependentFormula.java @@ -1,30 +1,30 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula; - -/** - * Should be implemented by any {@link org.apache.poi.hssf.record.formula.Ptg} subclass that needs a workbook to render its formula. - *
          - * - * For POI internal use only - * - * @author Josh Micich - */ -public interface WorkbookDependentFormula { - String toFormulaString(FormulaRenderingWorkbook book); -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.formula; + +/** + * Should be implemented by any {@link org.apache.poi.hssf.record.formula.Ptg} subclass that needs a workbook to render its formula. + *
          + * + * For POI internal use only + * + * @author Josh Micich + */ +public interface WorkbookDependentFormula { + String toFormulaString(FormulaRenderingWorkbook book); +} diff --git a/src/java/org/apache/poi/ss/formula/eval/NotImplementedException.java b/src/java/org/apache/poi/ss/formula/eval/NotImplementedException.java index 84480758ec..cad7f88582 100644 --- a/src/java/org/apache/poi/ss/formula/eval/NotImplementedException.java +++ b/src/java/org/apache/poi/ss/formula/eval/NotImplementedException.java @@ -1,36 +1,36 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval; - -import org.apache.poi.ss.usermodel.FormulaEvaluator; - -/** - * An exception thrown by implementors of {@link FormulaEvaluator} when attempting to evaluate - * a formula which requires features that POI does not (yet) support. - * - * @author Josh Micich - */ -public final class NotImplementedException extends RuntimeException { - - public NotImplementedException(String message) { - super(message); - } - public NotImplementedException(String message, NotImplementedException cause) { - super(message, cause); - } -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.formula.eval; + +import org.apache.poi.ss.usermodel.FormulaEvaluator; + +/** + * An exception thrown by implementors of {@link FormulaEvaluator} when attempting to evaluate + * a formula which requires features that POI does not (yet) support. + * + * @author Josh Micich + */ +public final class NotImplementedException extends RuntimeException { + + public NotImplementedException(String message) { + super(message); + } + public NotImplementedException(String message, NotImplementedException cause) { + super(message, cause); + } +} diff --git a/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationCell.java b/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationCell.java index 3563904b1a..73c6a7ddc6 100644 --- a/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationCell.java +++ b/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationCell.java @@ -1,132 +1,132 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval.forked; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -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.hssf.usermodel.HSSFCell; -import org.apache.poi.ss.formula.EvaluationCell; -import org.apache.poi.ss.formula.EvaluationSheet; -import org.apache.poi.ss.usermodel.Cell; - -/** - * Represents a cell being used for forked evaluation that has had a value set different from the - * corresponding cell in the shared master workbook. - * - * @author Josh Micich - */ -final class ForkedEvaluationCell implements EvaluationCell { - - private final EvaluationSheet _sheet; - /** corresponding cell from master workbook */ - private final EvaluationCell _masterCell; - private boolean _booleanValue; - private int _cellType; - private int _errorValue; - private double _numberValue; - private String _stringValue; - - public ForkedEvaluationCell(ForkedEvaluationSheet sheet, EvaluationCell masterCell) { - _sheet = sheet; - _masterCell = masterCell; - // start with value blank, but expect construction to be immediately - setValue(BlankEval.INSTANCE); // followed by a proper call to setValue() - } - - public Object getIdentityKey() { - return _masterCell.getIdentityKey(); - } - - public void setValue(ValueEval value) { - Class cls = value.getClass(); - - if (cls == NumberEval.class) { - _cellType = HSSFCell.CELL_TYPE_NUMERIC; - _numberValue = ((NumberEval)value).getNumberValue(); - return; - } - if (cls == StringEval.class) { - _cellType = HSSFCell.CELL_TYPE_STRING; - _stringValue = ((StringEval)value).getStringValue(); - return; - } - if (cls == BoolEval.class) { - _cellType = HSSFCell.CELL_TYPE_BOOLEAN; - _booleanValue = ((BoolEval)value).getBooleanValue(); - return; - } - if (cls == ErrorEval.class) { - _cellType = HSSFCell.CELL_TYPE_ERROR; - _errorValue = ((ErrorEval)value).getErrorCode(); - return; - } - if (cls == BlankEval.class) { - _cellType = HSSFCell.CELL_TYPE_BLANK; - return; - } - throw new IllegalArgumentException("Unexpected value class (" + cls.getName() + ")"); - } - public void copyValue(Cell destCell) { - switch (_cellType) { - case Cell.CELL_TYPE_BLANK: destCell.setCellType(Cell.CELL_TYPE_BLANK); return; - case Cell.CELL_TYPE_NUMERIC: destCell.setCellValue(_numberValue); return; - case Cell.CELL_TYPE_BOOLEAN: destCell.setCellValue(_booleanValue); return; - case Cell.CELL_TYPE_STRING: destCell.setCellValue(_stringValue); return; - case Cell.CELL_TYPE_ERROR: destCell.setCellErrorValue((byte)_errorValue); return; - } - throw new IllegalStateException("Unexpected data type (" + _cellType + ")"); - } - - private void checkCellType(int expectedCellType) { - if (_cellType != expectedCellType) { - throw new RuntimeException("Wrong data type (" + _cellType + ")"); - } - } - public int getCellType() { - return _cellType; - } - public boolean getBooleanCellValue() { - checkCellType(HSSFCell.CELL_TYPE_BOOLEAN); - return _booleanValue; - } - public int getErrorCellValue() { - checkCellType(HSSFCell.CELL_TYPE_ERROR); - return _errorValue; - } - public double getNumericCellValue() { - checkCellType(HSSFCell.CELL_TYPE_NUMERIC); - return _numberValue; - } - public String getStringCellValue() { - checkCellType(HSSFCell.CELL_TYPE_STRING); - return _stringValue; - } - public EvaluationSheet getSheet() { - return _sheet; - } - public int getRowIndex() { - return _masterCell.getRowIndex(); - } - public int getColumnIndex() { - return _masterCell.getColumnIndex(); - } -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.formula.eval.forked; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +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.hssf.usermodel.HSSFCell; +import org.apache.poi.ss.formula.EvaluationCell; +import org.apache.poi.ss.formula.EvaluationSheet; +import org.apache.poi.ss.usermodel.Cell; + +/** + * Represents a cell being used for forked evaluation that has had a value set different from the + * corresponding cell in the shared master workbook. + * + * @author Josh Micich + */ +final class ForkedEvaluationCell implements EvaluationCell { + + private final EvaluationSheet _sheet; + /** corresponding cell from master workbook */ + private final EvaluationCell _masterCell; + private boolean _booleanValue; + private int _cellType; + private int _errorValue; + private double _numberValue; + private String _stringValue; + + public ForkedEvaluationCell(ForkedEvaluationSheet sheet, EvaluationCell masterCell) { + _sheet = sheet; + _masterCell = masterCell; + // start with value blank, but expect construction to be immediately + setValue(BlankEval.INSTANCE); // followed by a proper call to setValue() + } + + public Object getIdentityKey() { + return _masterCell.getIdentityKey(); + } + + public void setValue(ValueEval value) { + Class cls = value.getClass(); + + if (cls == NumberEval.class) { + _cellType = HSSFCell.CELL_TYPE_NUMERIC; + _numberValue = ((NumberEval)value).getNumberValue(); + return; + } + if (cls == StringEval.class) { + _cellType = HSSFCell.CELL_TYPE_STRING; + _stringValue = ((StringEval)value).getStringValue(); + return; + } + if (cls == BoolEval.class) { + _cellType = HSSFCell.CELL_TYPE_BOOLEAN; + _booleanValue = ((BoolEval)value).getBooleanValue(); + return; + } + if (cls == ErrorEval.class) { + _cellType = HSSFCell.CELL_TYPE_ERROR; + _errorValue = ((ErrorEval)value).getErrorCode(); + return; + } + if (cls == BlankEval.class) { + _cellType = HSSFCell.CELL_TYPE_BLANK; + return; + } + throw new IllegalArgumentException("Unexpected value class (" + cls.getName() + ")"); + } + public void copyValue(Cell destCell) { + switch (_cellType) { + case Cell.CELL_TYPE_BLANK: destCell.setCellType(Cell.CELL_TYPE_BLANK); return; + case Cell.CELL_TYPE_NUMERIC: destCell.setCellValue(_numberValue); return; + case Cell.CELL_TYPE_BOOLEAN: destCell.setCellValue(_booleanValue); return; + case Cell.CELL_TYPE_STRING: destCell.setCellValue(_stringValue); return; + case Cell.CELL_TYPE_ERROR: destCell.setCellErrorValue((byte)_errorValue); return; + } + throw new IllegalStateException("Unexpected data type (" + _cellType + ")"); + } + + private void checkCellType(int expectedCellType) { + if (_cellType != expectedCellType) { + throw new RuntimeException("Wrong data type (" + _cellType + ")"); + } + } + public int getCellType() { + return _cellType; + } + public boolean getBooleanCellValue() { + checkCellType(HSSFCell.CELL_TYPE_BOOLEAN); + return _booleanValue; + } + public int getErrorCellValue() { + checkCellType(HSSFCell.CELL_TYPE_ERROR); + return _errorValue; + } + public double getNumericCellValue() { + checkCellType(HSSFCell.CELL_TYPE_NUMERIC); + return _numberValue; + } + public String getStringCellValue() { + checkCellType(HSSFCell.CELL_TYPE_STRING); + return _stringValue; + } + public EvaluationSheet getSheet() { + return _sheet; + } + public int getRowIndex() { + return _masterCell.getRowIndex(); + } + public int getColumnIndex() { + return _masterCell.getColumnIndex(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationSheet.java b/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationSheet.java index 837ba932e4..c36232a1d8 100644 --- a/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationSheet.java +++ b/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationSheet.java @@ -1,129 +1,129 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval.forked; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.ss.formula.EvaluationCell; -import org.apache.poi.ss.formula.EvaluationSheet; -import org.apache.poi.ss.formula.EvaluationWorkbook; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; - -/** - * Represents a sheet being used for forked evaluation. Initially, objects of this class contain - * only the cells from the master workbook. By calling {@link #getOrCreateUpdatableCell(int, int)}, - * the master cell object is logically replaced with a {@link ForkedEvaluationCell} instance, which - * will be used in all subsequent evaluations. - * - * @author Josh Micich - */ -final class ForkedEvaluationSheet implements EvaluationSheet { - - private final EvaluationSheet _masterSheet; - /** - * Only cells which have been split are put in this map. (This has been done to conserve memory). - */ - private final Map _sharedCellsByRowCol; - - public ForkedEvaluationSheet(EvaluationSheet masterSheet) { - _masterSheet = masterSheet; - _sharedCellsByRowCol = new HashMap(); - } - - public EvaluationCell getCell(int rowIndex, int columnIndex) { - RowColKey key = new RowColKey(rowIndex, columnIndex); - - ForkedEvaluationCell result = _sharedCellsByRowCol.get(key); - if (result == null) { - return _masterSheet.getCell(rowIndex, columnIndex); - } - return result; - } - - public ForkedEvaluationCell getOrCreateUpdatableCell(int rowIndex, int columnIndex) { - RowColKey key = new RowColKey(rowIndex, columnIndex); - - ForkedEvaluationCell result = _sharedCellsByRowCol.get(key); - if (result == null) { - EvaluationCell mcell = _masterSheet.getCell(rowIndex, columnIndex); - result = new ForkedEvaluationCell(this, mcell); - _sharedCellsByRowCol.put(key, result); - } - return result; - } - - public void copyUpdatedCells(Sheet sheet) { - RowColKey[] keys = new RowColKey[_sharedCellsByRowCol.size()]; - _sharedCellsByRowCol.keySet().toArray(keys); - Arrays.sort(keys); - for (int i = 0; i < keys.length; i++) { - RowColKey key = keys[i]; - Row row = sheet.getRow(key.getRowIndex()); - if (row == null) { - row = sheet.createRow(key.getRowIndex()); - } - Cell destCell = row.getCell(key.getColumnIndex()); - if (destCell == null) { - destCell = row.createCell(key.getColumnIndex()); - } - - ForkedEvaluationCell srcCell = _sharedCellsByRowCol.get(key); - srcCell.copyValue(destCell); - } - } - - public int getSheetIndex(EvaluationWorkbook mewb) { - return mewb.getSheetIndex(_masterSheet); - } - - private static final class RowColKey implements Comparable{ - private final int _rowIndex; - private final int _columnIndex; - - public RowColKey(int rowIndex, int columnIndex) { - _rowIndex = rowIndex; - _columnIndex = columnIndex; - } - @Override - public boolean equals(Object obj) { - RowColKey other = (RowColKey) obj; - return _rowIndex == other._rowIndex && _columnIndex == other._columnIndex; - } - @Override - public int hashCode() { - return _rowIndex ^ _columnIndex; - } - public int compareTo(RowColKey o) { - int cmp = _rowIndex - o._rowIndex; - if (cmp != 0) { - return cmp; - } - return _columnIndex - o._columnIndex; - } - public int getRowIndex() { - return _rowIndex; - } - public int getColumnIndex() { - 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.ss.formula.eval.forked; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import org.apache.poi.ss.formula.EvaluationCell; +import org.apache.poi.ss.formula.EvaluationSheet; +import org.apache.poi.ss.formula.EvaluationWorkbook; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; + +/** + * Represents a sheet being used for forked evaluation. Initially, objects of this class contain + * only the cells from the master workbook. By calling {@link #getOrCreateUpdatableCell(int, int)}, + * the master cell object is logically replaced with a {@link ForkedEvaluationCell} instance, which + * will be used in all subsequent evaluations. + * + * @author Josh Micich + */ +final class ForkedEvaluationSheet implements EvaluationSheet { + + private final EvaluationSheet _masterSheet; + /** + * Only cells which have been split are put in this map. (This has been done to conserve memory). + */ + private final Map _sharedCellsByRowCol; + + public ForkedEvaluationSheet(EvaluationSheet masterSheet) { + _masterSheet = masterSheet; + _sharedCellsByRowCol = new HashMap(); + } + + public EvaluationCell getCell(int rowIndex, int columnIndex) { + RowColKey key = new RowColKey(rowIndex, columnIndex); + + ForkedEvaluationCell result = _sharedCellsByRowCol.get(key); + if (result == null) { + return _masterSheet.getCell(rowIndex, columnIndex); + } + return result; + } + + public ForkedEvaluationCell getOrCreateUpdatableCell(int rowIndex, int columnIndex) { + RowColKey key = new RowColKey(rowIndex, columnIndex); + + ForkedEvaluationCell result = _sharedCellsByRowCol.get(key); + if (result == null) { + EvaluationCell mcell = _masterSheet.getCell(rowIndex, columnIndex); + result = new ForkedEvaluationCell(this, mcell); + _sharedCellsByRowCol.put(key, result); + } + return result; + } + + public void copyUpdatedCells(Sheet sheet) { + RowColKey[] keys = new RowColKey[_sharedCellsByRowCol.size()]; + _sharedCellsByRowCol.keySet().toArray(keys); + Arrays.sort(keys); + for (int i = 0; i < keys.length; i++) { + RowColKey key = keys[i]; + Row row = sheet.getRow(key.getRowIndex()); + if (row == null) { + row = sheet.createRow(key.getRowIndex()); + } + Cell destCell = row.getCell(key.getColumnIndex()); + if (destCell == null) { + destCell = row.createCell(key.getColumnIndex()); + } + + ForkedEvaluationCell srcCell = _sharedCellsByRowCol.get(key); + srcCell.copyValue(destCell); + } + } + + public int getSheetIndex(EvaluationWorkbook mewb) { + return mewb.getSheetIndex(_masterSheet); + } + + private static final class RowColKey implements Comparable{ + private final int _rowIndex; + private final int _columnIndex; + + public RowColKey(int rowIndex, int columnIndex) { + _rowIndex = rowIndex; + _columnIndex = columnIndex; + } + @Override + public boolean equals(Object obj) { + RowColKey other = (RowColKey) obj; + return _rowIndex == other._rowIndex && _columnIndex == other._columnIndex; + } + @Override + public int hashCode() { + return _rowIndex ^ _columnIndex; + } + public int compareTo(RowColKey o) { + int cmp = _rowIndex - o._rowIndex; + if (cmp != 0) { + return cmp; + } + return _columnIndex - o._columnIndex; + } + public int getRowIndex() { + return _rowIndex; + } + public int getColumnIndex() { + return _columnIndex; + } + } +} diff --git a/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationWorkbook.java b/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationWorkbook.java index d7e158f6ff..08c7841197 100644 --- a/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationWorkbook.java +++ b/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationWorkbook.java @@ -1,144 +1,144 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval.forked; - -import java.util.HashMap; -import java.util.Map; - -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.EvaluationCell; -import org.apache.poi.ss.formula.EvaluationName; -import org.apache.poi.ss.formula.EvaluationSheet; -import org.apache.poi.ss.formula.EvaluationWorkbook; -import org.apache.poi.ss.usermodel.Workbook; - -/** - * Represents a workbook being used for forked evaluation. Most operations are delegated to the - * shared master workbook, except those that potentially involve cell values that may have been - * updated after a call to {@link #getOrCreateUpdatableCell(String, int, int)}. - * - * @author Josh Micich - */ -final class ForkedEvaluationWorkbook implements EvaluationWorkbook { - - private final EvaluationWorkbook _masterBook; - private final Map _sharedSheetsByName; - - public ForkedEvaluationWorkbook(EvaluationWorkbook master) { - _masterBook = master; - _sharedSheetsByName = new HashMap(); - } - - public ForkedEvaluationCell getOrCreateUpdatableCell(String sheetName, int rowIndex, - int columnIndex) { - ForkedEvaluationSheet sheet = getSharedSheet(sheetName); - return sheet.getOrCreateUpdatableCell(rowIndex, columnIndex); - } - - public EvaluationCell getEvaluationCell(String sheetName, int rowIndex, int columnIndex) { - ForkedEvaluationSheet sheet = getSharedSheet(sheetName); - return sheet.getCell(rowIndex, columnIndex); - } - - private ForkedEvaluationSheet getSharedSheet(String sheetName) { - ForkedEvaluationSheet result = _sharedSheetsByName.get(sheetName); - if (result == null) { - result = new ForkedEvaluationSheet(_masterBook.getSheet(_masterBook - .getSheetIndex(sheetName))); - _sharedSheetsByName.put(sheetName, result); - } - return result; - } - - public void copyUpdatedCells(Workbook workbook) { - String[] sheetNames = new String[_sharedSheetsByName.size()]; - _sharedSheetsByName.keySet().toArray(sheetNames); - OrderedSheet[] oss = new OrderedSheet[sheetNames.length]; - for (int i = 0; i < sheetNames.length; i++) { - String sheetName = sheetNames[i]; - oss[i] = new OrderedSheet(sheetName, _masterBook.getSheetIndex(sheetName)); - } - for (int i = 0; i < oss.length; i++) { - String sheetName = oss[i].getSheetName(); - ForkedEvaluationSheet sheet = _sharedSheetsByName.get(sheetName); - sheet.copyUpdatedCells(workbook.getSheet(sheetName)); - } - } - - public int convertFromExternSheetIndex(int externSheetIndex) { - return _masterBook.convertFromExternSheetIndex(externSheetIndex); - } - - public ExternalSheet getExternalSheet(int externSheetIndex) { - return _masterBook.getExternalSheet(externSheetIndex); - } - - public Ptg[] getFormulaTokens(EvaluationCell cell) { - if (cell instanceof ForkedEvaluationCell) { - // doesn't happen yet because formulas cannot be modified from the master workbook - throw new RuntimeException("Updated formulas not supported yet"); - } - return _masterBook.getFormulaTokens(cell); - } - - public EvaluationName getName(NamePtg namePtg) { - return _masterBook.getName(namePtg); - } - - public EvaluationSheet getSheet(int sheetIndex) { - return getSharedSheet(getSheetName(sheetIndex)); - } - - public int getSheetIndex(EvaluationSheet sheet) { - if (sheet instanceof ForkedEvaluationSheet) { - ForkedEvaluationSheet mes = (ForkedEvaluationSheet) sheet; - return mes.getSheetIndex(_masterBook); - } - return _masterBook.getSheetIndex(sheet); - } - - public int getSheetIndex(String sheetName) { - return _masterBook.getSheetIndex(sheetName); - } - - public String getSheetName(int sheetIndex) { - return _masterBook.getSheetName(sheetIndex); - } - - public String resolveNameXText(NameXPtg ptg) { - return _masterBook.resolveNameXText(ptg); - } - - private static final class OrderedSheet implements Comparable { - private final String _sheetName; - private final int _index; - - public OrderedSheet(String sheetName, int index) { - _sheetName = sheetName; - _index = index; - } - public String getSheetName() { - return _sheetName; - } - public int compareTo(OrderedSheet o) { - return _index - o._index; - } - } -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.formula.eval.forked; + +import java.util.HashMap; +import java.util.Map; + +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.EvaluationCell; +import org.apache.poi.ss.formula.EvaluationName; +import org.apache.poi.ss.formula.EvaluationSheet; +import org.apache.poi.ss.formula.EvaluationWorkbook; +import org.apache.poi.ss.usermodel.Workbook; + +/** + * Represents a workbook being used for forked evaluation. Most operations are delegated to the + * shared master workbook, except those that potentially involve cell values that may have been + * updated after a call to {@link #getOrCreateUpdatableCell(String, int, int)}. + * + * @author Josh Micich + */ +final class ForkedEvaluationWorkbook implements EvaluationWorkbook { + + private final EvaluationWorkbook _masterBook; + private final Map _sharedSheetsByName; + + public ForkedEvaluationWorkbook(EvaluationWorkbook master) { + _masterBook = master; + _sharedSheetsByName = new HashMap(); + } + + public ForkedEvaluationCell getOrCreateUpdatableCell(String sheetName, int rowIndex, + int columnIndex) { + ForkedEvaluationSheet sheet = getSharedSheet(sheetName); + return sheet.getOrCreateUpdatableCell(rowIndex, columnIndex); + } + + public EvaluationCell getEvaluationCell(String sheetName, int rowIndex, int columnIndex) { + ForkedEvaluationSheet sheet = getSharedSheet(sheetName); + return sheet.getCell(rowIndex, columnIndex); + } + + private ForkedEvaluationSheet getSharedSheet(String sheetName) { + ForkedEvaluationSheet result = _sharedSheetsByName.get(sheetName); + if (result == null) { + result = new ForkedEvaluationSheet(_masterBook.getSheet(_masterBook + .getSheetIndex(sheetName))); + _sharedSheetsByName.put(sheetName, result); + } + return result; + } + + public void copyUpdatedCells(Workbook workbook) { + String[] sheetNames = new String[_sharedSheetsByName.size()]; + _sharedSheetsByName.keySet().toArray(sheetNames); + OrderedSheet[] oss = new OrderedSheet[sheetNames.length]; + for (int i = 0; i < sheetNames.length; i++) { + String sheetName = sheetNames[i]; + oss[i] = new OrderedSheet(sheetName, _masterBook.getSheetIndex(sheetName)); + } + for (int i = 0; i < oss.length; i++) { + String sheetName = oss[i].getSheetName(); + ForkedEvaluationSheet sheet = _sharedSheetsByName.get(sheetName); + sheet.copyUpdatedCells(workbook.getSheet(sheetName)); + } + } + + public int convertFromExternSheetIndex(int externSheetIndex) { + return _masterBook.convertFromExternSheetIndex(externSheetIndex); + } + + public ExternalSheet getExternalSheet(int externSheetIndex) { + return _masterBook.getExternalSheet(externSheetIndex); + } + + public Ptg[] getFormulaTokens(EvaluationCell cell) { + if (cell instanceof ForkedEvaluationCell) { + // doesn't happen yet because formulas cannot be modified from the master workbook + throw new RuntimeException("Updated formulas not supported yet"); + } + return _masterBook.getFormulaTokens(cell); + } + + public EvaluationName getName(NamePtg namePtg) { + return _masterBook.getName(namePtg); + } + + public EvaluationSheet getSheet(int sheetIndex) { + return getSharedSheet(getSheetName(sheetIndex)); + } + + public int getSheetIndex(EvaluationSheet sheet) { + if (sheet instanceof ForkedEvaluationSheet) { + ForkedEvaluationSheet mes = (ForkedEvaluationSheet) sheet; + return mes.getSheetIndex(_masterBook); + } + return _masterBook.getSheetIndex(sheet); + } + + public int getSheetIndex(String sheetName) { + return _masterBook.getSheetIndex(sheetName); + } + + public String getSheetName(int sheetIndex) { + return _masterBook.getSheetName(sheetIndex); + } + + public String resolveNameXText(NameXPtg ptg) { + return _masterBook.resolveNameXText(ptg); + } + + private static final class OrderedSheet implements Comparable { + private final String _sheetName; + private final int _index; + + public OrderedSheet(String sheetName, int index) { + _sheetName = sheetName; + _index = index; + } + public String getSheetName() { + return _sheetName; + } + public int compareTo(OrderedSheet o) { + return _index - o._index; + } + } +} diff --git a/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluator.java b/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluator.java index 6a1e1b1505..e89d2a6104 100644 --- a/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluator.java +++ b/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluator.java @@ -1,133 +1,133 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.formula.eval.forked; - -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.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment; -import org.apache.poi.ss.formula.EvaluationCell; -import org.apache.poi.ss.formula.EvaluationWorkbook; -import org.apache.poi.ss.formula.IStabilityClassifier; -import org.apache.poi.ss.formula.WorkbookEvaluator; -import org.apache.poi.ss.usermodel.Workbook; - -/** - * An alternative workbook evaluator that saves memory in situations where a single workbook is - * concurrently and independently evaluated many times. With standard formula evaluation, around - * 90% of memory consumption is due to loading of the {@link HSSFWorkbook} or {@link org.apache.poi.xssf.usermodel.XSSFWorkbook}. - * This class enables a 'master workbook' to be loaded just once and shared between many evaluation - * clients. Each evaluation client creates its own {@link ForkedEvaluator} and can set cell values - * that will be used for local evaluations (and don't disturb evaluations on other evaluators). - * - * @author Josh Micich - */ -public final class ForkedEvaluator { - - private WorkbookEvaluator _evaluator; - private ForkedEvaluationWorkbook _sewb; - - private ForkedEvaluator(EvaluationWorkbook masterWorkbook, IStabilityClassifier stabilityClassifier) { - _sewb = new ForkedEvaluationWorkbook(masterWorkbook); - _evaluator = new WorkbookEvaluator(_sewb, stabilityClassifier); - } - private static EvaluationWorkbook createEvaluationWorkbook(Workbook wb) { - if (wb instanceof HSSFWorkbook) { - return HSSFEvaluationWorkbook.create((HSSFWorkbook) wb); - } -// TODO rearrange POI build to allow this -// if (wb instanceof XSSFWorkbook) { -// return XSSFEvaluationWorkbook.create((XSSFWorkbook) wb); -// } - throw new IllegalArgumentException("Unexpected workbook type (" + wb.getClass().getName() + ")"); - } - public static ForkedEvaluator create(Workbook wb, IStabilityClassifier stabilityClassifier) { - return new ForkedEvaluator(createEvaluationWorkbook(wb), stabilityClassifier); - } - - /** - * Sets the specified cell to the supplied value - * @param sheetName the name of the sheet containing the cell - * @param rowIndex zero based - * @param columnIndex zero based - */ - public void updateCell(String sheetName, int rowIndex, int columnIndex, ValueEval value) { - - ForkedEvaluationCell cell = _sewb.getOrCreateUpdatableCell(sheetName, rowIndex, columnIndex); - cell.setValue(value); - _evaluator.notifyUpdateCell(cell); - } - /** - * Copies the values of all updated cells (modified by calls to {@link - * #updateCell(String, int, int, ValueEval)}) to the supplied workbook.
          - * Typically, the supplied workbook is a writable copy of the 'master workbook', - * but at the very least it must contain sheets with the same names. - */ - public void copyUpdatedCells(Workbook workbook) { - _sewb.copyUpdatedCells(workbook); - } - - /** - * 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 null signifying that the cell is not present (or blank) - * @return null if the supplied cell is null or blank - */ - public ValueEval evaluate(String sheetName, int rowIndex, int columnIndex) { - EvaluationCell cell = _sewb.getEvaluationCell(sheetName, rowIndex, columnIndex); - - switch (cell.getCellType()) { - case HSSFCell.CELL_TYPE_BOOLEAN: - return BoolEval.valueOf(cell.getBooleanCellValue()); - case HSSFCell.CELL_TYPE_ERROR: - return ErrorEval.valueOf(cell.getErrorCellValue()); - case HSSFCell.CELL_TYPE_FORMULA: - return _evaluator.evaluate(cell); - case HSSFCell.CELL_TYPE_NUMERIC: - return new NumberEval(cell.getNumericCellValue()); - case HSSFCell.CELL_TYPE_STRING: - return new StringEval(cell.getStringCellValue()); - case HSSFCell.CELL_TYPE_BLANK: - return null; - } - throw new IllegalStateException("Bad cell type (" + cell.getCellType() + ")"); - } - /** - * 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, ForkedEvaluator[] evaluators) { - WorkbookEvaluator[] wbEvals = new WorkbookEvaluator[evaluators.length]; - for (int i = 0; i < wbEvals.length; i++) { - wbEvals[i] = evaluators[i]._evaluator; - } - CollaboratingWorkbooksEnvironment.setup(workbookNames, wbEvals); - } -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.formula.eval.forked; + +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.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment; +import org.apache.poi.ss.formula.EvaluationCell; +import org.apache.poi.ss.formula.EvaluationWorkbook; +import org.apache.poi.ss.formula.IStabilityClassifier; +import org.apache.poi.ss.formula.WorkbookEvaluator; +import org.apache.poi.ss.usermodel.Workbook; + +/** + * An alternative workbook evaluator that saves memory in situations where a single workbook is + * concurrently and independently evaluated many times. With standard formula evaluation, around + * 90% of memory consumption is due to loading of the {@link HSSFWorkbook} or {@link org.apache.poi.xssf.usermodel.XSSFWorkbook}. + * This class enables a 'master workbook' to be loaded just once and shared between many evaluation + * clients. Each evaluation client creates its own {@link ForkedEvaluator} and can set cell values + * that will be used for local evaluations (and don't disturb evaluations on other evaluators). + * + * @author Josh Micich + */ +public final class ForkedEvaluator { + + private WorkbookEvaluator _evaluator; + private ForkedEvaluationWorkbook _sewb; + + private ForkedEvaluator(EvaluationWorkbook masterWorkbook, IStabilityClassifier stabilityClassifier) { + _sewb = new ForkedEvaluationWorkbook(masterWorkbook); + _evaluator = new WorkbookEvaluator(_sewb, stabilityClassifier); + } + private static EvaluationWorkbook createEvaluationWorkbook(Workbook wb) { + if (wb instanceof HSSFWorkbook) { + return HSSFEvaluationWorkbook.create((HSSFWorkbook) wb); + } +// TODO rearrange POI build to allow this +// if (wb instanceof XSSFWorkbook) { +// return XSSFEvaluationWorkbook.create((XSSFWorkbook) wb); +// } + throw new IllegalArgumentException("Unexpected workbook type (" + wb.getClass().getName() + ")"); + } + public static ForkedEvaluator create(Workbook wb, IStabilityClassifier stabilityClassifier) { + return new ForkedEvaluator(createEvaluationWorkbook(wb), stabilityClassifier); + } + + /** + * Sets the specified cell to the supplied value + * @param sheetName the name of the sheet containing the cell + * @param rowIndex zero based + * @param columnIndex zero based + */ + public void updateCell(String sheetName, int rowIndex, int columnIndex, ValueEval value) { + + ForkedEvaluationCell cell = _sewb.getOrCreateUpdatableCell(sheetName, rowIndex, columnIndex); + cell.setValue(value); + _evaluator.notifyUpdateCell(cell); + } + /** + * Copies the values of all updated cells (modified by calls to {@link + * #updateCell(String, int, int, ValueEval)}) to the supplied workbook.
          + * Typically, the supplied workbook is a writable copy of the 'master workbook', + * but at the very least it must contain sheets with the same names. + */ + public void copyUpdatedCells(Workbook workbook) { + _sewb.copyUpdatedCells(workbook); + } + + /** + * 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 null signifying that the cell is not present (or blank) + * @return null if the supplied cell is null or blank + */ + public ValueEval evaluate(String sheetName, int rowIndex, int columnIndex) { + EvaluationCell cell = _sewb.getEvaluationCell(sheetName, rowIndex, columnIndex); + + switch (cell.getCellType()) { + case HSSFCell.CELL_TYPE_BOOLEAN: + return BoolEval.valueOf(cell.getBooleanCellValue()); + case HSSFCell.CELL_TYPE_ERROR: + return ErrorEval.valueOf(cell.getErrorCellValue()); + case HSSFCell.CELL_TYPE_FORMULA: + return _evaluator.evaluate(cell); + case HSSFCell.CELL_TYPE_NUMERIC: + return new NumberEval(cell.getNumericCellValue()); + case HSSFCell.CELL_TYPE_STRING: + return new StringEval(cell.getStringCellValue()); + case HSSFCell.CELL_TYPE_BLANK: + return null; + } + throw new IllegalStateException("Bad cell type (" + cell.getCellType() + ")"); + } + /** + * 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, ForkedEvaluator[] evaluators) { + WorkbookEvaluator[] wbEvals = new WorkbookEvaluator[evaluators.length]; + for (int i = 0; i < wbEvals.length; i++) { + wbEvals[i] = evaluators[i]._evaluator; + } + CollaboratingWorkbooksEnvironment.setup(workbookNames, wbEvals); + } +} diff --git a/src/java/org/apache/poi/ss/usermodel/CellValue.java b/src/java/org/apache/poi/ss/usermodel/CellValue.java index 705f557101..664f100562 100644 --- a/src/java/org/apache/poi/ss/usermodel/CellValue.java +++ b/src/java/org/apache/poi/ss/usermodel/CellValue.java @@ -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.ss.usermodel; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.ss.usermodel.Cell; - -/** - * Mimics the 'data view' of a cell. This allows formula evaluator - * to return a CellValue instead of precasting the value to String - * or Number or boolean type. - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public final class CellValue { - public static final CellValue TRUE = new CellValue(Cell.CELL_TYPE_BOOLEAN, 0.0, true, null, 0); - public static final CellValue FALSE= new CellValue(Cell.CELL_TYPE_BOOLEAN, 0.0, false, null, 0); - - private final int _cellType; - private final double _numberValue; - private final boolean _booleanValue; - private final String _textValue; - private final int _errorCode; - - private CellValue(int cellType, double numberValue, boolean booleanValue, - String textValue, int errorCode) { - _cellType = cellType; - _numberValue = numberValue; - _booleanValue = booleanValue; - _textValue = textValue; - _errorCode = errorCode; - } - - - public CellValue(double numberValue) { - this(Cell.CELL_TYPE_NUMERIC, numberValue, false, null, 0); - } - public static CellValue valueOf(boolean booleanValue) { - return booleanValue ? TRUE : FALSE; - } - public CellValue(String stringValue) { - this(Cell.CELL_TYPE_STRING, 0.0, false, stringValue, 0); - } - public static CellValue getError(int errorCode) { - return new CellValue(Cell.CELL_TYPE_ERROR, 0.0, false, null, errorCode); - } - - - /** - * @return Returns the booleanValue. - */ - public boolean getBooleanValue() { - return _booleanValue; - } - /** - * @return Returns the numberValue. - */ - public double getNumberValue() { - return _numberValue; - } - /** - * @return Returns the stringValue. - */ - public String getStringValue() { - return _textValue; - } - /** - * @return Returns the cellType. - */ - public int getCellType() { - return _cellType; - } - /** - * @return Returns the errorValue. - */ - public byte getErrorValue() { - return (byte) _errorCode; - } - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(formatAsString()); - sb.append("]"); - return sb.toString(); - } - - public String formatAsString() { - switch (_cellType) { - case Cell.CELL_TYPE_NUMERIC: - return String.valueOf(_numberValue); - case Cell.CELL_TYPE_STRING: - return '"' + _textValue + '"'; - case Cell.CELL_TYPE_BOOLEAN: - return _booleanValue ? "TRUE" : "FALSE"; - case Cell.CELL_TYPE_ERROR: - return ErrorEval.getText(_errorCode); - } - return ""; - } -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.usermodel; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.ss.usermodel.Cell; + +/** + * Mimics the 'data view' of a cell. This allows formula evaluator + * to return a CellValue instead of precasting the value to String + * or Number or boolean type. + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + */ +public final class CellValue { + public static final CellValue TRUE = new CellValue(Cell.CELL_TYPE_BOOLEAN, 0.0, true, null, 0); + public static final CellValue FALSE= new CellValue(Cell.CELL_TYPE_BOOLEAN, 0.0, false, null, 0); + + private final int _cellType; + private final double _numberValue; + private final boolean _booleanValue; + private final String _textValue; + private final int _errorCode; + + private CellValue(int cellType, double numberValue, boolean booleanValue, + String textValue, int errorCode) { + _cellType = cellType; + _numberValue = numberValue; + _booleanValue = booleanValue; + _textValue = textValue; + _errorCode = errorCode; + } + + + public CellValue(double numberValue) { + this(Cell.CELL_TYPE_NUMERIC, numberValue, false, null, 0); + } + public static CellValue valueOf(boolean booleanValue) { + return booleanValue ? TRUE : FALSE; + } + public CellValue(String stringValue) { + this(Cell.CELL_TYPE_STRING, 0.0, false, stringValue, 0); + } + public static CellValue getError(int errorCode) { + return new CellValue(Cell.CELL_TYPE_ERROR, 0.0, false, null, errorCode); + } + + + /** + * @return Returns the booleanValue. + */ + public boolean getBooleanValue() { + return _booleanValue; + } + /** + * @return Returns the numberValue. + */ + public double getNumberValue() { + return _numberValue; + } + /** + * @return Returns the stringValue. + */ + public String getStringValue() { + return _textValue; + } + /** + * @return Returns the cellType. + */ + public int getCellType() { + return _cellType; + } + /** + * @return Returns the errorValue. + */ + public byte getErrorValue() { + return (byte) _errorCode; + } + public String toString() { + StringBuffer sb = new StringBuffer(64); + sb.append(getClass().getName()).append(" ["); + sb.append(formatAsString()); + sb.append("]"); + return sb.toString(); + } + + public String formatAsString() { + switch (_cellType) { + case Cell.CELL_TYPE_NUMERIC: + return String.valueOf(_numberValue); + case Cell.CELL_TYPE_STRING: + return '"' + _textValue + '"'; + case Cell.CELL_TYPE_BOOLEAN: + return _booleanValue ? "TRUE" : "FALSE"; + case Cell.CELL_TYPE_ERROR: + return ErrorEval.getText(_errorCode); + } + return ""; + } +} diff --git a/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java b/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java index 6a51a7288c..a4e66635ca 100755 --- a/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java +++ b/src/java/org/apache/poi/ss/usermodel/ClientAnchor.java @@ -1,202 +1,202 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -/** - * A client anchor is attached to an excel worksheet. It anchors against a - * top-left and bottom-right cell. - * - * @author Yegor Kozlov - */ -public interface ClientAnchor { - /** - * Move and Resize With Anchor Cells - *

          - * Specifies that the current drawing shall move and - * resize to maintain its row and column anchors (i.e. the - * object is anchored to the actual from and to row and column) - *

          - */ - public static final int MOVE_AND_RESIZE = 0; - - /** - * Move With Cells but Do Not Resize - *

          - * Specifies that the current drawing shall move with its - * row and column (i.e. the object is anchored to the - * actual from row and column), but that the size shall remain absolute. - *

          - *

          - * If additional rows/columns are added between the from and to locations of the drawing, - * the drawing shall move its to anchors as needed to maintain this same absolute size. - *

          - */ - public static final int MOVE_DONT_RESIZE = 2; - - /** - * Do Not Move or Resize With Underlying Rows/Columns - *

          - * Specifies that the current start and end positions shall - * be maintained with respect to the distances from the - * absolute start point of the worksheet. - *

          - *

          - * If additional rows/columns are added before the - * drawing, the drawing shall move its anchors as needed - * to maintain this same absolute position. - *

          - */ - public static final int DONT_MOVE_AND_RESIZE = 3; - - /** - * Returns the column (0 based) of the first cell. - * - * @return 0-based column of the first cell. - */ - public short getCol1(); - - /** - * Sets the column (0 based) of the first cell. - * - * @param col1 0-based column of the first cell. - */ - public void setCol1(int col1); - - /** - * Returns the column (0 based) of the second cell. - * - * @return 0-based column of the second cell. - */ - public short getCol2(); - - /** - * Returns the column (0 based) of the second cell. - * - * @param col2 0-based column of the second cell. - */ - public void setCol2(int col2); - - /** - * Returns the row (0 based) of the first cell. - * - * @return 0-based row of the first cell. - */ - public int getRow1(); - - /** - * Returns the row (0 based) of the first cell. - * - * @param row1 0-based row of the first cell. - */ - public void setRow1(int row1); - - /** - * Returns the row (0 based) of the second cell. - * - * @return 0-based row of the second cell. - */ - public int getRow2(); - - /** - * Returns the row (0 based) of the first cell. - * - * @param row2 0-based row of the first cell. - */ - public void setRow2(int row2); - - /** - * Returns the x coordinate within the first cell - * - * @return the x coordinate within the first cell - */ - public int getDx1(); - - /** - * Sets the x coordinate within the first cell - * - * @param dx1 the x coordinate within the first cell - */ - public void setDx1(int dx1); - - /** - * Returns the y coordinate within the first cell - * - * @return the y coordinate within the first cell - */ - public int getDy1(); - - /** - * Sets the y coordinate within the first cell - * - * @param dy1 the y coordinate within the first cell - */ - public void setDy1(int dy1); - - /** - * Sets the y coordinate within the second cell - * - * @return the y coordinate within the second cell - */ - public int getDy2(); - - /** - * Sets the y coordinate within the second cell - * - * @param dy2 the y coordinate within the second cell - */ - public void setDy2(int dy2); - - /** - * Returns the x coordinate within the second cell - * - * @return the x coordinate within the second cell - */ - public int getDx2(); - - /** - * Sets the x coordinate within the second cell - * - * @param dx2 the x coordinate within the second cell - */ - public void setDx2(int dx2); - - - /** - * Sets the anchor type - *

          - * 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells. - *

          - * @param anchorType the anchor type - * @see #MOVE_AND_RESIZE - * @see #MOVE_DONT_RESIZE - * @see #DONT_MOVE_AND_RESIZE - */ - public void setAnchorType( int anchorType ); - - /** - * Gets the anchor type - *

          - * 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells. - *

          - * @return the anchor type - * @see #MOVE_AND_RESIZE - * @see #MOVE_DONT_RESIZE - * @see #DONT_MOVE_AND_RESIZE - */ - public int getAnchorType(); - -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +package org.apache.poi.ss.usermodel; + +/** + * A client anchor is attached to an excel worksheet. It anchors against a + * top-left and bottom-right cell. + * + * @author Yegor Kozlov + */ +public interface ClientAnchor { + /** + * Move and Resize With Anchor Cells + *

          + * Specifies that the current drawing shall move and + * resize to maintain its row and column anchors (i.e. the + * object is anchored to the actual from and to row and column) + *

          + */ + public static final int MOVE_AND_RESIZE = 0; + + /** + * Move With Cells but Do Not Resize + *

          + * Specifies that the current drawing shall move with its + * row and column (i.e. the object is anchored to the + * actual from row and column), but that the size shall remain absolute. + *

          + *

          + * If additional rows/columns are added between the from and to locations of the drawing, + * the drawing shall move its to anchors as needed to maintain this same absolute size. + *

          + */ + public static final int MOVE_DONT_RESIZE = 2; + + /** + * Do Not Move or Resize With Underlying Rows/Columns + *

          + * Specifies that the current start and end positions shall + * be maintained with respect to the distances from the + * absolute start point of the worksheet. + *

          + *

          + * If additional rows/columns are added before the + * drawing, the drawing shall move its anchors as needed + * to maintain this same absolute position. + *

          + */ + public static final int DONT_MOVE_AND_RESIZE = 3; + + /** + * Returns the column (0 based) of the first cell. + * + * @return 0-based column of the first cell. + */ + public short getCol1(); + + /** + * Sets the column (0 based) of the first cell. + * + * @param col1 0-based column of the first cell. + */ + public void setCol1(int col1); + + /** + * Returns the column (0 based) of the second cell. + * + * @return 0-based column of the second cell. + */ + public short getCol2(); + + /** + * Returns the column (0 based) of the second cell. + * + * @param col2 0-based column of the second cell. + */ + public void setCol2(int col2); + + /** + * Returns the row (0 based) of the first cell. + * + * @return 0-based row of the first cell. + */ + public int getRow1(); + + /** + * Returns the row (0 based) of the first cell. + * + * @param row1 0-based row of the first cell. + */ + public void setRow1(int row1); + + /** + * Returns the row (0 based) of the second cell. + * + * @return 0-based row of the second cell. + */ + public int getRow2(); + + /** + * Returns the row (0 based) of the first cell. + * + * @param row2 0-based row of the first cell. + */ + public void setRow2(int row2); + + /** + * Returns the x coordinate within the first cell + * + * @return the x coordinate within the first cell + */ + public int getDx1(); + + /** + * Sets the x coordinate within the first cell + * + * @param dx1 the x coordinate within the first cell + */ + public void setDx1(int dx1); + + /** + * Returns the y coordinate within the first cell + * + * @return the y coordinate within the first cell + */ + public int getDy1(); + + /** + * Sets the y coordinate within the first cell + * + * @param dy1 the y coordinate within the first cell + */ + public void setDy1(int dy1); + + /** + * Sets the y coordinate within the second cell + * + * @return the y coordinate within the second cell + */ + public int getDy2(); + + /** + * Sets the y coordinate within the second cell + * + * @param dy2 the y coordinate within the second cell + */ + public void setDy2(int dy2); + + /** + * Returns the x coordinate within the second cell + * + * @return the x coordinate within the second cell + */ + public int getDx2(); + + /** + * Sets the x coordinate within the second cell + * + * @param dx2 the x coordinate within the second cell + */ + public void setDx2(int dx2); + + + /** + * Sets the anchor type + *

          + * 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells. + *

          + * @param anchorType the anchor type + * @see #MOVE_AND_RESIZE + * @see #MOVE_DONT_RESIZE + * @see #DONT_MOVE_AND_RESIZE + */ + public void setAnchorType( int anchorType ); + + /** + * Gets the anchor type + *

          + * 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells. + *

          + * @return the anchor type + * @see #MOVE_AND_RESIZE + * @see #MOVE_DONT_RESIZE + * @see #DONT_MOVE_AND_RESIZE + */ + public int getAnchorType(); + +} diff --git a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java index 50e3690f7c..f402a0cfab 100755 --- a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java +++ b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java @@ -1,665 +1,665 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -import java.util.regex.Pattern; -import java.util.regex.Matcher; -import java.util.*; -import java.text.*; - -/** - * DataFormatter contains methods for formatting the value stored in an - * Cell. This can be useful for reports and GUI presentations when you - * need to display data exactly as it appears in Excel. Supported formats - * include currency, SSN, percentages, decimals, dates, phone numbers, zip - * codes, etc. - *

          - * Internally, formats will be implemented using subclasses of {@link Format} - * such as {@link DecimalFormat} and {@link SimpleDateFormat}. Therefore the - * formats used by this class must obey the same pattern rules as these Format - * subclasses. This means that only legal number pattern characters ("0", "#", - * ".", "," etc.) may appear in number formats. Other characters can be - * inserted before or after the number pattern to form a - * prefix or suffix. - *

          - *

          - * For example the Excel pattern "$#,##0.00 "USD"_);($#,##0.00 "USD")" - * will be correctly formatted as "$1,000.00 USD" or "($1,000.00 USD)". - * However the pattern "00-00-00" is incorrectly formatted by - * DecimalFormat as "000000--". For Excel formats that are not compatible with - * DecimalFormat, you can provide your own custom {@link Format} implementation - * via DataFormatter.addFormat(String,Format). The following - * custom formats are already provided by this class: - *

          - *
          - * 
          • SSN "000-00-0000"
          • - *
          • Phone Number "(###) ###-####"
          • - *
          • Zip plus 4 "00000-0000"
          • - *
          - *
          - *

          - * If the Excel format pattern cannot be parsed successfully, then a default - * format will be used. The default number format will mimic the Excel General - * format: "#" for whole numbers and "#.##########" for decimal numbers. You - * can override the default format pattern with - * DataFormatter.setDefaultNumberFormat(Format). Note: the - * default format will only be used when a Format cannot be created from the - * cell's data format string. - * - * @author James May (james dot may at fmr dot com) - * - */ -public class DataFormatter { - - /** Pattern to find a number format: "0" or "#" */ - private static final Pattern numPattern = Pattern.compile("[0#]+"); - - /** Pattern to find days of week as text "ddd...." */ - private static final Pattern daysAsText = Pattern.compile("([d]{3,})", Pattern.CASE_INSENSITIVE); - - /** Pattern to find "AM/PM" marker */ - private static final Pattern amPmPattern = Pattern.compile("((A|P)[M/P]*)", Pattern.CASE_INSENSITIVE); - - /** A regex to find patterns like [$$-1009] and [$?-452]. */ - private static final Pattern specialPatternGroup = Pattern.compile("(\\[\\$[^-\\]]*-[0-9A-Z]+\\])"); - - /** General format for whole numbers. */ - private static final Format generalWholeNumFormat = new DecimalFormat("#"); - - /** General format for decimal numbers. */ - private static final Format generalDecimalNumFormat = new DecimalFormat("#.##########"); - - /** A default format to use when a number pattern cannot be parsed. */ - private Format defaultNumFormat; - - /** - * A map to cache formats. - * Map formats - */ - private final Map formats; - - /** - * Constructor - */ - public DataFormatter() { - formats = new HashMap(); - - // init built-in formats - - Format zipFormat = ZipPlusFourFormat.instance; - addFormat("00000\\-0000", zipFormat); - addFormat("00000-0000", zipFormat); - - Format phoneFormat = PhoneFormat.instance; - // allow for format string variations - addFormat("[<=9999999]###\\-####;\\(###\\)\\ ###\\-####", phoneFormat); - addFormat("[<=9999999]###-####;(###) ###-####", phoneFormat); - addFormat("###\\-####;\\(###\\)\\ ###\\-####", phoneFormat); - addFormat("###-####;(###) ###-####", phoneFormat); - - Format ssnFormat = SSNFormat.instance; - addFormat("000\\-00\\-0000", ssnFormat); - addFormat("000-00-0000", ssnFormat); - } - - /** - * Return a Format for the given cell if one exists, otherwise try to - * create one. This method will return null if the any of the - * following is true: - *

            - *
          • the cell's style is null
          • - *
          • the style's data format string is null or empty
          • - *
          • the format string cannot be recognized as either a number or date
          • - *
          - * - * @param cell The cell to retrieve a Format for - * @return A Format for the format String - */ - private Format getFormat(Cell cell) { - if ( cell.getCellStyle() == null) { - return null; - } - - int formatIndex = cell.getCellStyle().getDataFormat(); - String formatStr = cell.getCellStyle().getDataFormatString(); - if(formatStr == null || formatStr.trim().length() == 0) { - return null; - } - return getFormat(cell.getNumericCellValue(), formatIndex, formatStr); - } - - private Format getFormat(double cellValue, int formatIndex, String formatStr) { - Format format = (Format)formats.get(formatStr); - if (format != null) { - return format; - } - if (formatStr.equals("General") || formatStr.equals("@")) { - if (DataFormatter.isWholeNumber(cellValue)) { - return generalWholeNumFormat; - } - return generalDecimalNumFormat; - } - format = createFormat(cellValue, formatIndex, formatStr); - formats.put(formatStr, format); - return format; - } - - /** - * Create and return a Format based on the format string from a cell's - * style. If the pattern cannot be parsed, return a default pattern. - * - * @param cell The Excel cell - * @return A Format representing the excel format. May return null. - */ - public Format createFormat(Cell cell) { - - int formatIndex = cell.getCellStyle().getDataFormat(); - String formatStr = cell.getCellStyle().getDataFormatString(); - return createFormat(cell.getNumericCellValue(), formatIndex, formatStr); - } - - private Format createFormat(double cellValue, int formatIndex, String sFormat) { - // remove color formatting if present - String formatStr = sFormat.replaceAll("\\[[a-zA-Z]*\\]", ""); - - // try to extract special characters like currency - Matcher m = specialPatternGroup.matcher(formatStr); - while(m.find()) { - String match = m.group(); - String symbol = match.substring(match.indexOf('$') + 1, match.indexOf('-')); - if (symbol.indexOf('$') > -1) { - StringBuffer sb = new StringBuffer(); - sb.append(symbol.substring(0, symbol.indexOf('$'))); - sb.append('\\'); - sb.append(symbol.substring(symbol.indexOf('$'), symbol.length())); - symbol = sb.toString(); - } - formatStr = m.replaceAll(symbol); - m = specialPatternGroup.matcher(formatStr); - } - - if(formatStr == null || formatStr.trim().length() == 0) { - return getDefaultFormat(cellValue); - } - - - if(DateUtil.isADateFormat(formatIndex,formatStr) && - DateUtil.isValidExcelDate(cellValue)) { - return createDateFormat(formatStr, cellValue); - } - if (numPattern.matcher(formatStr).find()) { - return createNumberFormat(formatStr, cellValue); - } - // TODO - when does this occur? - return null; - } - - private Format createDateFormat(String pFormatStr, double cellValue) { - String formatStr = pFormatStr; - formatStr = formatStr.replaceAll("\\\\-","-"); - formatStr = formatStr.replaceAll("\\\\,",","); - formatStr = formatStr.replaceAll("\\\\ "," "); - formatStr = formatStr.replaceAll(";@", ""); - boolean hasAmPm = false; - Matcher amPmMatcher = amPmPattern.matcher(formatStr); - while (amPmMatcher.find()) { - formatStr = amPmMatcher.replaceAll("@"); - hasAmPm = true; - amPmMatcher = amPmPattern.matcher(formatStr); - } - formatStr = formatStr.replaceAll("@", "a"); - - - Matcher dateMatcher = daysAsText.matcher(formatStr); - if (dateMatcher.find()) { - String match = dateMatcher.group(0); - formatStr = dateMatcher.replaceAll(match.toUpperCase().replaceAll("D", "E")); - } - - // Convert excel date format to SimpleDateFormat. - // Excel uses lower case 'm' for both minutes and months. - // From Excel help: - /* - The "m" or "mm" code must appear immediately after the "h" or"hh" - code or immediately before the "ss" code; otherwise, Microsoft - Excel displays the month instead of minutes." - */ - - StringBuffer sb = new StringBuffer(); - char[] chars = formatStr.toCharArray(); - boolean mIsMonth = true; - List ms = new ArrayList(); - for(int j=0; j -1 && sb.charAt(idx -1) == '_') { - sb.deleteCharAt(idx); - sb.deleteCharAt(idx - 1); - sb.deleteCharAt(i); - i--; - } - } else if (c == ')' && i > 0 && sb.charAt(i - 1) == '_') { - sb.deleteCharAt(i); - sb.deleteCharAt(i - 1); - i--; - // remove quotes and back slashes - } else if (c == '\\' || c == '"') { - sb.deleteCharAt(i); - i--; - - // for scientific/engineering notation - } else if (c == '+' && i > 0 && sb.charAt(i - 1) == 'E') { - sb.deleteCharAt(i); - i--; - } - } - - try { - return new DecimalFormat(sb.toString()); - } catch(IllegalArgumentException iae) { - - // the pattern could not be parsed correctly, - // so fall back to the default number format - return getDefaultFormat(cellValue); - } - } - - /** - * Return true if the double value represents a whole number - * @param d the double value to check - * @return true if d is a whole number - */ - private static boolean isWholeNumber(double d) { - return d == Math.floor(d); - } - - /** - * Returns a default format for a cell. - * @param cell The cell - * @return a default format - */ - public Format getDefaultFormat(Cell cell) { - return getDefaultFormat(cell.getNumericCellValue()); - } - private Format getDefaultFormat(double cellValue) { - // for numeric cells try user supplied default - if (defaultNumFormat != null) { - return defaultNumFormat; - - // otherwise use general format - } - if (isWholeNumber(cellValue)){ - return generalWholeNumFormat; - } - return generalDecimalNumFormat; - } - - /** - * Returns the formatted value of an Excel date as a String based - * on the cell's DataFormat. i.e. "Thursday, January 02, 2003" - * , "01/02/2003" , "02-Jan" , etc. - * - * @param cell The cell - * @return a formatted date string - */ - private String getFormattedDateString(Cell cell) { - Format dateFormat = getFormat(cell); - Date d = cell.getDateCellValue(); - if (dateFormat != null) { - return dateFormat.format(d); - } - return d.toString(); - } - - /** - * Returns the formatted value of an Excel number as a String - * based on the cell's DataFormat. Supported formats include - * currency, percents, decimals, phone number, SSN, etc.: - * "61.54%", "$100.00", "(800) 555-1234". - * - * @param cell The cell - * @return a formatted number string - */ - private String getFormattedNumberString(Cell cell) { - - Format numberFormat = getFormat(cell); - double d = cell.getNumericCellValue(); - if (numberFormat == null) { - return String.valueOf(d); - } - return numberFormat.format(new Double(d)); - } - - /** - * Formats the given raw cell value, based on the supplied - * format index and string, according to excel style rules. - * @see #formatCellValue(Cell) - */ - public String formatRawCellContents(double value, int formatIndex, String formatString) { - // Is it a date? - if(DateUtil.isADateFormat(formatIndex,formatString) && - DateUtil.isValidExcelDate(value)) { - - Format dateFormat = getFormat(value, formatIndex, formatString); - Date d = DateUtil.getJavaDate(value); - if (dateFormat == null) { - return d.toString(); - } - return dateFormat.format(d); - } - // else Number - Format numberFormat = getFormat(value, formatIndex, formatString); - if (numberFormat == null) { - return String.valueOf(value); - } - return numberFormat.format(new Double(value)); - } - - /** - *

          - * Returns the formatted value of a cell as a String regardless - * of the cell type. If the Excel format pattern cannot be parsed then the - * cell value will be formatted using a default format. - *

          - *

          When passed a null or blank cell, this method will return an empty - * String (""). Formulas in formula type cells will not be evaluated. - *

          - * - * @param cell The cell - * @return the formatted cell value as a String - */ - public String formatCellValue(Cell cell) { - return formatCellValue(cell, null); - } - - /** - *

          - * Returns the formatted value of a cell as a String regardless - * of the cell type. If the Excel format pattern cannot be parsed then the - * cell value will be formatted using a default format. - *

          - *

          When passed a null or blank cell, this method will return an empty - * String (""). Formula cells will be evaluated using the given - * {@link FormulaEvaluator} if the evaluator is non-null. If the - * evaluator is null, then the formula String will be returned. The caller - * is responsible for setting the currentRow on the evaluator - *

          - * - * @param cell The cell (can be null) - * @param evaluator The FormulaEvaluator (can be null) - * @return a string value of the cell - */ - public String formatCellValue(Cell cell, FormulaEvaluator evaluator) { - - if (cell == null) { - return ""; - } - - int cellType = cell.getCellType(); - if (cellType == Cell.CELL_TYPE_FORMULA) { - if (evaluator == null) { - return cell.getCellFormula(); - } - cellType = evaluator.evaluateFormulaCell(cell); - } - switch (cellType) { - case Cell.CELL_TYPE_NUMERIC : - - if (DateUtil.isCellDateFormatted(cell)) { - return getFormattedDateString(cell); - } - return getFormattedNumberString(cell); - - case Cell.CELL_TYPE_STRING : - return cell.getRichStringCellValue().getString(); - - case Cell.CELL_TYPE_BOOLEAN : - return String.valueOf(cell.getBooleanCellValue()); - case Cell.CELL_TYPE_BLANK : - return ""; - } - throw new RuntimeException("Unexpected celltype (" + cellType + ")"); - } - - - /** - *

          - * Sets a default number format to be used when the Excel format cannot be - * parsed successfully. Note: This is a fall back for when an error - * occurs while parsing an Excel number format pattern. This will not - * affect cells with the General format. - *

          - *

          - * The value that will be passed to the Format's format method (specified - * by java.text.Format#format) will be a double value from a - * numeric cell. Therefore the code in the format method should expect a - * Number value. - *

          - * - * @param format A Format instance to be used as a default - * @see java.text.Format#format - */ - public void setDefaultNumberFormat(Format format) { - Iterator itr = formats.entrySet().iterator(); - while(itr.hasNext()) { - Map.Entry entry = (Map.Entry)itr.next(); - if (entry.getValue() == generalDecimalNumFormat - || entry.getValue() == generalWholeNumFormat) { - entry.setValue(format); - } - } - defaultNumFormat = format; - } - - /** - * Adds a new format to the available formats. - *

          - * The value that will be passed to the Format's format method (specified - * by java.text.Format#format) will be a double value from a - * numeric cell. Therefore the code in the format method should expect a - * Number value. - *

          - * @param excelFormatStr The data format string - * @param format A Format instance - */ - public void addFormat(String excelFormatStr, Format format) { - formats.put(excelFormatStr, format); - } - - // Some custom formats - - /** - * @return a DecimalFormat with parseIntegerOnly set true - */ - /* package */ static DecimalFormat createIntegerOnlyFormat(String fmt) { - DecimalFormat result = new DecimalFormat(fmt); - result.setParseIntegerOnly(true); - return result; - } - /** - * Format class for Excel's SSN format. This class mimics Excel's built-in - * SSN formatting. - * - * @author James May - */ - private static final class SSNFormat extends Format { - public static final Format instance = new SSNFormat(); - private static final DecimalFormat df = createIntegerOnlyFormat("000000000"); - private SSNFormat() { - // enforce singleton - } - - /** Format a number as an SSN */ - public static String format(Number num) { - String result = df.format(num); - StringBuffer sb = new StringBuffer(); - sb.append(result.substring(0, 3)).append('-'); - sb.append(result.substring(3, 5)).append('-'); - sb.append(result.substring(5, 9)); - return sb.toString(); - } - - public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { - return toAppendTo.append(format((Number)obj)); - } - - public Object parseObject(String source, ParsePosition pos) { - return df.parseObject(source, pos); - } - } - - /** - * Format class for Excel Zip + 4 format. This class mimics Excel's - * built-in formatting for Zip + 4. - * @author James May - */ - private static final class ZipPlusFourFormat extends Format { - public static final Format instance = new ZipPlusFourFormat(); - private static final DecimalFormat df = createIntegerOnlyFormat("000000000"); - private ZipPlusFourFormat() { - // enforce singleton - } - - /** Format a number as Zip + 4 */ - public static String format(Number num) { - String result = df.format(num); - StringBuffer sb = new StringBuffer(); - sb.append(result.substring(0, 5)).append('-'); - sb.append(result.substring(5, 9)); - return sb.toString(); - } - - public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { - return toAppendTo.append(format((Number)obj)); - } - - public Object parseObject(String source, ParsePosition pos) { - return df.parseObject(source, pos); - } - } - - /** - * Format class for Excel phone number format. This class mimics Excel's - * built-in phone number formatting. - * @author James May - */ - private static final class PhoneFormat extends Format { - public static final Format instance = new PhoneFormat(); - private static final DecimalFormat df = createIntegerOnlyFormat("##########"); - private PhoneFormat() { - // enforce singleton - } - - /** Format a number as a phone number */ - public static String format(Number num) { - String result = df.format(num); - StringBuffer sb = new StringBuffer(); - String seg1, seg2, seg3; - int len = result.length(); - if (len <= 4) { - return result; - } - - seg3 = result.substring(len - 4, len); - seg2 = result.substring(Math.max(0, len - 7), len - 4); - seg1 = result.substring(Math.max(0, len - 10), Math.max(0, len - 7)); - - if(seg1 != null && seg1.trim().length() > 0) { - sb.append('(').append(seg1).append(") "); - } - if(seg2 != null && seg2.trim().length() > 0) { - sb.append(seg2).append('-'); - } - sb.append(seg3); - return sb.toString(); - } - - public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { - return toAppendTo.append(format((Number)obj)); - } - - public Object parseObject(String source, ParsePosition pos) { - return df.parseObject(source, pos); - } - } -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +package org.apache.poi.ss.usermodel; + +import java.util.regex.Pattern; +import java.util.regex.Matcher; +import java.util.*; +import java.text.*; + +/** + * DataFormatter contains methods for formatting the value stored in an + * Cell. This can be useful for reports and GUI presentations when you + * need to display data exactly as it appears in Excel. Supported formats + * include currency, SSN, percentages, decimals, dates, phone numbers, zip + * codes, etc. + *

          + * Internally, formats will be implemented using subclasses of {@link Format} + * such as {@link DecimalFormat} and {@link SimpleDateFormat}. Therefore the + * formats used by this class must obey the same pattern rules as these Format + * subclasses. This means that only legal number pattern characters ("0", "#", + * ".", "," etc.) may appear in number formats. Other characters can be + * inserted before or after the number pattern to form a + * prefix or suffix. + *

          + *

          + * For example the Excel pattern "$#,##0.00 "USD"_);($#,##0.00 "USD")" + * will be correctly formatted as "$1,000.00 USD" or "($1,000.00 USD)". + * However the pattern "00-00-00" is incorrectly formatted by + * DecimalFormat as "000000--". For Excel formats that are not compatible with + * DecimalFormat, you can provide your own custom {@link Format} implementation + * via DataFormatter.addFormat(String,Format). The following + * custom formats are already provided by this class: + *

          + *
          + * 
          • SSN "000-00-0000"
          • + *
          • Phone Number "(###) ###-####"
          • + *
          • Zip plus 4 "00000-0000"
          • + *
          + *
          + *

          + * If the Excel format pattern cannot be parsed successfully, then a default + * format will be used. The default number format will mimic the Excel General + * format: "#" for whole numbers and "#.##########" for decimal numbers. You + * can override the default format pattern with + * DataFormatter.setDefaultNumberFormat(Format). Note: the + * default format will only be used when a Format cannot be created from the + * cell's data format string. + * + * @author James May (james dot may at fmr dot com) + * + */ +public class DataFormatter { + + /** Pattern to find a number format: "0" or "#" */ + private static final Pattern numPattern = Pattern.compile("[0#]+"); + + /** Pattern to find days of week as text "ddd...." */ + private static final Pattern daysAsText = Pattern.compile("([d]{3,})", Pattern.CASE_INSENSITIVE); + + /** Pattern to find "AM/PM" marker */ + private static final Pattern amPmPattern = Pattern.compile("((A|P)[M/P]*)", Pattern.CASE_INSENSITIVE); + + /** A regex to find patterns like [$$-1009] and [$?-452]. */ + private static final Pattern specialPatternGroup = Pattern.compile("(\\[\\$[^-\\]]*-[0-9A-Z]+\\])"); + + /** General format for whole numbers. */ + private static final Format generalWholeNumFormat = new DecimalFormat("#"); + + /** General format for decimal numbers. */ + private static final Format generalDecimalNumFormat = new DecimalFormat("#.##########"); + + /** A default format to use when a number pattern cannot be parsed. */ + private Format defaultNumFormat; + + /** + * A map to cache formats. + * Map formats + */ + private final Map formats; + + /** + * Constructor + */ + public DataFormatter() { + formats = new HashMap(); + + // init built-in formats + + Format zipFormat = ZipPlusFourFormat.instance; + addFormat("00000\\-0000", zipFormat); + addFormat("00000-0000", zipFormat); + + Format phoneFormat = PhoneFormat.instance; + // allow for format string variations + addFormat("[<=9999999]###\\-####;\\(###\\)\\ ###\\-####", phoneFormat); + addFormat("[<=9999999]###-####;(###) ###-####", phoneFormat); + addFormat("###\\-####;\\(###\\)\\ ###\\-####", phoneFormat); + addFormat("###-####;(###) ###-####", phoneFormat); + + Format ssnFormat = SSNFormat.instance; + addFormat("000\\-00\\-0000", ssnFormat); + addFormat("000-00-0000", ssnFormat); + } + + /** + * Return a Format for the given cell if one exists, otherwise try to + * create one. This method will return null if the any of the + * following is true: + *

            + *
          • the cell's style is null
          • + *
          • the style's data format string is null or empty
          • + *
          • the format string cannot be recognized as either a number or date
          • + *
          + * + * @param cell The cell to retrieve a Format for + * @return A Format for the format String + */ + private Format getFormat(Cell cell) { + if ( cell.getCellStyle() == null) { + return null; + } + + int formatIndex = cell.getCellStyle().getDataFormat(); + String formatStr = cell.getCellStyle().getDataFormatString(); + if(formatStr == null || formatStr.trim().length() == 0) { + return null; + } + return getFormat(cell.getNumericCellValue(), formatIndex, formatStr); + } + + private Format getFormat(double cellValue, int formatIndex, String formatStr) { + Format format = (Format)formats.get(formatStr); + if (format != null) { + return format; + } + if (formatStr.equals("General") || formatStr.equals("@")) { + if (DataFormatter.isWholeNumber(cellValue)) { + return generalWholeNumFormat; + } + return generalDecimalNumFormat; + } + format = createFormat(cellValue, formatIndex, formatStr); + formats.put(formatStr, format); + return format; + } + + /** + * Create and return a Format based on the format string from a cell's + * style. If the pattern cannot be parsed, return a default pattern. + * + * @param cell The Excel cell + * @return A Format representing the excel format. May return null. + */ + public Format createFormat(Cell cell) { + + int formatIndex = cell.getCellStyle().getDataFormat(); + String formatStr = cell.getCellStyle().getDataFormatString(); + return createFormat(cell.getNumericCellValue(), formatIndex, formatStr); + } + + private Format createFormat(double cellValue, int formatIndex, String sFormat) { + // remove color formatting if present + String formatStr = sFormat.replaceAll("\\[[a-zA-Z]*\\]", ""); + + // try to extract special characters like currency + Matcher m = specialPatternGroup.matcher(formatStr); + while(m.find()) { + String match = m.group(); + String symbol = match.substring(match.indexOf('$') + 1, match.indexOf('-')); + if (symbol.indexOf('$') > -1) { + StringBuffer sb = new StringBuffer(); + sb.append(symbol.substring(0, symbol.indexOf('$'))); + sb.append('\\'); + sb.append(symbol.substring(symbol.indexOf('$'), symbol.length())); + symbol = sb.toString(); + } + formatStr = m.replaceAll(symbol); + m = specialPatternGroup.matcher(formatStr); + } + + if(formatStr == null || formatStr.trim().length() == 0) { + return getDefaultFormat(cellValue); + } + + + if(DateUtil.isADateFormat(formatIndex,formatStr) && + DateUtil.isValidExcelDate(cellValue)) { + return createDateFormat(formatStr, cellValue); + } + if (numPattern.matcher(formatStr).find()) { + return createNumberFormat(formatStr, cellValue); + } + // TODO - when does this occur? + return null; + } + + private Format createDateFormat(String pFormatStr, double cellValue) { + String formatStr = pFormatStr; + formatStr = formatStr.replaceAll("\\\\-","-"); + formatStr = formatStr.replaceAll("\\\\,",","); + formatStr = formatStr.replaceAll("\\\\ "," "); + formatStr = formatStr.replaceAll(";@", ""); + boolean hasAmPm = false; + Matcher amPmMatcher = amPmPattern.matcher(formatStr); + while (amPmMatcher.find()) { + formatStr = amPmMatcher.replaceAll("@"); + hasAmPm = true; + amPmMatcher = amPmPattern.matcher(formatStr); + } + formatStr = formatStr.replaceAll("@", "a"); + + + Matcher dateMatcher = daysAsText.matcher(formatStr); + if (dateMatcher.find()) { + String match = dateMatcher.group(0); + formatStr = dateMatcher.replaceAll(match.toUpperCase().replaceAll("D", "E")); + } + + // Convert excel date format to SimpleDateFormat. + // Excel uses lower case 'm' for both minutes and months. + // From Excel help: + /* + The "m" or "mm" code must appear immediately after the "h" or"hh" + code or immediately before the "ss" code; otherwise, Microsoft + Excel displays the month instead of minutes." + */ + + StringBuffer sb = new StringBuffer(); + char[] chars = formatStr.toCharArray(); + boolean mIsMonth = true; + List ms = new ArrayList(); + for(int j=0; j -1 && sb.charAt(idx -1) == '_') { + sb.deleteCharAt(idx); + sb.deleteCharAt(idx - 1); + sb.deleteCharAt(i); + i--; + } + } else if (c == ')' && i > 0 && sb.charAt(i - 1) == '_') { + sb.deleteCharAt(i); + sb.deleteCharAt(i - 1); + i--; + // remove quotes and back slashes + } else if (c == '\\' || c == '"') { + sb.deleteCharAt(i); + i--; + + // for scientific/engineering notation + } else if (c == '+' && i > 0 && sb.charAt(i - 1) == 'E') { + sb.deleteCharAt(i); + i--; + } + } + + try { + return new DecimalFormat(sb.toString()); + } catch(IllegalArgumentException iae) { + + // the pattern could not be parsed correctly, + // so fall back to the default number format + return getDefaultFormat(cellValue); + } + } + + /** + * Return true if the double value represents a whole number + * @param d the double value to check + * @return true if d is a whole number + */ + private static boolean isWholeNumber(double d) { + return d == Math.floor(d); + } + + /** + * Returns a default format for a cell. + * @param cell The cell + * @return a default format + */ + public Format getDefaultFormat(Cell cell) { + return getDefaultFormat(cell.getNumericCellValue()); + } + private Format getDefaultFormat(double cellValue) { + // for numeric cells try user supplied default + if (defaultNumFormat != null) { + return defaultNumFormat; + + // otherwise use general format + } + if (isWholeNumber(cellValue)){ + return generalWholeNumFormat; + } + return generalDecimalNumFormat; + } + + /** + * Returns the formatted value of an Excel date as a String based + * on the cell's DataFormat. i.e. "Thursday, January 02, 2003" + * , "01/02/2003" , "02-Jan" , etc. + * + * @param cell The cell + * @return a formatted date string + */ + private String getFormattedDateString(Cell cell) { + Format dateFormat = getFormat(cell); + Date d = cell.getDateCellValue(); + if (dateFormat != null) { + return dateFormat.format(d); + } + return d.toString(); + } + + /** + * Returns the formatted value of an Excel number as a String + * based on the cell's DataFormat. Supported formats include + * currency, percents, decimals, phone number, SSN, etc.: + * "61.54%", "$100.00", "(800) 555-1234". + * + * @param cell The cell + * @return a formatted number string + */ + private String getFormattedNumberString(Cell cell) { + + Format numberFormat = getFormat(cell); + double d = cell.getNumericCellValue(); + if (numberFormat == null) { + return String.valueOf(d); + } + return numberFormat.format(new Double(d)); + } + + /** + * Formats the given raw cell value, based on the supplied + * format index and string, according to excel style rules. + * @see #formatCellValue(Cell) + */ + public String formatRawCellContents(double value, int formatIndex, String formatString) { + // Is it a date? + if(DateUtil.isADateFormat(formatIndex,formatString) && + DateUtil.isValidExcelDate(value)) { + + Format dateFormat = getFormat(value, formatIndex, formatString); + Date d = DateUtil.getJavaDate(value); + if (dateFormat == null) { + return d.toString(); + } + return dateFormat.format(d); + } + // else Number + Format numberFormat = getFormat(value, formatIndex, formatString); + if (numberFormat == null) { + return String.valueOf(value); + } + return numberFormat.format(new Double(value)); + } + + /** + *

          + * Returns the formatted value of a cell as a String regardless + * of the cell type. If the Excel format pattern cannot be parsed then the + * cell value will be formatted using a default format. + *

          + *

          When passed a null or blank cell, this method will return an empty + * String (""). Formulas in formula type cells will not be evaluated. + *

          + * + * @param cell The cell + * @return the formatted cell value as a String + */ + public String formatCellValue(Cell cell) { + return formatCellValue(cell, null); + } + + /** + *

          + * Returns the formatted value of a cell as a String regardless + * of the cell type. If the Excel format pattern cannot be parsed then the + * cell value will be formatted using a default format. + *

          + *

          When passed a null or blank cell, this method will return an empty + * String (""). Formula cells will be evaluated using the given + * {@link FormulaEvaluator} if the evaluator is non-null. If the + * evaluator is null, then the formula String will be returned. The caller + * is responsible for setting the currentRow on the evaluator + *

          + * + * @param cell The cell (can be null) + * @param evaluator The FormulaEvaluator (can be null) + * @return a string value of the cell + */ + public String formatCellValue(Cell cell, FormulaEvaluator evaluator) { + + if (cell == null) { + return ""; + } + + int cellType = cell.getCellType(); + if (cellType == Cell.CELL_TYPE_FORMULA) { + if (evaluator == null) { + return cell.getCellFormula(); + } + cellType = evaluator.evaluateFormulaCell(cell); + } + switch (cellType) { + case Cell.CELL_TYPE_NUMERIC : + + if (DateUtil.isCellDateFormatted(cell)) { + return getFormattedDateString(cell); + } + return getFormattedNumberString(cell); + + case Cell.CELL_TYPE_STRING : + return cell.getRichStringCellValue().getString(); + + case Cell.CELL_TYPE_BOOLEAN : + return String.valueOf(cell.getBooleanCellValue()); + case Cell.CELL_TYPE_BLANK : + return ""; + } + throw new RuntimeException("Unexpected celltype (" + cellType + ")"); + } + + + /** + *

          + * Sets a default number format to be used when the Excel format cannot be + * parsed successfully. Note: This is a fall back for when an error + * occurs while parsing an Excel number format pattern. This will not + * affect cells with the General format. + *

          + *

          + * The value that will be passed to the Format's format method (specified + * by java.text.Format#format) will be a double value from a + * numeric cell. Therefore the code in the format method should expect a + * Number value. + *

          + * + * @param format A Format instance to be used as a default + * @see java.text.Format#format + */ + public void setDefaultNumberFormat(Format format) { + Iterator itr = formats.entrySet().iterator(); + while(itr.hasNext()) { + Map.Entry entry = (Map.Entry)itr.next(); + if (entry.getValue() == generalDecimalNumFormat + || entry.getValue() == generalWholeNumFormat) { + entry.setValue(format); + } + } + defaultNumFormat = format; + } + + /** + * Adds a new format to the available formats. + *

          + * The value that will be passed to the Format's format method (specified + * by java.text.Format#format) will be a double value from a + * numeric cell. Therefore the code in the format method should expect a + * Number value. + *

          + * @param excelFormatStr The data format string + * @param format A Format instance + */ + public void addFormat(String excelFormatStr, Format format) { + formats.put(excelFormatStr, format); + } + + // Some custom formats + + /** + * @return a DecimalFormat with parseIntegerOnly set true + */ + /* package */ static DecimalFormat createIntegerOnlyFormat(String fmt) { + DecimalFormat result = new DecimalFormat(fmt); + result.setParseIntegerOnly(true); + return result; + } + /** + * Format class for Excel's SSN format. This class mimics Excel's built-in + * SSN formatting. + * + * @author James May + */ + private static final class SSNFormat extends Format { + public static final Format instance = new SSNFormat(); + private static final DecimalFormat df = createIntegerOnlyFormat("000000000"); + private SSNFormat() { + // enforce singleton + } + + /** Format a number as an SSN */ + public static String format(Number num) { + String result = df.format(num); + StringBuffer sb = new StringBuffer(); + sb.append(result.substring(0, 3)).append('-'); + sb.append(result.substring(3, 5)).append('-'); + sb.append(result.substring(5, 9)); + return sb.toString(); + } + + public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { + return toAppendTo.append(format((Number)obj)); + } + + public Object parseObject(String source, ParsePosition pos) { + return df.parseObject(source, pos); + } + } + + /** + * Format class for Excel Zip + 4 format. This class mimics Excel's + * built-in formatting for Zip + 4. + * @author James May + */ + private static final class ZipPlusFourFormat extends Format { + public static final Format instance = new ZipPlusFourFormat(); + private static final DecimalFormat df = createIntegerOnlyFormat("000000000"); + private ZipPlusFourFormat() { + // enforce singleton + } + + /** Format a number as Zip + 4 */ + public static String format(Number num) { + String result = df.format(num); + StringBuffer sb = new StringBuffer(); + sb.append(result.substring(0, 5)).append('-'); + sb.append(result.substring(5, 9)); + return sb.toString(); + } + + public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { + return toAppendTo.append(format((Number)obj)); + } + + public Object parseObject(String source, ParsePosition pos) { + return df.parseObject(source, pos); + } + } + + /** + * Format class for Excel phone number format. This class mimics Excel's + * built-in phone number formatting. + * @author James May + */ + private static final class PhoneFormat extends Format { + public static final Format instance = new PhoneFormat(); + private static final DecimalFormat df = createIntegerOnlyFormat("##########"); + private PhoneFormat() { + // enforce singleton + } + + /** Format a number as a phone number */ + public static String format(Number num) { + String result = df.format(num); + StringBuffer sb = new StringBuffer(); + String seg1, seg2, seg3; + int len = result.length(); + if (len <= 4) { + return result; + } + + seg3 = result.substring(len - 4, len); + seg2 = result.substring(Math.max(0, len - 7), len - 4); + seg1 = result.substring(Math.max(0, len - 10), Math.max(0, len - 7)); + + if(seg1 != null && seg1.trim().length() > 0) { + sb.append('(').append(seg1).append(") "); + } + if(seg2 != null && seg2.trim().length() > 0) { + sb.append(seg2).append('-'); + } + sb.append(seg3); + return sb.toString(); + } + + public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { + return toAppendTo.append(format((Number)obj)); + } + + public Object parseObject(String source, ParsePosition pos) { + return df.parseObject(source, pos); + } + } +} diff --git a/src/java/org/apache/poi/ss/usermodel/Drawing.java b/src/java/org/apache/poi/ss/usermodel/Drawing.java index c7b8dc0e84..b27c3098c0 100755 --- a/src/java/org/apache/poi/ss/usermodel/Drawing.java +++ b/src/java/org/apache/poi/ss/usermodel/Drawing.java @@ -1,24 +1,24 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -/** - * @author Yegor Kozlov - */ -public interface Drawing { - Picture createPicture(ClientAnchor anchor, int pictureIndex); -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +package org.apache.poi.ss.usermodel; + +/** + * @author Yegor Kozlov + */ +public interface Drawing { + Picture createPicture(ClientAnchor anchor, int pictureIndex); +} diff --git a/src/java/org/apache/poi/ss/usermodel/FormulaError.java b/src/java/org/apache/poi/ss/usermodel/FormulaError.java index 4f631c6ee4..c3c43301e5 100755 --- a/src/java/org/apache/poi/ss/usermodel/FormulaError.java +++ b/src/java/org/apache/poi/ss/usermodel/FormulaError.java @@ -1,140 +1,140 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -import java.util.Map; -import java.util.HashMap; - -/** - * Enumerates error values in SpreadsheetML formula calculations. - * - * @author Yegor Kozlov - */ -public enum FormulaError { - /** - * Intended to indicate when two areas are required to intersect, but do not. - *

          Example: - * In the case of SUM(B1 C1), the space between B1 and C1 is treated as the binary - * intersection operator, when a comma was intended. end example] - *

          - */ - NULL(0x00, "#NULL!"), - - /** - * Intended to indicate when any number, including zero, is divided by zero. - * Note: However, any error code divided by zero results in that error code. - */ - DIV0(0x07, "#DIV/0!"), - - /** - * Intended to indicate when an incompatible type argument is passed to a function, or - * an incompatible type operand is used with an operator. - *

          Example: - * In the case of a function argument, text was expected, but a number was provided - *

          - */ - VALUE(0x0F, "#VALUE!"), - - /** - * Intended to indicate when a cell reference is invalid. - *

          Example: - * If a formula contains a reference to a cell, and then the row or column containing that cell is deleted, - * a #REF! error results. If a worksheet does not support 20,001 columns, - * OFFSET(A1,0,20000) will result in a #REF! error. - *

          - */ - REF(0x1D, "#REF!"), - - /** - * Intended to indicate when what looks like a name is used, but no such name has been defined. - *

          Example: - * XYZ/3, where XYZ is not a defined name. Total is & A10, - * where neither Total nor is is a defined name. Presumably, "Total is " & A10 - * was intended. SUM(A1C10), where the range A1:C10 was intended. - *

          - */ - NAME(0x1D, "#NAME?"), - - /** - * Intended to indicate when an argument to a function has a compatible type, but has a - * value that is outside the domain over which that function is defined. (This is known as - * a domain error.) - *

          Example: - * Certain calls to ASIN, ATANH, FACT, and SQRT might result in domain errors. - *

          - * Intended to indicate that the result of a function cannot be represented in a value of - * the specified type, typically due to extreme magnitude. (This is known as a range - * error.) - *

          Example: FACT(1000) might result in a range error.

          - */ - NUM(0x24, "#NUM!"), - - /** - * Intended to indicate when a designated value is not available. - *

          Example: - * Some functions, such as SUMX2MY2, perform a series of operations on corresponding - * elements in two arrays. If those arrays do not have the same number of elements, then - * for some elements in the longer array, there are no corresponding elements in the - * shorter one; that is, one or more values in the shorter array are not available. - *

          - * This error value can be produced by calling the function NA - */ - NA(0x2A, "#N/A"); - - private byte type; - private String repr; - - private FormulaError(int type, String repr) { - this.type = (byte) type; - this.repr = repr; - } - - /** - * @return numeric code of the error - */ - public byte getCode() { - return type; - } - - /** - * @return string representation of the error - */ - public String getString() { - return repr; - } - - private static Map smap = new HashMap(); - private static Map imap = new HashMap(); - static{ - for (FormulaError error : values()) { - imap.put(error.getCode(), error); - smap.put(error.getString(), error); - } - } - - public static FormulaError forInt(byte type){ - FormulaError err = imap.get(type); - if(err == null) throw new IllegalArgumentException("Unknown error type: " + type); - return err; - } - - public static FormulaError forString(String code){ - FormulaError err = smap.get(code); - if(err == null) throw new IllegalArgumentException("Unknown error code: " + code); - return err; - } -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +package org.apache.poi.ss.usermodel; + +import java.util.Map; +import java.util.HashMap; + +/** + * Enumerates error values in SpreadsheetML formula calculations. + * + * @author Yegor Kozlov + */ +public enum FormulaError { + /** + * Intended to indicate when two areas are required to intersect, but do not. + *

          Example: + * In the case of SUM(B1 C1), the space between B1 and C1 is treated as the binary + * intersection operator, when a comma was intended. end example] + *

          + */ + NULL(0x00, "#NULL!"), + + /** + * Intended to indicate when any number, including zero, is divided by zero. + * Note: However, any error code divided by zero results in that error code. + */ + DIV0(0x07, "#DIV/0!"), + + /** + * Intended to indicate when an incompatible type argument is passed to a function, or + * an incompatible type operand is used with an operator. + *

          Example: + * In the case of a function argument, text was expected, but a number was provided + *

          + */ + VALUE(0x0F, "#VALUE!"), + + /** + * Intended to indicate when a cell reference is invalid. + *

          Example: + * If a formula contains a reference to a cell, and then the row or column containing that cell is deleted, + * a #REF! error results. If a worksheet does not support 20,001 columns, + * OFFSET(A1,0,20000) will result in a #REF! error. + *

          + */ + REF(0x1D, "#REF!"), + + /** + * Intended to indicate when what looks like a name is used, but no such name has been defined. + *

          Example: + * XYZ/3, where XYZ is not a defined name. Total is & A10, + * where neither Total nor is is a defined name. Presumably, "Total is " & A10 + * was intended. SUM(A1C10), where the range A1:C10 was intended. + *

          + */ + NAME(0x1D, "#NAME?"), + + /** + * Intended to indicate when an argument to a function has a compatible type, but has a + * value that is outside the domain over which that function is defined. (This is known as + * a domain error.) + *

          Example: + * Certain calls to ASIN, ATANH, FACT, and SQRT might result in domain errors. + *

          + * Intended to indicate that the result of a function cannot be represented in a value of + * the specified type, typically due to extreme magnitude. (This is known as a range + * error.) + *

          Example: FACT(1000) might result in a range error.

          + */ + NUM(0x24, "#NUM!"), + + /** + * Intended to indicate when a designated value is not available. + *

          Example: + * Some functions, such as SUMX2MY2, perform a series of operations on corresponding + * elements in two arrays. If those arrays do not have the same number of elements, then + * for some elements in the longer array, there are no corresponding elements in the + * shorter one; that is, one or more values in the shorter array are not available. + *

          + * This error value can be produced by calling the function NA + */ + NA(0x2A, "#N/A"); + + private byte type; + private String repr; + + private FormulaError(int type, String repr) { + this.type = (byte) type; + this.repr = repr; + } + + /** + * @return numeric code of the error + */ + public byte getCode() { + return type; + } + + /** + * @return string representation of the error + */ + public String getString() { + return repr; + } + + private static Map smap = new HashMap(); + private static Map imap = new HashMap(); + static{ + for (FormulaError error : values()) { + imap.put(error.getCode(), error); + smap.put(error.getString(), error); + } + } + + public static FormulaError forInt(byte type){ + FormulaError err = imap.get(type); + if(err == null) throw new IllegalArgumentException("Unknown error type: " + type); + return err; + } + + public static FormulaError forString(String code){ + FormulaError err = smap.get(code); + if(err == null) throw new IllegalArgumentException("Unknown error code: " + code); + return err; + } +} diff --git a/src/java/org/apache/poi/ss/usermodel/HorizontalAlignment.java b/src/java/org/apache/poi/ss/usermodel/HorizontalAlignment.java index bcc05d8fbf..9be6017ab0 100755 --- a/src/java/org/apache/poi/ss/usermodel/HorizontalAlignment.java +++ b/src/java/org/apache/poi/ss/usermodel/HorizontalAlignment.java @@ -1,95 +1,95 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -/** - * The enumeration value indicating horizontal alignment of a cell, - * i.e., whether it is aligned general, left, right, horizontally centered, filled (replicated), - * justified, centered across multiple cells, or distributed. - */ -public enum HorizontalAlignment { - /** - * The horizontal alignment is general-aligned. Text data is left-aligned. - * Numbers, dates, and times are rightaligned. Boolean types are centered. - * Changing the alignment does not change the type of data. - */ - GENERAL, - - /** - * The horizontal alignment is left-aligned, even in Rightto-Left mode. - * Aligns contents at the left edge of the cell. If an indent amount is specified, the contents of - * the cell is indented from the left by the specified number of character spaces. The character spaces are - * based on the default font and font size for the workbook. - */ - LEFT, - - /** - * The horizontal alignment is centered, meaning the text is centered across the cell. - */ - CENTER, - - /** - * The horizontal alignment is right-aligned, meaning that cell contents are aligned at the right edge of the cell, - * even in Right-to-Left mode. - */ - RIGHT, - - /** - * Indicates that the value of the cell should be filled - * across the entire width of the cell. If blank cells to the right also have the fill alignment, - * they are also filled with the value, using a convention similar to centerContinuous. - *

          - * Additional rules: - *

            - *
          1. Only whole values can be appended, not partial values.
          2. - *
          3. The column will not be widened to 'best fit' the filled value
          4. - *
          5. If appending an additional occurrence of the value exceeds the boundary of the cell - * left/right edge, don't append the additional occurrence of the value.
          6. - *
          7. The display value of the cell is filled, not the underlying raw number.
          8. - *
          - *

          - */ - FILL, - - /** - * The horizontal alignment is justified (flush left and right). - * For each line of text, aligns each line of the wrapped text in a cell to the right and left - * (except the last line). If no single line of text wraps in the cell, then the text is not justified. - */ - JUSTIFY, - - /** - * The horizontal alignment is centered across multiple cells. - * The information about how many cells to span is expressed in the Sheet Part, - * in the row of the cell in question. For each cell that is spanned in the alignment, - * a cell element needs to be written out, with the same style Id which references the centerContinuous alignment. - */ - CENTER_SELECTION, - - /** - * Indicates that each 'word' in each line of text inside the cell is evenly distributed - * across the width of the cell, with flush right and left margins. - *

          - * When there is also an indent value to apply, both the left and right side of the cell - * are padded by the indent value. - *

          - *

          A 'word' is a set of characters with no space character in them.

          - *

          Two lines inside a cell are separated by a carriage return.

          - */ - DISTRIBUTED -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.usermodel; + +/** + * The enumeration value indicating horizontal alignment of a cell, + * i.e., whether it is aligned general, left, right, horizontally centered, filled (replicated), + * justified, centered across multiple cells, or distributed. + */ +public enum HorizontalAlignment { + /** + * The horizontal alignment is general-aligned. Text data is left-aligned. + * Numbers, dates, and times are rightaligned. Boolean types are centered. + * Changing the alignment does not change the type of data. + */ + GENERAL, + + /** + * The horizontal alignment is left-aligned, even in Rightto-Left mode. + * Aligns contents at the left edge of the cell. If an indent amount is specified, the contents of + * the cell is indented from the left by the specified number of character spaces. The character spaces are + * based on the default font and font size for the workbook. + */ + LEFT, + + /** + * The horizontal alignment is centered, meaning the text is centered across the cell. + */ + CENTER, + + /** + * The horizontal alignment is right-aligned, meaning that cell contents are aligned at the right edge of the cell, + * even in Right-to-Left mode. + */ + RIGHT, + + /** + * Indicates that the value of the cell should be filled + * across the entire width of the cell. If blank cells to the right also have the fill alignment, + * they are also filled with the value, using a convention similar to centerContinuous. + *

          + * Additional rules: + *

            + *
          1. Only whole values can be appended, not partial values.
          2. + *
          3. The column will not be widened to 'best fit' the filled value
          4. + *
          5. If appending an additional occurrence of the value exceeds the boundary of the cell + * left/right edge, don't append the additional occurrence of the value.
          6. + *
          7. The display value of the cell is filled, not the underlying raw number.
          8. + *
          + *

          + */ + FILL, + + /** + * The horizontal alignment is justified (flush left and right). + * For each line of text, aligns each line of the wrapped text in a cell to the right and left + * (except the last line). If no single line of text wraps in the cell, then the text is not justified. + */ + JUSTIFY, + + /** + * The horizontal alignment is centered across multiple cells. + * The information about how many cells to span is expressed in the Sheet Part, + * in the row of the cell in question. For each cell that is spanned in the alignment, + * a cell element needs to be written out, with the same style Id which references the centerContinuous alignment. + */ + CENTER_SELECTION, + + /** + * Indicates that each 'word' in each line of text inside the cell is evenly distributed + * across the width of the cell, with flush right and left margins. + *

          + * When there is also an indent value to apply, both the left and right side of the cell + * are padded by the indent value. + *

          + *

          A 'word' is a set of characters with no space character in them.

          + *

          Two lines inside a cell are separated by a carriage return.

          + */ + DISTRIBUTED +} diff --git a/src/java/org/apache/poi/ss/usermodel/Picture.java b/src/java/org/apache/poi/ss/usermodel/Picture.java index dd6a8e7d31..e816c9ac15 100755 --- a/src/java/org/apache/poi/ss/usermodel/Picture.java +++ b/src/java/org/apache/poi/ss/usermodel/Picture.java @@ -1,42 +1,42 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -/** - * Repersents a picture in a SpreadsheetML document - * - * @author Yegor Kozlov - */ -public interface Picture { - - /** - * Reset the image to the original size. - */ - void resize(); - - /** - * Reset the image to the original size. - * - * @param scale the amount by which image dimensions are multiplied relative to the original size. - * resize(1.0) sets the original size, resize(0.5) resize to 50% of the original, - * resize(2.0) resizes to 200% of the original. - */ - void resize(double scale); - - ClientAnchor getPreferredSize(); - -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +package org.apache.poi.ss.usermodel; + +/** + * Repersents a picture in a SpreadsheetML document + * + * @author Yegor Kozlov + */ +public interface Picture { + + /** + * Reset the image to the original size. + */ + void resize(); + + /** + * Reset the image to the original size. + * + * @param scale the amount by which image dimensions are multiplied relative to the original size. + * resize(1.0) sets the original size, resize(0.5) resize to 50% of the original, + * resize(2.0) resizes to 200% of the original. + */ + void resize(double scale); + + ClientAnchor getPreferredSize(); + +} diff --git a/src/java/org/apache/poi/ss/usermodel/ShapeTypes.java b/src/java/org/apache/poi/ss/usermodel/ShapeTypes.java index ef8409340c..3c5747ee5a 100755 --- a/src/java/org/apache/poi/ss/usermodel/ShapeTypes.java +++ b/src/java/org/apache/poi/ss/usermodel/ShapeTypes.java @@ -1,212 +1,212 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.ss.usermodel; - -/** - * All known types of automatic shapes in DrawingML - * - * @author Yegor Kozlov - */ -public class ShapeTypes { - public static final int LINE = 1; - public static final int LINE_INV = 2; - public static final int TRIANGLE = 3; - public static final int RT_TRIANGLE = 4; - public static final int RECT = 5; - public static final int DIAMOND = 6; - public static final int PARALLELOGRAM = 7; - public static final int TRAPEZOID = 8; - public static final int NON_ISOSCELES_TRAPEZOID = 9; - public static final int PENTAGON = 10; - public static final int HEXAGON = 11; - public static final int HEPTAGON = 12; - public static final int OCTAGON = 13; - public static final int DECAGON = 14; - public static final int DODECAGON = 15; - public static final int STAR_4 = 16; - public static final int STAR_5 = 17; - public static final int STAR_6 = 18; - public static final int STAR_7 = 19; - public static final int STAR_8 = 20; - public static final int STAR_10 = 21; - public static final int STAR_12 = 22; - public static final int STAR_16 = 23; - public static final int STAR_24 = 24; - public static final int STAR_32 = 25; - public static final int ROUND_RECT = 26; - public static final int ROUND_1_RECT = 27; - public static final int ROUND_2_SAME_RECT = 28; - public static final int ROUND_2_DIAG_RECT = 29; - public static final int SNIP_ROUND_RECT = 30; - public static final int SNIP_1_RECT = 31; - public static final int SNIP_2_SAME_RECT = 32; - public static final int SNIP_2_DIAG_RECT = 33; - public static final int PLAQUE = 34; - public static final int ELLIPSE = 35; - public static final int TEARDROP = 36; - public static final int HOME_PLATE = 37; - public static final int CHEVRON = 38; - public static final int PIE_WEDGE = 39; - public static final int PIE = 40; - public static final int BLOCK_ARC = 41; - public static final int DONUT = 42; - public static final int NO_SMOKING = 43; - public static final int RIGHT_ARROW = 44; - public static final int LEFT_ARROW = 45; - public static final int UP_ARROW = 46; - public static final int DOWN_ARROW = 47; - public static final int STRIPED_RIGHT_ARROW = 48; - public static final int NOTCHED_RIGHT_ARROW = 49; - public static final int BENT_UP_ARROW = 50; - public static final int LEFT_RIGHT_ARROW = 51; - public static final int UP_DOWN_ARROW = 52; - public static final int LEFT_UP_ARROW = 53; - public static final int LEFT_RIGHT_UP_ARROW = 54; - public static final int QUAD_ARROW = 55; - public static final int LEFT_ARROW_CALLOUT = 56; - public static final int RIGHT_ARROW_CALLOUT = 57; - public static final int UP_ARROW_CALLOUT = 58; - public static final int DOWN_ARROW_CALLOUT = 59; - public static final int LEFT_RIGHT_ARROW_CALLOUT = 60; - public static final int UP_DOWN_ARROW_CALLOUT = 61; - public static final int QUAD_ARROW_CALLOUT = 62; - public static final int BENT_ARROW = 63; - public static final int UTURN_ARROW = 64; - public static final int CIRCULAR_ARROW = 65; - public static final int LEFT_CIRCULAR_ARROW = 66; - public static final int LEFT_RIGHT_CIRCULAR_ARROW = 67; - public static final int CURVED_RIGHT_ARROW = 68; - public static final int CURVED_LEFT_ARROW = 69; - public static final int CURVED_UP_ARROW = 70; - public static final int CURVED_DOWN_ARROW = 71; - public static final int SWOOSH_ARROW = 72; - public static final int CUBE = 73; - public static final int CAN = 74; - public static final int LIGHTNING_BOLT = 75; - public static final int HEART = 76; - public static final int SUN = 77; - public static final int MOON = 78; - public static final int SMILEY_FACE = 79; - public static final int IRREGULAR_SEAL_1 = 80; - public static final int IRREGULAR_SEAL_2 = 81; - public static final int FOLDED_CORNER = 82; - public static final int BEVEL = 83; - public static final int FRAME = 84; - public static final int HALF_FRAME = 85; - public static final int CORNER = 86; - public static final int DIAG_STRIPE = 87; - public static final int CHORD = 88; - public static final int ARC = 89; - public static final int LEFT_BRACKET = 90; - public static final int RIGHT_BRACKET = 91; - public static final int LEFT_BRACE = 92; - public static final int RIGHT_BRACE = 93; - public static final int BRACKET_PAIR = 94; - public static final int BRACE_PAIR = 95; - public static final int STRAIGHT_CONNECTOR_1 = 96; - public static final int BENT_CONNECTOR_2 = 97; - public static final int BENT_CONNECTOR_3 = 98; - public static final int BENT_CONNECTOR_4 = 99; - public static final int BENT_CONNECTOR_5 = 100; - public static final int CURVED_CONNECTOR_2 = 101; - public static final int CURVED_CONNECTOR_3 = 102; - public static final int CURVED_CONNECTOR_4 = 103; - public static final int CURVED_CONNECTOR_5 = 104; - public static final int CALLOUT_1 = 105; - public static final int CALLOUT_2 = 106; - public static final int CALLOUT_3 = 107; - public static final int ACCENT_CALLOUT_1 = 108; - public static final int ACCENT_CALLOUT_2 = 109; - public static final int ACCENT_CALLOUT_3 = 110; - public static final int BORDER_CALLOUT_1 = 111; - public static final int BORDER_CALLOUT_2 = 112; - public static final int BORDER_CALLOUT_3 = 113; - public static final int ACCENT_BORDER_CALLOUT_1 = 114; - public static final int ACCENT_BORDER_CALLOUT_2 = 115; - public static final int ACCENT_BORDER_CALLOUT_3 = 116; - public static final int WEDGE_RECT_CALLOUT = 117; - public static final int WEDGE_ROUND_RECT_CALLOUT = 118; - public static final int WEDGE_ELLIPSE_CALLOUT = 119; - public static final int CLOUD_CALLOUT = 120; - public static final int CLOUD = 121; - public static final int RIBBON = 122; - public static final int RIBBON_2 = 123; - public static final int ELLIPSE_RIBBON = 124; - public static final int ELLIPSE_RIBBON_2 = 125; - public static final int LEFT_RIGHT_RIBBON = 126; - public static final int VERTICAL_SCROLL = 127; - public static final int HORIZONTAL_SCROLL = 128; - public static final int WAVE = 129; - public static final int DOUBLE_WAVE = 130; - public static final int PLUS = 131; - public static final int FLOW_CHART_PROCESS = 132; - public static final int FLOW_CHART_DECISION = 133; - public static final int FLOW_CHART_INPUT_OUTPUT = 134; - public static final int FLOW_CHART_PREDEFINED_PROCESS = 135; - public static final int FLOW_CHART_INTERNAL_STORAGE = 136; - public static final int FLOW_CHART_DOCUMENT = 137; - public static final int FLOW_CHART_MULTIDOCUMENT = 138; - public static final int FLOW_CHART_TERMINATOR = 139; - public static final int FLOW_CHART_PREPARATION = 140; - public static final int FLOW_CHART_MANUAL_INPUT = 141; - public static final int FLOW_CHART_MANUAL_OPERATION = 142; - public static final int FLOW_CHART_CONNECTOR = 143; - public static final int FLOW_CHART_PUNCHED_CARD = 144; - public static final int FLOW_CHART_PUNCHED_TAPE = 145; - public static final int FLOW_CHART_SUMMING_JUNCTION = 146; - public static final int FLOW_CHART_OR = 147; - public static final int FLOW_CHART_COLLATE = 148; - public static final int FLOW_CHART_SORT = 149; - public static final int FLOW_CHART_EXTRACT = 150; - public static final int FLOW_CHART_MERGE = 151; - public static final int FLOW_CHART_OFFLINE_STORAGE = 152; - public static final int FLOW_CHART_ONLINE_STORAGE = 153; - public static final int FLOW_CHART_MAGNETIC_TAPE = 154; - public static final int FLOW_CHART_MAGNETIC_DISK = 155; - public static final int FLOW_CHART_MAGNETIC_DRUM = 156; - public static final int FLOW_CHART_DISPLAY = 157; - public static final int FLOW_CHART_DELAY = 158; - public static final int FLOW_CHART_ALTERNATE_PROCESS = 159; - public static final int FLOW_CHART_OFFPAGE_CONNECTOR = 160; - public static final int ACTION_BUTTON_BLANK = 161; - public static final int ACTION_BUTTON_HOME = 162; - public static final int ACTION_BUTTON_HELP = 163; - public static final int ACTION_BUTTON_INFORMATION = 164; - public static final int ACTION_BUTTON_FORWARD_NEXT = 165; - public static final int ACTION_BUTTON_BACK_PREVIOUS = 166; - public static final int ACTION_BUTTON_END = 167; - public static final int ACTION_BUTTON_BEGINNING = 168; - public static final int ACTION_BUTTON_RETURN = 169; - public static final int ACTION_BUTTON_DOCUMENT = 170; - public static final int ACTION_BUTTON_SOUND = 171; - public static final int ACTION_BUTTON_MOVIE = 172; - public static final int GEAR_6 = 173; - public static final int GEAR_9 = 174; - public static final int FUNNEL = 175; - public static final int MATH_PLUS = 176; - public static final int MATH_MINUS = 177; - public static final int MATH_MULTIPLY = 178; - public static final int MATH_DIVIDE = 179; - public static final int MATH_EQUAL = 180; - public static final int MATH_NOT_EQUAL = 181; - public static final int CORNER_TABS = 182; - public static final int SQUARE_TABS = 183; - public static final int PLAQUE_TABS = 184; - public static final int CHART_X = 185; - public static final int CHART_STAR = 186; - public static final int CHART_PLUS = 187; -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +package org.apache.poi.ss.usermodel; + +/** + * All known types of automatic shapes in DrawingML + * + * @author Yegor Kozlov + */ +public class ShapeTypes { + public static final int LINE = 1; + public static final int LINE_INV = 2; + public static final int TRIANGLE = 3; + public static final int RT_TRIANGLE = 4; + public static final int RECT = 5; + public static final int DIAMOND = 6; + public static final int PARALLELOGRAM = 7; + public static final int TRAPEZOID = 8; + public static final int NON_ISOSCELES_TRAPEZOID = 9; + public static final int PENTAGON = 10; + public static final int HEXAGON = 11; + public static final int HEPTAGON = 12; + public static final int OCTAGON = 13; + public static final int DECAGON = 14; + public static final int DODECAGON = 15; + public static final int STAR_4 = 16; + public static final int STAR_5 = 17; + public static final int STAR_6 = 18; + public static final int STAR_7 = 19; + public static final int STAR_8 = 20; + public static final int STAR_10 = 21; + public static final int STAR_12 = 22; + public static final int STAR_16 = 23; + public static final int STAR_24 = 24; + public static final int STAR_32 = 25; + public static final int ROUND_RECT = 26; + public static final int ROUND_1_RECT = 27; + public static final int ROUND_2_SAME_RECT = 28; + public static final int ROUND_2_DIAG_RECT = 29; + public static final int SNIP_ROUND_RECT = 30; + public static final int SNIP_1_RECT = 31; + public static final int SNIP_2_SAME_RECT = 32; + public static final int SNIP_2_DIAG_RECT = 33; + public static final int PLAQUE = 34; + public static final int ELLIPSE = 35; + public static final int TEARDROP = 36; + public static final int HOME_PLATE = 37; + public static final int CHEVRON = 38; + public static final int PIE_WEDGE = 39; + public static final int PIE = 40; + public static final int BLOCK_ARC = 41; + public static final int DONUT = 42; + public static final int NO_SMOKING = 43; + public static final int RIGHT_ARROW = 44; + public static final int LEFT_ARROW = 45; + public static final int UP_ARROW = 46; + public static final int DOWN_ARROW = 47; + public static final int STRIPED_RIGHT_ARROW = 48; + public static final int NOTCHED_RIGHT_ARROW = 49; + public static final int BENT_UP_ARROW = 50; + public static final int LEFT_RIGHT_ARROW = 51; + public static final int UP_DOWN_ARROW = 52; + public static final int LEFT_UP_ARROW = 53; + public static final int LEFT_RIGHT_UP_ARROW = 54; + public static final int QUAD_ARROW = 55; + public static final int LEFT_ARROW_CALLOUT = 56; + public static final int RIGHT_ARROW_CALLOUT = 57; + public static final int UP_ARROW_CALLOUT = 58; + public static final int DOWN_ARROW_CALLOUT = 59; + public static final int LEFT_RIGHT_ARROW_CALLOUT = 60; + public static final int UP_DOWN_ARROW_CALLOUT = 61; + public static final int QUAD_ARROW_CALLOUT = 62; + public static final int BENT_ARROW = 63; + public static final int UTURN_ARROW = 64; + public static final int CIRCULAR_ARROW = 65; + public static final int LEFT_CIRCULAR_ARROW = 66; + public static final int LEFT_RIGHT_CIRCULAR_ARROW = 67; + public static final int CURVED_RIGHT_ARROW = 68; + public static final int CURVED_LEFT_ARROW = 69; + public static final int CURVED_UP_ARROW = 70; + public static final int CURVED_DOWN_ARROW = 71; + public static final int SWOOSH_ARROW = 72; + public static final int CUBE = 73; + public static final int CAN = 74; + public static final int LIGHTNING_BOLT = 75; + public static final int HEART = 76; + public static final int SUN = 77; + public static final int MOON = 78; + public static final int SMILEY_FACE = 79; + public static final int IRREGULAR_SEAL_1 = 80; + public static final int IRREGULAR_SEAL_2 = 81; + public static final int FOLDED_CORNER = 82; + public static final int BEVEL = 83; + public static final int FRAME = 84; + public static final int HALF_FRAME = 85; + public static final int CORNER = 86; + public static final int DIAG_STRIPE = 87; + public static final int CHORD = 88; + public static final int ARC = 89; + public static final int LEFT_BRACKET = 90; + public static final int RIGHT_BRACKET = 91; + public static final int LEFT_BRACE = 92; + public static final int RIGHT_BRACE = 93; + public static final int BRACKET_PAIR = 94; + public static final int BRACE_PAIR = 95; + public static final int STRAIGHT_CONNECTOR_1 = 96; + public static final int BENT_CONNECTOR_2 = 97; + public static final int BENT_CONNECTOR_3 = 98; + public static final int BENT_CONNECTOR_4 = 99; + public static final int BENT_CONNECTOR_5 = 100; + public static final int CURVED_CONNECTOR_2 = 101; + public static final int CURVED_CONNECTOR_3 = 102; + public static final int CURVED_CONNECTOR_4 = 103; + public static final int CURVED_CONNECTOR_5 = 104; + public static final int CALLOUT_1 = 105; + public static final int CALLOUT_2 = 106; + public static final int CALLOUT_3 = 107; + public static final int ACCENT_CALLOUT_1 = 108; + public static final int ACCENT_CALLOUT_2 = 109; + public static final int ACCENT_CALLOUT_3 = 110; + public static final int BORDER_CALLOUT_1 = 111; + public static final int BORDER_CALLOUT_2 = 112; + public static final int BORDER_CALLOUT_3 = 113; + public static final int ACCENT_BORDER_CALLOUT_1 = 114; + public static final int ACCENT_BORDER_CALLOUT_2 = 115; + public static final int ACCENT_BORDER_CALLOUT_3 = 116; + public static final int WEDGE_RECT_CALLOUT = 117; + public static final int WEDGE_ROUND_RECT_CALLOUT = 118; + public static final int WEDGE_ELLIPSE_CALLOUT = 119; + public static final int CLOUD_CALLOUT = 120; + public static final int CLOUD = 121; + public static final int RIBBON = 122; + public static final int RIBBON_2 = 123; + public static final int ELLIPSE_RIBBON = 124; + public static final int ELLIPSE_RIBBON_2 = 125; + public static final int LEFT_RIGHT_RIBBON = 126; + public static final int VERTICAL_SCROLL = 127; + public static final int HORIZONTAL_SCROLL = 128; + public static final int WAVE = 129; + public static final int DOUBLE_WAVE = 130; + public static final int PLUS = 131; + public static final int FLOW_CHART_PROCESS = 132; + public static final int FLOW_CHART_DECISION = 133; + public static final int FLOW_CHART_INPUT_OUTPUT = 134; + public static final int FLOW_CHART_PREDEFINED_PROCESS = 135; + public static final int FLOW_CHART_INTERNAL_STORAGE = 136; + public static final int FLOW_CHART_DOCUMENT = 137; + public static final int FLOW_CHART_MULTIDOCUMENT = 138; + public static final int FLOW_CHART_TERMINATOR = 139; + public static final int FLOW_CHART_PREPARATION = 140; + public static final int FLOW_CHART_MANUAL_INPUT = 141; + public static final int FLOW_CHART_MANUAL_OPERATION = 142; + public static final int FLOW_CHART_CONNECTOR = 143; + public static final int FLOW_CHART_PUNCHED_CARD = 144; + public static final int FLOW_CHART_PUNCHED_TAPE = 145; + public static final int FLOW_CHART_SUMMING_JUNCTION = 146; + public static final int FLOW_CHART_OR = 147; + public static final int FLOW_CHART_COLLATE = 148; + public static final int FLOW_CHART_SORT = 149; + public static final int FLOW_CHART_EXTRACT = 150; + public static final int FLOW_CHART_MERGE = 151; + public static final int FLOW_CHART_OFFLINE_STORAGE = 152; + public static final int FLOW_CHART_ONLINE_STORAGE = 153; + public static final int FLOW_CHART_MAGNETIC_TAPE = 154; + public static final int FLOW_CHART_MAGNETIC_DISK = 155; + public static final int FLOW_CHART_MAGNETIC_DRUM = 156; + public static final int FLOW_CHART_DISPLAY = 157; + public static final int FLOW_CHART_DELAY = 158; + public static final int FLOW_CHART_ALTERNATE_PROCESS = 159; + public static final int FLOW_CHART_OFFPAGE_CONNECTOR = 160; + public static final int ACTION_BUTTON_BLANK = 161; + public static final int ACTION_BUTTON_HOME = 162; + public static final int ACTION_BUTTON_HELP = 163; + public static final int ACTION_BUTTON_INFORMATION = 164; + public static final int ACTION_BUTTON_FORWARD_NEXT = 165; + public static final int ACTION_BUTTON_BACK_PREVIOUS = 166; + public static final int ACTION_BUTTON_END = 167; + public static final int ACTION_BUTTON_BEGINNING = 168; + public static final int ACTION_BUTTON_RETURN = 169; + public static final int ACTION_BUTTON_DOCUMENT = 170; + public static final int ACTION_BUTTON_SOUND = 171; + public static final int ACTION_BUTTON_MOVIE = 172; + public static final int GEAR_6 = 173; + public static final int GEAR_9 = 174; + public static final int FUNNEL = 175; + public static final int MATH_PLUS = 176; + public static final int MATH_MINUS = 177; + public static final int MATH_MULTIPLY = 178; + public static final int MATH_DIVIDE = 179; + public static final int MATH_EQUAL = 180; + public static final int MATH_NOT_EQUAL = 181; + public static final int CORNER_TABS = 182; + public static final int SQUARE_TABS = 183; + public static final int PLAQUE_TABS = 184; + public static final int CHART_X = 185; + public static final int CHART_STAR = 186; + public static final int CHART_PLUS = 187; +} diff --git a/src/java/org/apache/poi/ss/usermodel/VerticalAlignment.java b/src/java/org/apache/poi/ss/usermodel/VerticalAlignment.java index 2f93273287..398565d043 100755 --- a/src/java/org/apache/poi/ss/usermodel/VerticalAlignment.java +++ b/src/java/org/apache/poi/ss/usermodel/VerticalAlignment.java @@ -1,69 +1,69 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.ss.usermodel; - -/** - * This enumeration value indicates the type of vertical alignment for a cell, i.e., - * whether it is aligned top, bottom, vertically centered, justified or distributed. - */ -public enum VerticalAlignment { - /** - * The vertical alignment is aligned-to-top. - */ - TOP, - - /** - * The vertical alignment is centered across the height of the cell. - */ - CENTER, - - /** - * The vertical alignment is aligned-to-bottom. - */ - BOTTOM, - - /** - *

          - * When text direction is horizontal: the vertical alignment of lines of text is distributed vertically, - * where each line of text inside the cell is evenly distributed across the height of the cell, - * with flush top and bottom margins. - *

          - *

          - * When text direction is vertical: similar behavior as horizontal justification. - * The alignment is justified (flush top and bottom in this case). For each line of text, each - * line of the wrapped text in a cell is aligned to the top and bottom (except the last line). - * If no single line of text wraps in the cell, then the text is not justified. - *

          - */ - JUSTIFY, - - /** - *

          - * When text direction is horizontal: the vertical alignment of lines of text is distributed vertically, - * where each line of text inside the cell is evenly distributed across the height of the cell, - * with flush top - *

          - *

          - * When text direction is vertical: behaves exactly as distributed horizontal alignment. - * The first words in a line of text (appearing at the top of the cell) are flush - * with the top edge of the cell, and the last words of a line of text are flush with the bottom edge of the cell, - * and the line of text is distributed evenly from top to bottom. - *

          - */ - DISTRIBUTED -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.usermodel; + +/** + * This enumeration value indicates the type of vertical alignment for a cell, i.e., + * whether it is aligned top, bottom, vertically centered, justified or distributed. + */ +public enum VerticalAlignment { + /** + * The vertical alignment is aligned-to-top. + */ + TOP, + + /** + * The vertical alignment is centered across the height of the cell. + */ + CENTER, + + /** + * The vertical alignment is aligned-to-bottom. + */ + BOTTOM, + + /** + *

          + * When text direction is horizontal: the vertical alignment of lines of text is distributed vertically, + * where each line of text inside the cell is evenly distributed across the height of the cell, + * with flush top and bottom margins. + *

          + *

          + * When text direction is vertical: similar behavior as horizontal justification. + * The alignment is justified (flush top and bottom in this case). For each line of text, each + * line of the wrapped text in a cell is aligned to the top and bottom (except the last line). + * If no single line of text wraps in the cell, then the text is not justified. + *

          + */ + JUSTIFY, + + /** + *

          + * When text direction is horizontal: the vertical alignment of lines of text is distributed vertically, + * where each line of text inside the cell is evenly distributed across the height of the cell, + * with flush top + *

          + *

          + * When text direction is vertical: behaves exactly as distributed horizontal alignment. + * The first words in a line of text (appearing at the top of the cell) are flush + * with the top edge of the cell, and the last words of a line of text are flush with the bottom edge of the cell, + * and the line of text is distributed evenly from top to bottom. + *

          + */ + DISTRIBUTED +} diff --git a/src/java/org/apache/poi/util/DelayableLittleEndianOutput.java b/src/java/org/apache/poi/util/DelayableLittleEndianOutput.java index d8e4395e64..13282ac378 100644 --- a/src/java/org/apache/poi/util/DelayableLittleEndianOutput.java +++ b/src/java/org/apache/poi/util/DelayableLittleEndianOutput.java @@ -1,34 +1,34 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; -/** - * Implementors of this interface allow client code to 'delay' writing to a certain section of a - * data output stream.
          - * A typical application is for writing BIFF records when the size is not known until well after - * the header has been written. The client code can call {@link #createDelayedOutput(int)} - * to reserve two bytes of the output for the 'ushort size' header field. The delayed output can - * be written at any stage. - * - * @author Josh Micich - */ -public interface DelayableLittleEndianOutput extends LittleEndianOutput { - /** - * Creates an output stream intended for outputting a sequence of size bytes. - */ - LittleEndianOutput createDelayedOutput(int size); -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.util; +/** + * Implementors of this interface allow client code to 'delay' writing to a certain section of a + * data output stream.
          + * A typical application is for writing BIFF records when the size is not known until well after + * the header has been written. The client code can call {@link #createDelayedOutput(int)} + * to reserve two bytes of the output for the 'ushort size' header field. The delayed output can + * be written at any stage. + * + * @author Josh Micich + */ +public interface DelayableLittleEndianOutput extends LittleEndianOutput { + /** + * Creates an output stream intended for outputting a sequence of size bytes. + */ + LittleEndianOutput createDelayedOutput(int size); +} diff --git a/src/java/org/apache/poi/util/LittleEndianInput.java b/src/java/org/apache/poi/util/LittleEndianInput.java index dafa7eadac..d8db24797f 100644 --- a/src/java/org/apache/poi/util/LittleEndianInput.java +++ b/src/java/org/apache/poi/util/LittleEndianInput.java @@ -1,34 +1,34 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; -/** - * - * @author Josh Micich - */ -public interface LittleEndianInput { - int available(); - byte readByte(); - int readUByte(); - short readShort(); - int readUShort(); - int readInt(); - long readLong(); - double readDouble(); - void readFully(byte[] buf); - void readFully(byte[] buf, int off, int len); -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.util; +/** + * + * @author Josh Micich + */ +public interface LittleEndianInput { + int available(); + byte readByte(); + int readUByte(); + short readShort(); + int readUShort(); + int readInt(); + long readLong(); + double readDouble(); + void readFully(byte[] buf); + void readFully(byte[] buf, int off, int len); +} diff --git a/src/java/org/apache/poi/util/LittleEndianInputStream.java b/src/java/org/apache/poi/util/LittleEndianInputStream.java index 622ee23cd4..1a37964a8f 100644 --- a/src/java/org/apache/poi/util/LittleEndianInputStream.java +++ b/src/java/org/apache/poi/util/LittleEndianInputStream.java @@ -1,144 +1,144 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.util; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * Wraps an {@link InputStream} providing {@link LittleEndianInput}

          - * - * This class does not buffer any input, so the stream read position maintained - * by this class is consistent with that of the inner stream. - * - * @author Josh Micich - */ -public class LittleEndianInputStream extends FilterInputStream implements LittleEndianInput { - public LittleEndianInputStream(InputStream is) { - super(is); - } - public int available() { - try { - return super.available(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - public byte readByte() { - return (byte)readUByte(); - } - public int readUByte() { - int ch; - try { - ch = in.read(); - } catch (IOException e) { - throw new RuntimeException(e); - } - checkEOF(ch); - return ch; - } - public double readDouble() { - return Double.longBitsToDouble(readLong()); - } - public int readInt() { - int ch1; - int ch2; - int ch3; - int ch4; - try { - ch1 = in.read(); - ch2 = in.read(); - ch3 = in.read(); - ch4 = in.read(); - } catch (IOException e) { - throw new RuntimeException(e); - } - checkEOF(ch1 | ch2 | ch3 | ch4); - return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0); - } - public long readLong() { - int b0; - int b1; - int b2; - int b3; - int b4; - int b5; - int b6; - int b7; - try { - b0 = in.read(); - b1 = in.read(); - b2 = in.read(); - b3 = in.read(); - b4 = in.read(); - b5 = in.read(); - b6 = in.read(); - b7 = in.read(); - } catch (IOException e) { - throw new RuntimeException(e); - } - checkEOF(b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7); - return (((long)b7 << 56) + - ((long)b6 << 48) + - ((long)b5 << 40) + - ((long)b4 << 32) + - ((long)b3 << 24) + - (b2 << 16) + - (b1 << 8) + - (b0 << 0)); - } - public short readShort() { - return (short)readUShort(); - } - public int readUShort() { - int ch1; - int ch2; - try { - ch1 = in.read(); - ch2 = in.read(); - } catch (IOException e) { - throw new RuntimeException(e); - } - checkEOF(ch1 | ch2); - return (ch2 << 8) + (ch1 << 0); - } - private static void checkEOF(int value) { - if (value <0) { - throw new RuntimeException("Unexpected end-of-file"); - } - } - - public void readFully(byte[] buf) { - readFully(buf, 0, buf.length); - } - - public void readFully(byte[] buf, int off, int len) { - int max = off+len; - for(int i=off; i + * + * This class does not buffer any input, so the stream read position maintained + * by this class is consistent with that of the inner stream. + * + * @author Josh Micich + */ +public class LittleEndianInputStream extends FilterInputStream implements LittleEndianInput { + public LittleEndianInputStream(InputStream is) { + super(is); + } + public int available() { + try { + return super.available(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + public byte readByte() { + return (byte)readUByte(); + } + public int readUByte() { + int ch; + try { + ch = in.read(); + } catch (IOException e) { + throw new RuntimeException(e); + } + checkEOF(ch); + return ch; + } + public double readDouble() { + return Double.longBitsToDouble(readLong()); + } + public int readInt() { + int ch1; + int ch2; + int ch3; + int ch4; + try { + ch1 = in.read(); + ch2 = in.read(); + ch3 = in.read(); + ch4 = in.read(); + } catch (IOException e) { + throw new RuntimeException(e); + } + checkEOF(ch1 | ch2 | ch3 | ch4); + return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0); + } + public long readLong() { + int b0; + int b1; + int b2; + int b3; + int b4; + int b5; + int b6; + int b7; + try { + b0 = in.read(); + b1 = in.read(); + b2 = in.read(); + b3 = in.read(); + b4 = in.read(); + b5 = in.read(); + b6 = in.read(); + b7 = in.read(); + } catch (IOException e) { + throw new RuntimeException(e); + } + checkEOF(b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7); + return (((long)b7 << 56) + + ((long)b6 << 48) + + ((long)b5 << 40) + + ((long)b4 << 32) + + ((long)b3 << 24) + + (b2 << 16) + + (b1 << 8) + + (b0 << 0)); + } + public short readShort() { + return (short)readUShort(); + } + public int readUShort() { + int ch1; + int ch2; + try { + ch1 = in.read(); + ch2 = in.read(); + } catch (IOException e) { + throw new RuntimeException(e); + } + checkEOF(ch1 | ch2); + return (ch2 << 8) + (ch1 << 0); + } + private static void checkEOF(int value) { + if (value <0) { + throw new RuntimeException("Unexpected end-of-file"); + } + } + + public void readFully(byte[] buf) { + readFully(buf, 0, buf.length); + } + + public void readFully(byte[] buf, int off, int len) { + int max = off+len; + for(int i=off; i>> 24) & 0xFF; - int b2 = (v >>> 16) & 0xFF; - int b1 = (v >>> 8) & 0xFF; - int b0 = (v >>> 0) & 0xFF; - try { - out.write(b0); - out.write(b1); - out.write(b2); - out.write(b3); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public void writeLong(long v) { - writeInt((int)(v >> 0)); - writeInt((int)(v >> 32)); - } - - public void writeShort(int v) { - int b1 = (v >>> 8) & 0xFF; - int b0 = (v >>> 0) & 0xFF; - try { - out.write(b0); - out.write(b1); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - public void write(byte[] b) { - // suppress IOException for interface method - try { - super.write(b); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - public void write(byte[] b, int off, int len) { - // suppress IOException for interface method - try { - super.write(b, off, len); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.util; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * + * @author Josh Micich + */ +public final class LittleEndianOutputStream extends FilterOutputStream implements LittleEndianOutput { + public LittleEndianOutputStream(OutputStream out) { + super(out); + } + + public void writeByte(int v) { + try { + out.write(v); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public void writeDouble(double v) { + writeLong(Double.doubleToLongBits(v)); + } + + public void writeInt(int v) { + int b3 = (v >>> 24) & 0xFF; + int b2 = (v >>> 16) & 0xFF; + int b1 = (v >>> 8) & 0xFF; + int b0 = (v >>> 0) & 0xFF; + try { + out.write(b0); + out.write(b1); + out.write(b2); + out.write(b3); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public void writeLong(long v) { + writeInt((int)(v >> 0)); + writeInt((int)(v >> 32)); + } + + public void writeShort(int v) { + int b1 = (v >>> 8) & 0xFF; + int b0 = (v >>> 0) & 0xFF; + try { + out.write(b0); + out.write(b1); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + public void write(byte[] b) { + // suppress IOException for interface method + try { + super.write(b); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + public void write(byte[] b, int off, int len) { + // suppress IOException for interface method + try { + super.write(b, off, len); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +}