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