From: Andreas Beeker Date: Wed, 17 Sep 2014 21:12:36 +0000 (+0000) Subject: merge with trunk X-Git-Tag: REL_3_11_BETA3~73^2~12 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=56051c3e44486c2b54cc53cf2c91a1f94555f14f;p=poi.git merge with trunk git-svn-id: https://svn.apache.org/repos/asf/poi/branches/xml_signature@1625828 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/KEYS b/KEYS index 5c1de0c2a3..340f8504db 100644 --- a/KEYS +++ b/KEYS @@ -1753,3 +1753,46 @@ W45jdvBkYoPdQtS+8Vy+q0997zobctz8i5hfXzxg51/IuSU4uNtgr26XapsoLDur 7PoqJGZ6UdBVwyb0qZqs6KLGQkEyJ8358ivjJsjxUR8diK027wWnW/s= =/Vu1 -----END PGP PUBLIC KEY BLOCK----- +pub 2048R/26062CE3 2014-08-17 [expires: 2016-08-16] +uid Andreas Beeker +uid Andreas Beeker (kiwiwings) +sub 2048R/EE864ED6 2014-08-17 [expires: 2016-08-16] + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 + +mQENBFPwtjQBCADWg7jYCGq+QFGfB8nLLQs/WEw4XJiAY9q65qWX1clNuVgTF9Nn +ABBOy4KiSDR9XWmARZlC2trKfdoFEnNJ6EnFkLhOjzZKiy4jkyxCctKfbV+sMzCm +ODjjNQtn+nYmOu7a8Xg3g3vTnikkuHZqWvK0O0VYouW/p1NHelUejQbOPuUKukD1 +omzskuYgteTZ9Jn8efJMIymg9dGubuvN4HvUdEO0/u6K2MCZjIqNEPeqWIuZXeMb ++4nGv2r0jSQAU94g3hueooqbUf+Mk2+H5O1d/h2Cii9qVvi6gELdVw9H+5Ir9AFc +ynsmvxrPIxraBMPgrXmvPFOTlqlizyFv2O7pABEBAAG0MkFuZHJlYXMgQmVla2Vy +IChraXdpd2luZ3MpIDxhbmRyZWFzLmJlZWtlckBnbXguZGU+iQE+BBMBAgAoBQJT +8LY0AhsDBQkDwmcABgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRCpPhxLJgYs +4wvFB/9hEV8LzHUpD0X/vM9pfW1ZbTl2GNiZfuMh6/KlqB3C4gL3SLLRlk4mEPM3 +qlZWCqZiWVp5zz1C/j/+BLJW3c+j3rCUEAsobsR6HkxBr7N0LUnurbMXyiOvdg4l +AS42Vi1JrydFdih1HCI3NiGMHAV/8NEdtmLt7Ue8Opx01R6rwXBomX5BHJXnzbZR +bCbdor/UnO8ff5K4jwd6yhY0BV+bI2uD+vGq9nMld0JGj7W7qB+HzOAxpINtHksQ +htTV/PBWjHTCNhOdGh1zyoyvJSshm1NkvwBVZYMs/0ujApcqxAXytGXonLiMmZME +COjxAigph8T4PCEKdIqdsVxkC2ybtCVBbmRyZWFzIEJlZWtlciA8a2l3aXdpbmdz +QGFwYWNoZS5vcmc+iQE+BBMBAgAoBQJT8RApAhsDBQkDwmcABgsJCAcDAgYVCAIJ +CgsEFgIDAQIeAQIXgAAKCRCpPhxLJgYs4732CAC0tb5Wqjf3+/2M6ZzsJR9lqOI6 +SIwaxu0qnHVUJNzRrF01886uae7k086RCVvEXmSxnmGk86odbx/e7gD0esC9xoxz +GRdo5AtMEh18b4fRsq3cdywPDUjvgQBvWXw+jhpJbJe7RRRKZS6X0dRLACn24tGw +GPOkn1cE5gkHxUraEk84PKi69znCULasPOV1X46xU2j42N+v0XC3F1ZgFTesvBPh +O9Nfaj99GnxpL8PmWyKvKm8SSLTmzLoZ+cXSNGGjJtsrnQn5tmhmEgp5K4DX7lsx ++lmfJ9X7+OUxgVHdkesz69d3h+9wBtVl6WqaA+Ocn/0xWr0X55J1OsW+1N2SuQEN +BFPwtjQBCACln6mHC8Js3T3KJgNydimOCAFhLmS4e0ur03Y1nckB9zB/pMTLulDg +tZwWSin3Kd40VZDyKi6mqOp5ldz6AsZ2CSx1GfI9iVhfuFqOaiBLqpNpdvf9nGL9 +OVoy1SdwTXgnboiIFtbTG3sVwD4x4qTRbmT22Ln/mIAICR2wxFBkzpbIQ7MfR/zE +gRh2VlRUUrWUsnYdOh0xfxuYgsnPCjpTY8hvEno3H6kzXKmj2GQJtawMVs5bRo/G +CM9lBBR/PAhB65ACzLmUUSsxjlmjZw0tCcOufg1RyAF/l6YVw1UOJaqXBfSPeZkL +QBj9p8VNpasX/acIfpEaZLE8QhoO11ajABEBAAGJASUEGAECAA8FAlPwtjQCGwwF +CQPCZwAACgkQqT4cSyYGLOPzLggAjHrdpMjZrHM5WqnxkJ1Eib1g14aScMGdOIw9 +NOSQ2AGvJjbSy4xyMEUg3S14I73JGYtJu8g9YvCHbuWiyzySBIuGNinMI/ZjET/w +1noqoNaSlIY4UfFh30g+OikEzP9WXmo0Scg0XH/fJhX1wCpM/TVlphX0yNGmmkNB +BqerRXC7Md4XOy001vvXZGM7vy+xOotyBOy/D4WNERSz3GVS3juCQGMWvMdqKQa+ +qoiVaXWfFHwg8u4bSHunrzNja17GyaZHdCEmM9vFzlaqBkoLWCMwIcaKnX9stQJp +FZwpzgut7DanaPcCDk7LMBbntaJwRC72M0qcj16SUAdAuGt1yQ== +=0DjT +-----END PGP PUBLIC KEY BLOCK----- diff --git a/build.xml b/build.xml index 8f27b57feb..8be3cb707d 100644 --- a/build.xml +++ b/build.xml @@ -164,13 +164,17 @@ under the License. - + + + + + @@ -254,6 +258,7 @@ under the License. + @@ -261,6 +266,7 @@ under the License. + @@ -268,6 +274,7 @@ under the License. + @@ -300,6 +307,7 @@ under the License. + @@ -372,6 +380,7 @@ under the License. + @@ -388,6 +397,7 @@ under the License. + @@ -438,6 +448,10 @@ under the License. + + + + 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(); - 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 @@ -827,6 +827,29 @@ public final class HSSFCellStyle implements CellStyle { return _format.getShrinkToFit(); } + /** + * Get the reading order, for RTL/LTR ordering of + * the text. + *

0 means Context (Default), 1 means Left To Right, + * and 2 means Right to Left

+ * + * @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. + *

0 means Context (Default), 1 means Left To Right, + * and 2 means Right to Left

+ * + * @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. 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 2.3.7.4 Binary Document Password Verifier Derivation Method 2 * * @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.

* - * @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 /** *

Creates a POIFSFileSystem from an open FileChannel. This uses - * less memory than creating from an InputStream.

+ * less memory than creating from an InputStream. The stream will + * be used in read-only mode.

* *

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.

* - * @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); + } + + /** + *

Creates a POIFSFileSystem from an open FileChannel. This uses + * less memory than creating from an InputStream.

+ * + *

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.

+ * + * @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 spreadsheet that are easily + *

Properties of this enum correspond to attributes of the spreadsheet that are easily * discernable to the user. It is not intended to deal with low-level issues like file formats. - *

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

    - *
  • The total number of available columns is 256 (2^8)
  • - *
  • The total number of available rows is 64k (2^16)
  • - *
  • The maximum number of arguments to a function is 30
  • - *
  • Number of conditional format conditions on a cell is 3
  • + /** + * Excel97 format aka BIFF8 + *
      + *
    • The total number of available columns is 256 (2^8)
    • + *
    • The total number of available rows is 64k (2^16)
    • + *
    • The maximum number of arguments to a function is 30
    • + *
    • Number of conditional format conditions on a cell is 3
    • + *
    • Number of cell styles is 4000
    • *
    • Length of text cell contents is 32767
    • - *
    - */ - EXCEL97(0x10000, 0x0100, 30, 3, 32767), - - /** - * Excel2007 - * - *
      - *
    • The total number of available columns is 16K (2^14)
    • - *
    • The total number of available rows is 1M (2^20)
    • - *
    • The maximum number of arguments to a function is 255
    • - *
    • Number of conditional format conditions on a cell is unlimited - * (actually limited by available memory in Excel)
    • + *
    + */ + EXCEL97(0x10000, 0x0100, 30, 3, 4000, 32767), + + /** + * Excel2007 + * + *
      + *
    • The total number of available columns is 16K (2^14)
    • + *
    • The total number of available rows is 1M (2^20)
    • + *
    • The maximum number of arguments to a function is 255
    • + *
    • Number of conditional format conditions on a cell is unlimited + * (actually limited by available memory in Excel)
    • + *
    • Number of cell styles is 64000
    • *
    • Length of text cell contents is 32767
    • - *
        - */ - EXCEL2007(0x100000, 0x4000, 255, Integer.MAX_VALUE, 32767); - - private final int _maxRows; - private final int _maxColumns; - private final int _maxFunctionArgs; - private final int _maxCondFormats; + *
          + */ + 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 getMaxRows() - 1 - */ - public int getLastRowIndex() { - return _maxRows - 1; - } - - /** - * @return the maximum number of usable columns in each spreadsheet - */ - public int getMaxColumns() { - return _maxColumns; - } - - /** - * @return the last (maximum) valid column index, equals to getMaxColumns() - 1 - */ - public int getLastColumnIndex() { - return _maxColumns - 1; - } - - /** - * @return the maximum number arguments that can be passed to a multi-arg function (e.g. COUNTIF) - */ - public int getMaxFunctionArgs() { - return _maxFunctionArgs; - } - - /** - * - * @return the maximum number of conditional format conditions on a cell - */ - public int getMaxConditionalFormats() { - return _maxCondFormats; - } - - /** - * - * @return the last valid column index in a ALPHA-26 representation - * (IV or XFD). - */ - public String getLastColumnName() { - return CellReference.convertNumToColString(getLastColumnIndex()); - } + /** + * @return the maximum number of usable rows in each spreadsheet + */ + public int getMaxRows() { + return _maxRows; + } + + /** + * @return the last (maximum) valid row index, equals to getMaxRows() - 1 + */ + public int getLastRowIndex() { + return _maxRows - 1; + } + + /** + * @return the maximum number of usable columns in each spreadsheet + */ + public int getMaxColumns() { + return _maxColumns; + } + + /** + * @return the last (maximum) valid column index, equals to getMaxColumns() - 1 + */ + public int getLastColumnIndex() { + return _maxColumns - 1; + } + + /** + * @return the maximum number arguments that can be passed to a multi-arg function (e.g. COUNTIF) + */ + public int getMaxFunctionArgs() { + return _maxFunctionArgs; + } + + /** + * @return the maximum number of conditional format conditions on a cell + */ + public int getMaxConditionalFormats() { + return _maxCondFormats; + } + + /** + * @return the maximum number of cell styles per spreadsheet + */ + public int getMaxCellStyles() { + return _maxCellStyles; + } + + /** + * + * @return the last valid column index in a ALPHA-26 representation + * (IV or XFD). + */ + 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 newLength is negative - * @throws NullPointerException - * if original 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 newLength is negative - * @throws NullPointerException - * if original is null - */ - public static 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 (from) must lie between zero - * and original.length, inclusive. The value at - * original[from] is placed into the initial element of the copy - * (unless from == original.length or from == to). - * Values from subsequent elements in the original array are placed into - * subsequent elements in the copy. The final index of the range - * (to), which must be greater than or equal to from, - * may be greater than original.length, in which case - * (byte)0 is placed in all elements of the copy whose index is - * greater than or equal to original.length - from. The length - * of the returned array will be to - from. - * - * 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 from < 0 - * or from > original.length() - * @throws IllegalArgumentException if from > to - * @throws NullPointerException if original 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 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 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 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(); - 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{ List paths = new ArrayList(); 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 ctTableRows = table.getTrList(); - DrawingTableRow[] o = new DrawingTableRow[ctTableRows.size()]; + CTTableRow[] ctTableRows = table.getTrArray(); + DrawingTableRow[] o = new DrawingTableRow[ctTableRows.length]; for (int i=0; i ctTableCells = row.getTcList(); - DrawingTableCell[] o = new DrawingTableCell[ctTableCells.size()]; + CTTableCell[] ctTableCells = row.getTcArray(); + DrawingTableCell[] o = new DrawingTableCell[ctTableCells.length]; for (int i=0; i paragraphs = textBody.getPList(); - DrawingParagraph[] o = new DrawingParagraph[paragraphs.size()]; + CTTextParagraph[] paragraphs = textBody.getPArray(); + DrawingParagraph[] o = new DrawingParagraph[paragraphs.length]; for (int i=0; i computeOutlines(Graphics2D graphics) { Collection lst = new ArrayList(); @@ -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(); if (_presentation.isSetSldIdLst()) { - List 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 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 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 out) { - List 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 _rows; + @SuppressWarnings("deprecation") /*package*/ XSLFTable(CTGraphicalObjectFrame shape, XSLFSheet sheet){ super(shape, sheet); @@ -71,8 +72,9 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable(_table.sizeOfTrArray()); - for(CTTableRow row : _table.getTrList()) _rows.add(new XSLFTableRow(row, this)); + CTTableRow[] trArray = _table.getTrArray(); + _rows = new ArrayList(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 { private List _cells; private XSLFTable _table; + @SuppressWarnings("deprecation") /*package*/ XSLFTableRow(CTTableRow row, XSLFTable table){ _row = row; _table = table; - _cells = new ArrayList(_row.sizeOfTcArray()); - for(CTTableCell cell : _row.getTcList()) { + CTTableCell[] tcArray = _row.getTcArray(); + _cells = new ArrayList(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{ private CTTableStyleList _tblStyleLst; @@ -39,12 +39,14 @@ public class XSLFTableStyles extends POIXMLDocumentPart implements Iterable(_tblStyleLst.sizeOfTblStyleArray()); - for(CTTableStyle c : _tblStyleLst.getTblStyleList()){ + CTTableStyle[] tblStyleArray = _tblStyleLst.getTblStyleArray(); + _styles = new ArrayList(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(); 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(); - List 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{ 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 rootElement = map.getCtMap().getRootElement(); - Document doc = getEmptyDocument(); + Document doc = DocumentHelper.createDocument(); Element root = null; @@ -459,8 +448,8 @@ public class XSSFExportToXml implements Comparator{ 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{ 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{ 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{ 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(); - 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 getAllSimpleXmlCell(){ List list = new Vector(); - 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 collection, referencing a particular or * value expressed in the Theme part. */ public int getTheme() { return (int)ctColor.getTheme(); - } - + } + /** * Index into the collection, referencing a particular or * 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 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 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 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 { * * @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 { } if(!isOrdered){ - CTCell[] cArray = new CTCell[_cells.size()]; + cArray = new CTCell[_cells.size()]; int i = 0; - for (Map.Entry 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 null */ @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,18 +1139,27 @@ 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 null */ @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: + 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: - 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 indices) { + if (!worksheet.isSetMergeCells()) return; + + CTMergeCells ctMergeCells = worksheet.getMergeCells(); + List newMergeCells = new ArrayList(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: - 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 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 getTables() { - List tableList = new ArrayList( - tables.values() - ); - return tableList; + return new ArrayList(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 refs = new ArrayList(); 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 getXmlColumnPrs() { if(xmlColumnPr==null){ xmlColumnPr = new ArrayList(); - 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 must 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(); 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 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 { - - 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 Sweep line algorithm */ private void sweepCleanColumns(CTCols cols, CTCol[] flattenedColsArray, CTCol overrideColumn) { List flattenedCols = new ArrayList(Arrays.asList(flattenedColsArray)); - TreeSet currentElements = new TreeSet(new CTColByMaxComparator()); + TreeSet currentElements = new TreeSet(CTColComparator.BY_MAX); ListIterator 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 currentIndexElements = new HashSet(); @@ -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 shiftMerged(int startRow, int endRow, int n) { List shiftedRegions = new ArrayList(); + Set removedIndices = new HashSet(); //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 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 cellRanges = new ArrayList(); 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 temp = new ArrayList(); - 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 refs = new ArrayList(); @@ -257,14 +266,14 @@ public final class XSSFRowShifter { cf.setSqref(refs); } - for(CTCfRule cfRule : cf.getCfRuleList()){ - List 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{ +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 BY_MAX = new Comparator() { + @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 BY_MIN_MAX = new Comparator() { + @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 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 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 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 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,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 drawingList = r.getDrawingList(); - for (CTDrawing ctDrawing : drawingList) { - List 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 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 pictTextObjs = new ArrayList(); - 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 bodyElements = new ArrayList(); 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(); paragraphs = new ArrayList(); @@ -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 getTableCells(){ if(tableCells == null){ List cells = new ArrayList(); - 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 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("")[1].split("")[0].trim()); + assertEquals("12.5", xmlData.split("")[1].split("")[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("Incorrec", t1.xmlText()); assertEquals("t\nLine-Breaking", 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("Incorrect", t1.xmlText()); assertEquals("\nLine-Breaking", 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("Incorrect", t1.xmlText()); assertEquals("\n Line-Breaking", t2.xmlText()); @@ -333,15 +333,15 @@ public final class TestXSSFRichTextString extends TestCase { assertEquals("Tab\tseparated\n", 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("Tab", t1.xmlText()); assertEquals("\tseparated\n", 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("Tab\t", t1.xmlText()); assertEquals("separated\n", 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("\n\n\n", t1.xmlText()); assertEquals("New Line", 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 rmIdx = new HashSet(Arrays.asList(5,6)); + sheet.removeMergedRegions(rmIdx); + rmIdx = new HashSet(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 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 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 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 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 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 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){ diff --git a/test-data/spreadsheet/56730.xlsx b/test-data/spreadsheet/56730.xlsx new file mode 100644 index 0000000000..9883de4f66 Binary files /dev/null and b/test-data/spreadsheet/56730.xlsx differ diff --git a/test-data/spreadsheet/Themes.xlsx b/test-data/spreadsheet/Themes.xlsx new file mode 100644 index 0000000000..188f1bdbc2 Binary files /dev/null and b/test-data/spreadsheet/Themes.xlsx differ diff --git a/test-data/spreadsheet/workbookProtection-sheet_password-2013.xlsx b/test-data/spreadsheet/workbookProtection-sheet_password-2013.xlsx new file mode 100644 index 0000000000..691b2cc219 Binary files /dev/null and b/test-data/spreadsheet/workbookProtection-sheet_password-2013.xlsx differ diff --git a/test-data/spreadsheet/workbookProtection-workbook_password-2013.xlsx b/test-data/spreadsheet/workbookProtection-workbook_password-2013.xlsx new file mode 100644 index 0000000000..978210787c Binary files /dev/null and b/test-data/spreadsheet/workbookProtection-workbook_password-2013.xlsx differ diff --git a/test-data/spreadsheet/workbookProtection-workbook_password_user_range-2010.xlsx b/test-data/spreadsheet/workbookProtection-workbook_password_user_range-2010.xlsx new file mode 100644 index 0000000000..2712913380 Binary files /dev/null and b/test-data/spreadsheet/workbookProtection-workbook_password_user_range-2010.xlsx differ