git-svn-id: https://svn.apache.org/repos/asf/poi/branches/xml_signature@1625828 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_11_BETA3
@@ -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 <kiwiwings@apache.org> | |||
uid Andreas Beeker (kiwiwings) <andreas.beeker@gmx.de> | |||
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----- |
@@ -164,13 +164,17 @@ under the License. | |||
<property name="ooxml.xmlbeans26.jar" location="${ooxml.lib}/xmlbeans-2.6.0.jar"/> | |||
<property name="ooxml.xmlbeans26.url" | |||
value="${repository.m2}/maven2/org/apache/xmlbeans/xmlbeans/2.6.0/xmlbeans-2.6.0.jar"/> | |||
<!-- coverage libs --> | |||
<property name="jacoco.zip" location="${main.lib}/jacoco-0.7.1.201405082137.zip"/> | |||
<property name="jacoco.url" value="${repository.m2}/maven2/org/jacoco/jacoco/0.7.1.201405082137/jacoco-0.7.1.201405082137.zip"/> | |||
<property name="asm.jar" location="${main.lib}/asm-all-5.0.3.jar"/> | |||
<property name="asm.url" value="${repository.m2}/maven2/org/ow2/asm/asm-all/5.0.3/asm-all-5.0.3.jar"/> | |||
<!-- for testing with older Xerces implementation --> | |||
<property name="xerces.jar" location="${main.lib}/xercesImpl-2.6.1.jar"/> | |||
<property name="xerces.url" value="${repository.m2}/maven2/xerces/xercesImpl/2.6.1//xercesImpl-2.6.1.jar"/> | |||
<!-- license checks --> | |||
<property name="rat.jar" location="${main.lib}/apache-rat-0.10.jar"/> | |||
<property name="rat.url" value="${repository.m2}/maven2/org/apache/rat/apache-rat/0.10/apache-rat-0.10.jar"/> | |||
@@ -254,6 +258,7 @@ under the License. | |||
<path refid="main.classpath"/> | |||
<pathelement location="${main.output.dir}"/> | |||
<pathelement location="${main.output.test.dir}"/> | |||
<pathelement location="${additionaljar}"/> | |||
</path> | |||
<path id="test.scratchpad.classpath"> | |||
@@ -261,6 +266,7 @@ under the License. | |||
<pathelement location="${main.output.test.dir}"/> | |||
<pathelement location="${scratchpad.output.dir}"/> | |||
<pathelement location="${scratchpad.output.test.dir}"/> | |||
<pathelement location="${additionaljar}"/> | |||
</path> | |||
<path id="test.ooxml.classpath"> | |||
@@ -268,6 +274,7 @@ under the License. | |||
<pathelement location="${ooxml.output.dir}"/> | |||
<pathelement location="${ooxml.output.test.dir}"/> | |||
<pathelement location="${main.output.test.dir}"/> | |||
<pathelement location="${additionaljar}"/> | |||
</path> | |||
<path id="ooxml-lite.classpath"> | |||
@@ -300,6 +307,7 @@ under the License. | |||
<pathelement location="${excelant.output.dir}"/> | |||
<pathelement location="${excelant.output.test.dir}"/> | |||
<pathelement location="${main.output.test.dir}"/> | |||
<pathelement location="${additionaljar}"/> | |||
</path> | |||
<path id="lib.jacoco"> | |||
@@ -372,6 +380,7 @@ under the License. | |||
<include name="jacoco-0.6*"/> | |||
<include name="log4j-1.2.13*"/> | |||
<include name="org.jacoco.*-0.6.*"/> | |||
<include name="dom4j*"/> | |||
</fileset> | |||
</delete> | |||
@@ -388,6 +397,7 @@ under the License. | |||
<available file="${asm.jar}"/> | |||
<available file="${jacoco.zip}"/> | |||
<available file="${rat.jar}"/> | |||
<available file="${xerces.jar}"/> | |||
</and> | |||
<isset property="disconnected"/> | |||
</or> | |||
@@ -438,6 +448,10 @@ under the License. | |||
<include name="lib/*.jar"/> | |||
</patternset> | |||
</unzip> | |||
<antcall target="downloadfile"> | |||
<param name="sourcefile" value="${xerces.url}"/> | |||
<param name="destfile" value="${xerces.jar}"/> | |||
</antcall> | |||
<antcall target="downloadfile"> | |||
<param name="sourcefile" value="${rat.url}"/> | |||
<param name="destfile" value="${rat.jar}"/> |
@@ -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 |
@@ -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); |
@@ -57,20 +57,19 @@ public abstract class AbstractEscherHolderRecord extends Record { | |||
public AbstractEscherHolderRecord(RecordInputStream in) | |||
{ | |||
escherRecords = new ArrayList<EscherRecord>(); | |||
if (! DESERIALISE ) | |||
{ | |||
if (! DESERIALISE ) { | |||
rawDataContainer.concatenate(in.readRemainder()); | |||
} | |||
else | |||
{ | |||
} else { | |||
byte[] data = in.readAllContinuedRemainder(); | |||
convertToEscherRecords( 0, data.length, data ); | |||
} | |||
} | |||
protected void convertRawBytesToEscherRecords() { | |||
byte[] rawData = getRawData(); | |||
convertToEscherRecords(0, rawData.length, rawData); | |||
if (! DESERIALISE ) { | |||
byte[] rawData = getRawData(); | |||
convertToEscherRecords(0, rawData.length, rawData); | |||
} | |||
} | |||
private void convertToEscherRecords( int offset, int size, byte[] data ) | |||
{ | |||
@@ -224,7 +223,7 @@ public abstract class AbstractEscherHolderRecord extends Record { | |||
public EscherRecord getEscherRecord(int index) | |||
{ | |||
return (EscherRecord) escherRecords.get(index); | |||
return escherRecords.get(index); | |||
} | |||
/** |
@@ -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; |
@@ -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; |
@@ -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); | |||
} | |||
/** |
@@ -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); |
@@ -827,6 +827,29 @@ public final class HSSFCellStyle implements CellStyle { | |||
return _format.getShrinkToFit(); | |||
} | |||
/** | |||
* Get the reading order, for RTL/LTR ordering of | |||
* the text. | |||
* <p>0 means Context (Default), 1 means Left To Right, | |||
* and 2 means Right to Left</p> | |||
* | |||
* @return order - the reading order (0,1,2) | |||
*/ | |||
public short getReadingOrder() { | |||
return _format.getReadingOrder(); | |||
} | |||
/** | |||
* Sets the reading order, for RTL/LTR ordering of | |||
* the text. | |||
* <p>0 means Context (Default), 1 means Left To Right, | |||
* and 2 means Right to Left</p> | |||
* | |||
* @param order - the reading order (0,1,2) | |||
*/ | |||
public void setReadingOrder(short order) { | |||
_format.setReadingOrder(order); | |||
} | |||
/** | |||
* Verifies that this style belongs to the supplied Workbook. | |||
* Will throw an exception if it belongs to a different one. |
@@ -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. |
@@ -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. |
@@ -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; |
@@ -181,14 +181,20 @@ public class CryptoFunctions { | |||
} | |||
/** | |||
* | |||
* Initialize a new cipher object with the given cipher properties | |||
* If the given algorithm is not implemented in the JCE, it will try to load it from the bouncy castle | |||
* provider. | |||
* | |||
* @param key | |||
* @param chain | |||
* @param vec | |||
* @param key the secrect key | |||
* @param cipherAlgorithm the cipher algorithm | |||
* @param chain the chaining mode | |||
* @param vec the initialization vector (IV), can be null | |||
* @param cipherMode Cipher.DECRYPT_MODE or Cipher.ENCRYPT_MODE | |||
* @param padding | |||
* @return the requested cipher | |||
* @throws GeneralSecurityException | |||
* @throws EncryptedDocumentException if the initialization failed or if an algorithm was specified, | |||
* which depends on a missing bouncy castle provider | |||
*/ | |||
public static Cipher getCipher(Key key, CipherAlgorithm cipherAlgorithm, ChainingMode chain, byte[] vec, int cipherMode, String padding) { | |||
int keySizeInBytes = key.getEncoded().length; | |||
@@ -227,10 +233,26 @@ public class CryptoFunctions { | |||
} | |||
} | |||
/** | |||
* Returns a new byte array with a truncated to the given size. | |||
* If the hash has less then size bytes, it will be filled with 0x36-bytes | |||
* | |||
* @param hash the to be truncated/filled hash byte array | |||
* @param size the size of the returned byte array | |||
* @return the padded hash | |||
*/ | |||
public static byte[] getBlock36(byte[] hash, int size) { | |||
return getBlockX(hash, size, (byte)0x36); | |||
} | |||
/** | |||
* Returns a new byte array with a truncated to the given size. | |||
* If the hash has less then size bytes, it will be filled with 0-bytes | |||
* | |||
* @param hash the to be truncated/filled hash byte array | |||
* @param size the size of the returned byte array | |||
* @return the padded hash | |||
*/ | |||
public static byte[] getBlock0(byte[] hash, int size) { | |||
return getBlockX(hash, size, (byte)0); | |||
} | |||
@@ -334,11 +356,11 @@ public class CryptoFunctions { | |||
byte[] generatedKey = new byte[4]; | |||
//Maximum length of the password is 15 chars. | |||
final int intMaxPasswordLength = 15; | |||
final int maxPasswordLength = 15; | |||
if (!"".equals(password)) { | |||
// Truncate the password to 15 characters | |||
password = password.substring(0, Math.min(password.length(), intMaxPasswordLength)); | |||
password = password.substring(0, Math.min(password.length(), maxPasswordLength)); | |||
// Construct a new NULL-terminated string consisting of single-byte characters: | |||
// -- > Get the single-byte values by iterating through the Unicode characters of the truncated Password. | |||
@@ -362,7 +384,7 @@ public class CryptoFunctions { | |||
// the most significant, if the bit is set, XOR the keys high-order word with the corresponding word from | |||
// the Encryption Matrix | |||
for (int i = 0; i < arrByteChars.length; i++) { | |||
int tmp = intMaxPasswordLength - arrByteChars.length + i; | |||
int tmp = maxPasswordLength - arrByteChars.length + i; | |||
for (int intBit = 0; intBit < 7; intBit++) { | |||
if ((arrByteChars[i] & (0x0001 << intBit)) != 0) { | |||
highOrderWord ^= EncryptionMatrix[tmp][intBit]; | |||
@@ -372,22 +394,28 @@ public class CryptoFunctions { | |||
// Compute the low-order word of the new key: | |||
// Initialize with 0 | |||
int lowOrderWord = 0; | |||
// SET Verifier TO 0x0000 | |||
short verifier = 0; | |||
// For each character in the password, going backwards | |||
for (int i = arrByteChars.length - 1; i >= 0; i--) { | |||
// low-order word = (((low-order word SHR 14) AND 0x0001) OR (low-order word SHL 1) AND 0x7FFF)) XOR character | |||
lowOrderWord = (((lowOrderWord >> 14) & 0x0001) | ((lowOrderWord << 1) & 0x7FFF)) ^ arrByteChars[i]; | |||
// FOR EACH PasswordByte IN PasswordArray IN REVERSE ORDER | |||
for (int i = arrByteChars.length-1; i >= 0; i--) { | |||
// SET Verifier TO Intermediate3 BITWISE XOR PasswordByte | |||
verifier = rotateLeftBase15Bit(verifier); | |||
verifier ^= arrByteChars[i]; | |||
} | |||
// Lastly,low-order word = (((low-order word SHR 14) AND 0x0001) OR (low-order word SHL 1) AND 0x7FFF)) XOR password length XOR 0xCE4B. | |||
lowOrderWord = (((lowOrderWord >> 14) & 0x0001) | ((lowOrderWord << 1) & 0x7FFF)) ^ arrByteChars.length ^ 0xCE4B; | |||
// as we haven't prepended the password length into the input array | |||
// we need to do it now separately ... | |||
verifier = rotateLeftBase15Bit(verifier); | |||
verifier ^= arrByteChars.length; | |||
// RETURN Verifier BITWISE XOR 0xCE4B | |||
verifier ^= 0xCE4B; // (0x8000 | ('N' << 8) | 'K') | |||
// The byte order of the result shall be reversed [password "Example": 0x64CEED7E becomes 7EEDCE64], | |||
// and that value shall be hashed as defined by the attribute values. | |||
LittleEndian.putShort(generatedKey, 0, (short)lowOrderWord); | |||
LittleEndian.putShort(generatedKey, 0, verifier); | |||
LittleEndian.putShort(generatedKey, 2, (short)highOrderWord); | |||
} | |||
@@ -424,7 +452,7 @@ public class CryptoFunctions { | |||
* @see <a href="http://msdn.microsoft.com/en-us/library/dd905229.aspx">2.3.7.4 Binary Document Password Verifier Derivation Method 2</a> | |||
* | |||
* @param password the password | |||
* @return the verifier | |||
* @return the verifier (actually a short value) | |||
*/ | |||
public static int createXorVerifier1(String password) { | |||
// the verifier for method 1 is part of the verifier for method 2 | |||
@@ -483,4 +511,25 @@ public class CryptoFunctions { | |||
private static byte rotateLeft(byte bits, int shift) { | |||
return (byte)(((bits & 0xff) << shift) | ((bits & 0xff) >>> (8 - shift))); | |||
} | |||
private static short rotateLeftBase15Bit(short verifier) { | |||
/* | |||
* IF (Verifier BITWISE AND 0x4000) is 0x0000 | |||
* SET Intermediate1 TO 0 | |||
* ELSE | |||
* SET Intermediate1 TO 1 | |||
* ENDIF | |||
*/ | |||
short intermediate1 = (short)(((verifier & 0x4000) == 0) ? 0 : 1); | |||
/* | |||
* SET Intermediate2 TO Verifier MULTIPLED BY 2 | |||
* SET most significant bit of Intermediate2 TO 0 | |||
*/ | |||
short intermediate2 = (short)((verifier<<1) & 0x7FFF); | |||
/* | |||
* SET Intermediate3 TO Intermediate1 BITWISE OR Intermediate2 | |||
*/ | |||
short intermediate3 = (short)(intermediate1 | intermediate2); | |||
return intermediate3; | |||
} | |||
} |
@@ -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"); | |||
} | |||
} |
@@ -153,7 +153,8 @@ public class NPOIFSFileSystem extends BlockStore | |||
* when you're done to have the underlying file closed, as the file is | |||
* kept open during normal operation to read the data out.</p> | |||
* | |||
* @param file the File from which to read the data | |||
* @param file the File from which to read or read/write the data | |||
* @param readOnly whether the POIFileSystem will only be used in read-only mode | |||
* | |||
* @exception IOException on errors reading, or on invalid data | |||
*/ | |||
@@ -165,20 +166,40 @@ public class NPOIFSFileSystem extends BlockStore | |||
/** | |||
* <p>Creates a POIFSFileSystem from an open <tt>FileChannel</tt>. This uses | |||
* less memory than creating from an <tt>InputStream</tt>.</p> | |||
* less memory than creating from an <tt>InputStream</tt>. The stream will | |||
* be used in read-only mode.</p> | |||
* | |||
* <p>Note that with this constructor, you will need to call {@link #close()} | |||
* when you're done to have the underlying Channel closed, as the channel is | |||
* kept open during normal operation to read the data out.</p> | |||
* | |||
* @param channel the FileChannel from which to read and write the data | |||
* @param channel the FileChannel from which to read the data | |||
* | |||
* @exception IOException on errors reading, or on invalid data | |||
*/ | |||
public NPOIFSFileSystem(FileChannel channel) | |||
throws IOException | |||
{ | |||
this(channel, null, false, false); | |||
this(channel, true); | |||
} | |||
/** | |||
* <p>Creates a POIFSFileSystem from an open <tt>FileChannel</tt>. This uses | |||
* less memory than creating from an <tt>InputStream</tt>.</p> | |||
* | |||
* <p>Note that with this constructor, you will need to call {@link #close()} | |||
* when you're done to have the underlying Channel closed, as the channel is | |||
* kept open during normal operation to read the data out.</p> | |||
* | |||
* @param channel the FileChannel from which to read or read/write the data | |||
* @param readOnly whether the POIFileSystem will only be used in read-only mode | |||
* | |||
* @exception IOException on errors reading, or on invalid data | |||
*/ | |||
public NPOIFSFileSystem(FileChannel channel, boolean readOnly) | |||
throws IOException | |||
{ | |||
this(channel, null, readOnly, false); | |||
} | |||
private NPOIFSFileSystem(FileChannel channel, File srcFile, boolean readOnly, boolean closeChannelOnError) |
@@ -21,105 +21,111 @@ import org.apache.poi.ss.util.CellReference; | |||
/** | |||
* This enum allows spreadsheets from multiple Excel versions to be handled by the common code. | |||
* Properties of this enum correspond to attributes of the <i>spreadsheet</i> that are easily | |||
* <p>Properties of this enum correspond to attributes of the <i>spreadsheet</i> that are easily | |||
* discernable to the user. It is not intended to deal with low-level issues like file formats. | |||
* <p/> | |||
* | |||
* @author Josh Micich | |||
* @author Yegor Kozlov | |||
*/ | |||
public enum SpreadsheetVersion { | |||
/** | |||
* Excel97 format aka BIFF8 | |||
* <ul> | |||
* <li>The total number of available columns is 256 (2^8)</li> | |||
* <li>The total number of available rows is 64k (2^16)</li> | |||
* <li>The maximum number of arguments to a function is 30</li> | |||
* <li>Number of conditional format conditions on a cell is 3</li> | |||
/** | |||
* Excel97 format aka BIFF8 | |||
* <ul> | |||
* <li>The total number of available columns is 256 (2^8)</li> | |||
* <li>The total number of available rows is 64k (2^16)</li> | |||
* <li>The maximum number of arguments to a function is 30</li> | |||
* <li>Number of conditional format conditions on a cell is 3</li> | |||
* <li>Number of cell styles is 4000</li> | |||
* <li>Length of text cell contents is 32767</li> | |||
* </ul> | |||
*/ | |||
EXCEL97(0x10000, 0x0100, 30, 3, 32767), | |||
/** | |||
* Excel2007 | |||
* | |||
* <ul> | |||
* <li>The total number of available columns is 16K (2^14)</li> | |||
* <li>The total number of available rows is 1M (2^20)</li> | |||
* <li>The maximum number of arguments to a function is 255</li> | |||
* <li>Number of conditional format conditions on a cell is unlimited | |||
* (actually limited by available memory in Excel)</li> | |||
* </ul> | |||
*/ | |||
EXCEL97(0x10000, 0x0100, 30, 3, 4000, 32767), | |||
/** | |||
* Excel2007 | |||
* | |||
* <ul> | |||
* <li>The total number of available columns is 16K (2^14)</li> | |||
* <li>The total number of available rows is 1M (2^20)</li> | |||
* <li>The maximum number of arguments to a function is 255</li> | |||
* <li>Number of conditional format conditions on a cell is unlimited | |||
* (actually limited by available memory in Excel)</li> | |||
* <li>Number of cell styles is 64000</li> | |||
* <li>Length of text cell contents is 32767</li> | |||
* <ul> | |||
*/ | |||
EXCEL2007(0x100000, 0x4000, 255, Integer.MAX_VALUE, 32767); | |||
private final int _maxRows; | |||
private final int _maxColumns; | |||
private final int _maxFunctionArgs; | |||
private final int _maxCondFormats; | |||
* <ul> | |||
*/ | |||
EXCEL2007(0x100000, 0x4000, 255, Integer.MAX_VALUE, 64000, 32767); | |||
private final int _maxRows; | |||
private final int _maxColumns; | |||
private final int _maxFunctionArgs; | |||
private final int _maxCondFormats; | |||
private final int _maxCellStyles; | |||
private final int _maxTextLength; | |||
private SpreadsheetVersion(int maxRows, int maxColumns, int maxFunctionArgs, int maxCondFormats, int maxText) { | |||
_maxRows = maxRows; | |||
_maxColumns = maxColumns; | |||
_maxFunctionArgs = maxFunctionArgs; | |||
_maxCondFormats = maxCondFormats; | |||
private SpreadsheetVersion(int maxRows, int maxColumns, int maxFunctionArgs, int maxCondFormats, int maxCellStyles, int maxText) { | |||
_maxRows = maxRows; | |||
_maxColumns = maxColumns; | |||
_maxFunctionArgs = maxFunctionArgs; | |||
_maxCondFormats = maxCondFormats; | |||
_maxCellStyles = maxCellStyles; | |||
_maxTextLength = maxText; | |||
} | |||
/** | |||
* @return the maximum number of usable rows in each spreadsheet | |||
*/ | |||
public int getMaxRows() { | |||
return _maxRows; | |||
} | |||
/** | |||
* @return the last (maximum) valid row index, equals to <code> getMaxRows() - 1 </code> | |||
*/ | |||
public int getLastRowIndex() { | |||
return _maxRows - 1; | |||
} | |||
/** | |||
* @return the maximum number of usable columns in each spreadsheet | |||
*/ | |||
public int getMaxColumns() { | |||
return _maxColumns; | |||
} | |||
/** | |||
* @return the last (maximum) valid column index, equals to <code> getMaxColumns() - 1 </code> | |||
*/ | |||
public int getLastColumnIndex() { | |||
return _maxColumns - 1; | |||
} | |||
/** | |||
* @return the maximum number arguments that can be passed to a multi-arg function (e.g. COUNTIF) | |||
*/ | |||
public int getMaxFunctionArgs() { | |||
return _maxFunctionArgs; | |||
} | |||
/** | |||
* | |||
* @return the maximum number of conditional format conditions on a cell | |||
*/ | |||
public int getMaxConditionalFormats() { | |||
return _maxCondFormats; | |||
} | |||
/** | |||
* | |||
* @return the last valid column index in a ALPHA-26 representation | |||
* (<code>IV</code> or <code>XFD</code>). | |||
*/ | |||
public String getLastColumnName() { | |||
return CellReference.convertNumToColString(getLastColumnIndex()); | |||
} | |||
/** | |||
* @return the maximum number of usable rows in each spreadsheet | |||
*/ | |||
public int getMaxRows() { | |||
return _maxRows; | |||
} | |||
/** | |||
* @return the last (maximum) valid row index, equals to <code> getMaxRows() - 1 </code> | |||
*/ | |||
public int getLastRowIndex() { | |||
return _maxRows - 1; | |||
} | |||
/** | |||
* @return the maximum number of usable columns in each spreadsheet | |||
*/ | |||
public int getMaxColumns() { | |||
return _maxColumns; | |||
} | |||
/** | |||
* @return the last (maximum) valid column index, equals to <code> getMaxColumns() - 1 </code> | |||
*/ | |||
public int getLastColumnIndex() { | |||
return _maxColumns - 1; | |||
} | |||
/** | |||
* @return the maximum number arguments that can be passed to a multi-arg function (e.g. COUNTIF) | |||
*/ | |||
public int getMaxFunctionArgs() { | |||
return _maxFunctionArgs; | |||
} | |||
/** | |||
* @return the maximum number of conditional format conditions on a cell | |||
*/ | |||
public int getMaxConditionalFormats() { | |||
return _maxCondFormats; | |||
} | |||
/** | |||
* @return the maximum number of cell styles per spreadsheet | |||
*/ | |||
public int getMaxCellStyles() { | |||
return _maxCellStyles; | |||
} | |||
/** | |||
* | |||
* @return the last valid column index in a ALPHA-26 representation | |||
* (<code>IV</code> or <code>XFD</code>). | |||
*/ | |||
public String getLastColumnName() { | |||
return CellReference.convertNumToColString(getLastColumnIndex()); | |||
} | |||
/** | |||
* @return the maximum length of a text cell | |||
@@ -127,5 +133,4 @@ public enum SpreadsheetVersion { | |||
public int getMaxTextLength() { | |||
return _maxTextLength; | |||
} | |||
} |
@@ -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); |
@@ -106,89 +106,4 @@ public class ArrayUtil | |||
// We're done - array will now have everything moved as required | |||
} | |||
/** | |||
* Copies the specified array, truncating or padding with zeros (if | |||
* necessary) so the copy has the specified length. This method is temporary | |||
* replace for Arrays.copyOf() until we start to require JDK 1.6. | |||
* | |||
* @param source | |||
* the array to be copied | |||
* @param newLength | |||
* the length of the copy to be returned | |||
* @return a copy of the original array, truncated or padded with zeros to | |||
* obtain the specified length | |||
* @throws NegativeArraySizeException | |||
* if <tt>newLength</tt> is negative | |||
* @throws NullPointerException | |||
* if <tt>original</tt> is null | |||
*/ | |||
public static byte[] copyOf( byte[] source, int newLength ) | |||
{ | |||
byte[] result = new byte[newLength]; | |||
System.arraycopy( source, 0, result, 0, | |||
Math.min( source.length, newLength ) ); | |||
return result; | |||
} | |||
/** | |||
* Copies the specified array into specified result array, truncating or | |||
* padding with zeros (if necessary) so the copy has the specified length. | |||
* This method is temporary replace for Arrays.copyOf() until we start to | |||
* require JDK 1.6. | |||
* | |||
* @param source | |||
* the array to be copied | |||
* @param result | |||
* the array to be filled and returned | |||
* @throws NegativeArraySizeException | |||
* if <tt>newLength</tt> is negative | |||
* @throws NullPointerException | |||
* if <tt>original</tt> is null | |||
*/ | |||
public static <T> T[] copyOf( T[] source, T[] result ) | |||
{ | |||
System.arraycopy( source, 0, result, 0, | |||
Math.min( source.length, result.length ) ); | |||
return result; | |||
} | |||
/** | |||
* Copies the specified range of the specified array into a new array. | |||
* The initial index of the range (<tt>from</tt>) must lie between zero | |||
* and <tt>original.length</tt>, inclusive. The value at | |||
* <tt>original[from]</tt> is placed into the initial element of the copy | |||
* (unless <tt>from == original.length</tt> or <tt>from == to</tt>). | |||
* Values from subsequent elements in the original array are placed into | |||
* subsequent elements in the copy. The final index of the range | |||
* (<tt>to</tt>), which must be greater than or equal to <tt>from</tt>, | |||
* may be greater than <tt>original.length</tt>, in which case | |||
* <tt>(byte)0</tt> is placed in all elements of the copy whose index is | |||
* greater than or equal to <tt>original.length - from</tt>. The length | |||
* of the returned array will be <tt>to - from</tt>. | |||
* | |||
* This method is temporary | |||
* replace for Arrays.copyOfRange() until we start to require JDK 1.6. | |||
* | |||
* @param original the array from which a range is to be copied | |||
* @param from the initial index of the range to be copied, inclusive | |||
* @param to the final index of the range to be copied, exclusive. | |||
* (This index may lie outside the array.) | |||
* @return a new array containing the specified range from the original array, | |||
* truncated or padded with zeros to obtain the required length | |||
* @throws ArrayIndexOutOfBoundsException if <tt>from < 0</tt> | |||
* or <tt>from > original.length()</tt> | |||
* @throws IllegalArgumentException if <tt>from > to</tt> | |||
* @throws NullPointerException if <tt>original</tt> is null | |||
* @since 1.6 | |||
*/ | |||
public static byte[] copyOfRange(byte[] original, int from, int to) { | |||
int newLength = to - from; | |||
if (newLength < 0) | |||
throw new IllegalArgumentException(from + " > " + to); | |||
byte[] copy = new byte[newLength]; | |||
System.arraycopy(original, from, copy, 0, | |||
Math.min(original.length - from, newLength)); | |||
return copy; | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
} |
@@ -19,7 +19,6 @@ package org.apache.poi; | |||
import java.math.BigDecimal; | |||
import java.util.Date; | |||
import java.util.List; | |||
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart; | |||
import org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty; | |||
@@ -126,13 +125,13 @@ public class POIXMLPropertiesTextExtractor extends POIXMLTextExtractor { | |||
* Returns the custom document properties, if | |||
* there are any | |||
*/ | |||
@SuppressWarnings("deprecation") | |||
public String getCustomPropertiesText() { | |||
StringBuffer text = new StringBuffer(); | |||
StringBuilder text = new StringBuilder(); | |||
org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperties | |||
props = getDocument().getProperties().getCustomProperties().getUnderlyingProperties(); | |||
List<CTProperty> properties = props.getPropertyList(); | |||
for(CTProperty property : properties) { | |||
for(CTProperty property : props.getPropertyArray()) { | |||
String val = "(not implemented!)"; | |||
if (property.isSetLpwstr()) { |
@@ -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(); |
@@ -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); |
@@ -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 */ | |||
@@ -57,9 +57,9 @@ import org.apache.poi.poifs.crypt.HashAlgorithm; | |||
import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService; | |||
import org.apache.poi.poifs.crypt.dsig.services.XmlSignatureService; | |||
import org.apache.poi.poifs.crypt.dsig.spi.DigestInfo; | |||
import org.apache.poi.util.DocumentHelper; | |||
import org.apache.poi.util.POILogFactory; | |||
import org.apache.poi.util.POILogger; | |||
import org.apache.poi.util.SAXHelper; | |||
import org.apache.xml.security.Init; | |||
import org.apache.xmlbeans.XmlCursor; | |||
import org.apache.xmlbeans.XmlException; | |||
@@ -127,7 +127,7 @@ public class SignatureInfo { | |||
throws NoSuchAlgorithmException, IOException, MarshalException, ParserConfigurationException, XmlException { | |||
XmlSignatureService signatureService = createSignatureService(hashAlgo, pkg); | |||
Document document = SAXHelper.getDocumentBuilder().newDocument(); | |||
Document document = DocumentHelper.createDocument(); | |||
// operate | |||
List<X509Certificate> x509Chain = Collections.singletonList(x509); | |||
@@ -181,7 +181,7 @@ public class SignatureInfo { | |||
KeyInfoKeySelector keySelector = new KeyInfoKeySelector(); | |||
try { | |||
Document doc = SAXHelper.readSAXDocument(signaturePart.getInputStream()); | |||
Document doc = DocumentHelper.readDocument(signaturePart.getInputStream()); | |||
// dummy call to createSignatureService to tweak document afterwards | |||
createSignatureService(HashAlgorithm.sha1, pkg).registerIds(doc); | |||
@@ -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(); | |||
} | |||
/** |
@@ -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); | |||
} | |||
} |
@@ -31,7 +31,20 @@ import org.apache.poi.util.Internal; | |||
import org.apache.poi.xslf.usermodel.XMLSlideShow; | |||
import org.apache.poi.xslf.usermodel.XSLFRelation; | |||
import org.apache.xmlbeans.XmlException; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.*; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.CTCommentList; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesSlide; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPresentation; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdList; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMaster; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdList; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdListEntry; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.CmLstDocument; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.NotesDocument; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.PresentationDocument; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.SldDocument; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.SldMasterDocument; | |||
/** | |||
* Experimental class to do low level processing of pptx files. | |||
@@ -53,6 +66,7 @@ public class XSLFSlideShow extends POIXMLDocument { | |||
*/ | |||
private List<PackagePart> embedds; | |||
@SuppressWarnings("deprecation") | |||
public XSLFSlideShow(OPCPackage container) throws OpenXML4JException, IOException, XmlException { | |||
super(container); | |||
@@ -64,7 +78,7 @@ public class XSLFSlideShow extends POIXMLDocument { | |||
PresentationDocument.Factory.parse(getCorePart().getInputStream()); | |||
embedds = new LinkedList<PackagePart>(); | |||
for (CTSlideIdListEntry ctSlide : getSlideReferences().getSldIdList()) { | |||
for (CTSlideIdListEntry ctSlide : getSlideReferences().getSldIdArray()) { | |||
PackagePart corePart = getCorePart(); | |||
PackagePart slidePart = corePart.getRelatedPart( | |||
corePart.getRelationship(ctSlide.getId2())); |
@@ -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()); |
@@ -19,12 +19,17 @@ | |||
package org.apache.poi.xslf.model.geom; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.*; | |||
import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTCustomGeometry2D; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuide; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuideList; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomRect; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPath2D; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPath2DList; | |||
/** | |||
* Definition of a custom geometric shape | |||
* | |||
@@ -36,19 +41,20 @@ public class CustomGeometry implements Iterable<Path>{ | |||
List<Path> paths = new ArrayList<Path>(); | |||
Path textBounds; | |||
@SuppressWarnings("deprecation") | |||
public CustomGeometry(CTCustomGeometry2D geom) { | |||
CTGeomGuideList avLst = geom.getAvLst(); | |||
if(avLst != null) for(CTGeomGuide gd : avLst.getGdList()){ | |||
if(avLst != null) for(CTGeomGuide gd : avLst.getGdArray()){ | |||
adjusts.add(new AdjustValue(gd)); | |||
} | |||
CTGeomGuideList gdLst = geom.getGdLst(); | |||
if(gdLst != null) for(CTGeomGuide gd : gdLst.getGdList()){ | |||
if(gdLst != null) for(CTGeomGuide gd : gdLst.getGdArray()){ | |||
guides.add(new Guide(gd)); | |||
} | |||
CTPath2DList pathLst = geom.getPathLst(); | |||
if(pathLst != null) for(CTPath2D spPath : pathLst.getPathList()){ | |||
if(pathLst != null) for(CTPath2D spPath : pathLst.getPathArray()){ | |||
paths.add(new Path(spPath)); | |||
} | |||
@@ -20,8 +20,6 @@ package org.apache.poi.xslf.usermodel; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTable; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow; | |||
import java.util.List; | |||
public class DrawingTable { | |||
private final CTTable table; | |||
@@ -29,12 +27,13 @@ public class DrawingTable { | |||
this.table = table; | |||
} | |||
@SuppressWarnings("deprecation") | |||
public DrawingTableRow[] getRows() { | |||
List<CTTableRow> ctTableRows = table.getTrList(); | |||
DrawingTableRow[] o = new DrawingTableRow[ctTableRows.size()]; | |||
CTTableRow[] ctTableRows = table.getTrArray(); | |||
DrawingTableRow[] o = new DrawingTableRow[ctTableRows.length]; | |||
for (int i=0; i<o.length; i++) { | |||
o[i] = new DrawingTableRow(ctTableRows.get(i)); | |||
o[i] = new DrawingTableRow(ctTableRows[i]); | |||
} | |||
return o; |
@@ -20,8 +20,6 @@ package org.apache.poi.xslf.usermodel; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow; | |||
import java.util.List; | |||
public class DrawingTableRow { | |||
private final CTTableRow row; | |||
@@ -29,12 +27,13 @@ public class DrawingTableRow { | |||
this.row = row; | |||
} | |||
@SuppressWarnings("deprecation") | |||
public DrawingTableCell[] getCells() { | |||
List<CTTableCell> ctTableCells = row.getTcList(); | |||
DrawingTableCell[] o = new DrawingTableCell[ctTableCells.size()]; | |||
CTTableCell[] ctTableCells = row.getTcArray(); | |||
DrawingTableCell[] o = new DrawingTableCell[ctTableCells.length]; | |||
for (int i=0; i<o.length; i++) { | |||
o[i] = new DrawingTableCell(ctTableCells.get(i)); | |||
o[i] = new DrawingTableCell(ctTableCells[i]); | |||
} | |||
return o; |
@@ -20,8 +20,6 @@ package org.apache.poi.xslf.usermodel; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; | |||
import java.util.List; | |||
public class DrawingTextBody { | |||
private final CTTextBody textBody; | |||
@@ -29,12 +27,13 @@ public class DrawingTextBody { | |||
this.textBody = textBody; | |||
} | |||
@SuppressWarnings("deprecation") | |||
public DrawingParagraph[] getParagraphs() { | |||
List<CTTextParagraph> paragraphs = textBody.getPList(); | |||
DrawingParagraph[] o = new DrawingParagraph[paragraphs.size()]; | |||
CTTextParagraph[] paragraphs = textBody.getPArray(); | |||
DrawingParagraph[] o = new DrawingParagraph[paragraphs.length]; | |||
for (int i=0; i<o.length; i++) { | |||
o[i] = new DrawingParagraph(paragraphs.get(i)); | |||
o[i] = new DrawingParagraph(paragraphs[i]); | |||
} | |||
return o; |
@@ -19,6 +19,25 @@ | |||
package org.apache.poi.xslf.usermodel; | |||
import java.awt.AlphaComposite; | |||
import java.awt.BasicStroke; | |||
import java.awt.Color; | |||
import java.awt.GradientPaint; | |||
import java.awt.Graphics2D; | |||
import java.awt.Paint; | |||
import java.awt.Shape; | |||
import java.awt.Stroke; | |||
import java.awt.TexturePaint; | |||
import java.awt.geom.AffineTransform; | |||
import java.awt.geom.Point2D; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.image.BufferedImage; | |||
import java.lang.reflect.Constructor; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Collection; | |||
import java.util.Comparator; | |||
import org.apache.poi.openxml4j.opc.PackagePart; | |||
import org.apache.poi.openxml4j.opc.PackageRelationship; | |||
import org.apache.poi.util.Internal; | |||
@@ -47,25 +66,6 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillPropertie | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.STPathShadeType; | |||
import java.awt.AlphaComposite; | |||
import java.awt.BasicStroke; | |||
import java.awt.Color; | |||
import java.awt.GradientPaint; | |||
import java.awt.Graphics2D; | |||
import java.awt.Paint; | |||
import java.awt.Shape; | |||
import java.awt.Stroke; | |||
import java.awt.TexturePaint; | |||
import java.awt.geom.AffineTransform; | |||
import java.awt.geom.Point2D; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.image.BufferedImage; | |||
import java.lang.reflect.Constructor; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Collection; | |||
import java.util.Comparator; | |||
/** | |||
* Encapsulates logic to translate DrawingML objects to Java2D | |||
*/ | |||
@@ -548,6 +548,7 @@ class RenderableShape { | |||
} | |||
} | |||
@SuppressWarnings("deprecation") | |||
private Collection<Outline> computeOutlines(Graphics2D graphics) { | |||
Collection<Outline> lst = new ArrayList<Outline>(); | |||
@@ -576,7 +577,7 @@ class RenderableShape { | |||
public Guide getAdjustValue(String name) { | |||
CTPresetGeometry2D prst = _shape.getSpPr().getPrstGeom(); | |||
if (prst.isSetAvLst()) { | |||
for (CTGeomGuide g : prst.getAvLst().getGdList()) { | |||
for (CTGeomGuide g : prst.getAvLst().getGdArray()) { | |||
if (g.getName().equals(name)) { | |||
return new Guide(g); | |||
} |
@@ -115,6 +115,7 @@ public class XMLSlideShow extends POIXMLDocument { | |||
} | |||
@Override | |||
@SuppressWarnings("deprecation") | |||
protected void onDocumentRead() throws IOException { | |||
try { | |||
PresentationDocument doc = | |||
@@ -140,8 +141,7 @@ public class XMLSlideShow extends POIXMLDocument { | |||
_slides = new ArrayList<XSLFSlide>(); | |||
if (_presentation.isSetSldIdLst()) { | |||
List<CTSlideIdListEntry> slideIds = _presentation.getSldIdLst().getSldIdList(); | |||
for (CTSlideIdListEntry slId : slideIds) { | |||
for (CTSlideIdListEntry slId : _presentation.getSldIdLst().getSldIdArray()) { | |||
XSLFSlide sh = shIdMap.get(slId.getId2()); | |||
if (sh == null) { | |||
_logger.log(POILogger.WARN, "Slide with r:id " + slId.getId() + " was defined, but didn't exist in package, skipping"); | |||
@@ -201,13 +201,14 @@ public class XMLSlideShow extends POIXMLDocument { | |||
* @param layout | |||
* @return created slide | |||
*/ | |||
@SuppressWarnings("deprecation") | |||
public XSLFSlide createSlide(XSLFSlideLayout layout) { | |||
int slideNumber = 256, cnt = 1; | |||
CTSlideIdList slideList; | |||
if (!_presentation.isSetSldIdLst()) slideList = _presentation.addNewSldIdLst(); | |||
else { | |||
slideList = _presentation.getSldIdLst(); | |||
for(CTSlideIdListEntry slideId : slideList.getSldIdList()){ | |||
for(CTSlideIdListEntry slideId : slideList.getSldIdArray()){ | |||
slideNumber = (int)Math.max(slideId.getId() + 1, slideNumber); | |||
cnt++; | |||
} | |||
@@ -283,16 +284,16 @@ public class XMLSlideShow extends POIXMLDocument { | |||
_slides.add(newIndex, _slides.remove(oldIndex)); | |||
// fix ordering in the low-level xml | |||
List<CTSlideIdListEntry> slideIds = _presentation.getSldIdLst().getSldIdList(); | |||
CTSlideIdListEntry oldEntry = slideIds.get(oldIndex); | |||
slideIds.add(newIndex, oldEntry); | |||
slideIds.remove(oldEntry); | |||
CTSlideIdList sldIdLst = _presentation.getSldIdLst(); | |||
CTSlideIdListEntry oldEntry = sldIdLst.getSldIdArray(oldIndex); | |||
sldIdLst.insertNewSldId(newIndex).set(oldEntry); | |||
sldIdLst.removeSldId(oldIndex); | |||
} | |||
public XSLFSlide removeSlide(int index){ | |||
XSLFSlide slide = _slides.remove(index); | |||
removeRelation(slide); | |||
_presentation.getSldIdLst().getSldIdList().remove(index); | |||
_presentation.getSldIdLst().removeSldId(index); | |||
return slide; | |||
} | |||
@@ -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; | |||
} |
@@ -66,6 +66,6 @@ public class XSLFComments extends POIXMLDocumentPart { | |||
} | |||
public CTComment getCommentAt(int pos) { | |||
return _comments.getCmList().get(pos); | |||
return _comments.getCmArray(pos); | |||
} | |||
} |
@@ -17,6 +17,10 @@ | |||
package org.apache.poi.xslf.usermodel; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.List; | |||
import org.apache.poi.POIXMLException; | |||
import org.apache.poi.util.Beta; | |||
import org.apache.xmlbeans.XmlCursor; | |||
@@ -32,10 +36,6 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFra | |||
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.List; | |||
@Beta | |||
public class XSLFCommonSlideData { | |||
private final CTCommonSlideData data; | |||
@@ -44,6 +44,7 @@ public class XSLFCommonSlideData { | |||
this.data = data; | |||
} | |||
@SuppressWarnings("deprecation") | |||
public List<DrawingTextBody> getDrawingText() { | |||
CTGroupShape gs = data.getSpTree(); | |||
@@ -51,11 +52,11 @@ public class XSLFCommonSlideData { | |||
processShape(gs, out); | |||
for (CTGroupShape shape : gs.getGrpSpList()) { | |||
for (CTGroupShape shape : gs.getGrpSpArray()) { | |||
processShape(shape, out); | |||
} | |||
for (CTGraphicalObjectFrame frame: gs.getGraphicFrameList()) { | |||
for (CTGraphicalObjectFrame frame: gs.getGraphicFrameArray()) { | |||
CTGraphicalObjectData data = frame.getGraphic().getGraphicData(); | |||
XmlCursor c = data.newCursor(); | |||
c.selectPath("declare namespace pic='"+CTTable.type.getName().getNamespaceURI()+"' .//pic:tbl"); | |||
@@ -97,9 +98,9 @@ public class XSLFCommonSlideData { | |||
return paragraphs; | |||
} | |||
@SuppressWarnings("deprecation") | |||
private void processShape(CTGroupShape gs, List<DrawingTextBody> out) { | |||
List<CTShape> shapes = gs.getSpList(); | |||
for (CTShape shape : shapes) { | |||
for (CTShape shape : gs.getSpArray()) { | |||
CTTextBody ctTextBody = shape.getTxBody(); | |||
if (ctTextBody==null) { | |||
continue; |
@@ -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("*")){ |
@@ -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){ |
@@ -51,6 +51,7 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow | |||
private CTTable _table; | |||
private List<XSLFTableRow> _rows; | |||
@SuppressWarnings("deprecation") | |||
/*package*/ XSLFTable(CTGraphicalObjectFrame shape, XSLFSheet sheet){ | |||
super(shape, sheet); | |||
@@ -71,8 +72,9 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow | |||
} | |||
_table = (CTTable) rs[0]; | |||
_rows = new ArrayList<XSLFTableRow>(_table.sizeOfTrArray()); | |||
for(CTTableRow row : _table.getTrList()) _rows.add(new XSLFTableRow(row, this)); | |||
CTTableRow[] trArray = _table.getTrArray(); | |||
_rows = new ArrayList<XSLFTableRow>(trArray.length); | |||
for(CTTableRow row : trArray) _rows.add(new XSLFTableRow(row, this)); | |||
} | |||
@Internal |
@@ -19,15 +19,15 @@ | |||
package org.apache.poi.xslf.usermodel; | |||
import org.apache.poi.util.Units; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import org.apache.poi.util.Units; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow; | |||
/** | |||
* Represents a table in a .pptx presentation | |||
* | |||
@@ -38,11 +38,13 @@ public class XSLFTableRow implements Iterable<XSLFTableCell> { | |||
private List<XSLFTableCell> _cells; | |||
private XSLFTable _table; | |||
@SuppressWarnings("deprecation") | |||
/*package*/ XSLFTableRow(CTTableRow row, XSLFTable table){ | |||
_row = row; | |||
_table = table; | |||
_cells = new ArrayList<XSLFTableCell>(_row.sizeOfTcArray()); | |||
for(CTTableCell cell : _row.getTcList()) { | |||
CTTableCell[] tcArray = _row.getTcArray(); | |||
_cells = new ArrayList<XSLFTableCell>(tcArray.length); | |||
for(CTTableCell cell : tcArray) { | |||
_cells.add(new XSLFTableCell(cell, table.getSheet())); | |||
} | |||
} |
@@ -16,6 +16,12 @@ | |||
==================================================================== */ | |||
package org.apache.poi.xslf.usermodel; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import org.apache.poi.POIXMLDocumentPart; | |||
import org.apache.poi.openxml4j.opc.PackagePart; | |||
import org.apache.poi.openxml4j.opc.PackageRelationship; | |||
@@ -24,12 +30,6 @@ import org.apache.xmlbeans.XmlException; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableStyle; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableStyleList; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
@Beta | |||
public class XSLFTableStyles extends POIXMLDocumentPart implements Iterable<XSLFTableStyle>{ | |||
private CTTableStyleList _tblStyleLst; | |||
@@ -39,12 +39,14 @@ public class XSLFTableStyles extends POIXMLDocumentPart implements Iterable<XSLF | |||
super(); | |||
} | |||
@SuppressWarnings("deprecation") | |||
public XSLFTableStyles(PackagePart part, PackageRelationship rel) throws IOException, XmlException { | |||
super(part, rel); | |||
_tblStyleLst = CTTableStyleList.Factory.parse(getPackagePart().getInputStream()); | |||
_styles = new ArrayList<XSLFTableStyle>(_tblStyleLst.sizeOfTblStyleArray()); | |||
for(CTTableStyle c : _tblStyleLst.getTblStyleList()){ | |||
CTTableStyle[] tblStyleArray = _tblStyleLst.getTblStyleArray(); | |||
_styles = new ArrayList<XSLFTableStyle>(tblStyleArray.length); | |||
for(CTTableStyle c : tblStyleArray){ | |||
_styles.add(new XSLFTableStyle(c)); | |||
} | |||
} |
@@ -19,6 +19,14 @@ | |||
package org.apache.poi.xslf.usermodel; | |||
import java.awt.Graphics2D; | |||
import java.awt.geom.AffineTransform; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.image.BufferedImage; | |||
import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import org.apache.poi.POIXMLException; | |||
import org.apache.poi.util.Beta; | |||
import org.apache.poi.util.Units; | |||
@@ -36,14 +44,6 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; | |||
import java.awt.Graphics2D; | |||
import java.awt.geom.AffineTransform; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.image.BufferedImage; | |||
import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
/** | |||
* Represents a shape that can hold text. | |||
* | |||
@@ -58,13 +58,14 @@ public abstract class XSLFTextShape extends XSLFSimpleShape implements Iterable< | |||
*/ | |||
private boolean _isTextBroken; | |||
@SuppressWarnings("deprecation") | |||
/*package*/ XSLFTextShape(XmlObject shape, XSLFSheet sheet) { | |||
super(shape, sheet); | |||
_paragraphs = new ArrayList<XSLFTextParagraph>(); | |||
CTTextBody txBody = getTextBody(false); | |||
if (txBody != null) { | |||
for (CTTextParagraph p : txBody.getPList()) { | |||
for (CTTextParagraph p : txBody.getPArray()) { | |||
_paragraphs.add(new XSLFTextParagraph(p, this)); | |||
} | |||
} |
@@ -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) { |
@@ -18,7 +18,6 @@ package org.apache.poi.xssf.eventusermodel; | |||
import java.util.Comparator; | |||
import java.util.LinkedList; | |||
import java.util.List; | |||
import java.util.Queue; | |||
import org.apache.poi.ss.usermodel.BuiltinFormats; | |||
@@ -159,11 +158,11 @@ public class XSSFSheetXMLHandler extends DefaultHandler { | |||
this(styles, strings, sheetContentsHandler, new DataFormatter(), formulasNotResults); | |||
} | |||
@SuppressWarnings("deprecation") | |||
private void init() { | |||
if (commentsTable != null) { | |||
commentCellRefs = new LinkedList<CellReference>(); | |||
List<CTComment> commentList = commentsTable.getCTComments().getCommentList().getCommentList(); | |||
for (CTComment comment : commentList) { | |||
for (CTComment comment : commentsTable.getCTComments().getCommentList().getCommentArray()) { | |||
commentCellRefs.add(new CellReference(comment.getRef())); | |||
} | |||
} | |||
@@ -187,6 +186,7 @@ public class XSSFSheetXMLHandler extends DefaultHandler { | |||
} | |||
@Override | |||
@SuppressWarnings("unused") | |||
public void startElement(String uri, String localName, String name, | |||
Attributes attributes) throws SAXException { | |||
@@ -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); |
@@ -28,8 +28,6 @@ import java.util.List; | |||
import java.util.Map; | |||
import java.util.Vector; | |||
import javax.xml.parsers.DocumentBuilder; | |||
import javax.xml.parsers.DocumentBuilderFactory; | |||
import javax.xml.parsers.ParserConfigurationException; | |||
import javax.xml.transform.OutputKeys; | |||
import javax.xml.transform.Source; | |||
@@ -45,7 +43,7 @@ import javax.xml.validation.Validator; | |||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; | |||
import org.apache.poi.ss.usermodel.Cell; | |||
import org.apache.poi.ss.usermodel.DateUtil; | |||
import org.apache.poi.util.XMLHelper; | |||
import org.apache.poi.util.DocumentHelper; | |||
import org.apache.poi.xssf.usermodel.XSSFCell; | |||
import org.apache.poi.xssf.usermodel.XSSFMap; | |||
import org.apache.poi.xssf.usermodel.XSSFRow; | |||
@@ -106,15 +104,6 @@ public class XSSFExportToXml implements Comparator<String>{ | |||
exportToXML(os, "UTF-8", validate); | |||
} | |||
private Document getEmptyDocument() throws ParserConfigurationException{ | |||
DocumentBuilderFactory dbfac = XMLHelper.getDocumentBuilderFactory(); | |||
DocumentBuilder docBuilder = dbfac.newDocumentBuilder(); | |||
Document doc = docBuilder.newDocument(); | |||
return doc; | |||
} | |||
/** | |||
* Exports the data in an XML stream | |||
* | |||
@@ -132,7 +121,7 @@ public class XSSFExportToXml implements Comparator<String>{ | |||
String rootElement = map.getCtMap().getRootElement(); | |||
Document doc = getEmptyDocument(); | |||
Document doc = DocumentHelper.createDocument(); | |||
Element root = null; | |||
@@ -459,8 +448,8 @@ public class XSSFExportToXml implements Comparator<String>{ | |||
Node node = list.item(i); | |||
if (node instanceof Element) { | |||
if (node.getLocalName().equals("element")) { | |||
Node nameAttribute = node.getAttributes().getNamedItem("name"); | |||
if (nameAttribute.getNodeValue().equals(removeNamespace(elementName))) { | |||
Node element = getNameOrRefElement(node); | |||
if (element.getNodeValue().equals(removeNamespace(elementName))) { | |||
indexOf = i; | |||
break; | |||
} | |||
@@ -471,6 +460,15 @@ public class XSSFExportToXml implements Comparator<String>{ | |||
return indexOf; | |||
} | |||
private Node getNameOrRefElement(Node node) { | |||
Node returnNode = node.getAttributes().getNamedItem("name"); | |||
if(returnNode != null) { | |||
return returnNode; | |||
} | |||
return node.getAttributes().getNamedItem("ref"); | |||
} | |||
private Node getComplexTypeForElement(String elementName,Node xmlSchema,Node localComplexTypeRootNode) { | |||
String elementNameWithoutNamespace = removeNamespace(elementName); | |||
@@ -494,7 +492,7 @@ public class XSSFExportToXml implements Comparator<String>{ | |||
Node node = list.item(i); | |||
if ( node instanceof Element) { | |||
if (node.getLocalName().equals("element")) { | |||
Node nameAttribute = node.getAttributes().getNamedItem("name"); | |||
Node nameAttribute = getNameOrRefElement(node); | |||
if (nameAttribute.getNodeValue().equals(elementNameWithoutNamespace)) { | |||
Node complexTypeAttribute = node.getAttributes().getNamedItem("type"); | |||
if (complexTypeAttribute!=null) { | |||
@@ -515,7 +513,7 @@ public class XSSFExportToXml implements Comparator<String>{ | |||
Node node = complexTypeList.item(i); | |||
if ( node instanceof Element) { | |||
if (node.getLocalName().equals("complexType")) { | |||
Node nameAttribute = node.getAttributes().getNamedItem("name"); | |||
Node nameAttribute = getNameOrRefElement(node); | |||
if (nameAttribute.getNodeValue().equals(complexTypeName)) { | |||
NodeList complexTypeChildList =node.getChildNodes(); |
@@ -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()))); | |||
@@ -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; |
@@ -24,7 +24,6 @@ import java.util.Collection; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import org.apache.poi.POIXMLDocumentPart; | |||
import org.apache.poi.openxml4j.opc.PackagePart; | |||
import org.apache.poi.openxml4j.opc.PackageRelationship; | |||
@@ -66,13 +65,14 @@ public class MapInfo extends POIXMLDocumentPart { | |||
readFrom(part.getInputStream()); | |||
} | |||
@SuppressWarnings("deprecation") | |||
public void readFrom(InputStream is) throws IOException { | |||
try { | |||
MapInfoDocument doc = MapInfoDocument.Factory.parse(is); | |||
mapInfo = doc.getMapInfo(); | |||
maps= new HashMap<Integer, XSSFMap>(); | |||
for(CTMap map :mapInfo.getMapList()){ | |||
for(CTMap map :mapInfo.getMapArray()){ | |||
maps.put((int)map.getID(), new XSSFMap(map,this)); | |||
} | |||
@@ -104,10 +104,11 @@ public class MapInfo extends POIXMLDocumentPart { | |||
* @param schemaId the schema ID | |||
* @return CTSchema by it's ID | |||
*/ | |||
@SuppressWarnings("deprecation") | |||
public CTSchema getCTSchemaById(String schemaId){ | |||
CTSchema xmlSchema = null; | |||
for(CTSchema schema: mapInfo.getSchemaList()){ | |||
for(CTSchema schema: mapInfo.getSchemaArray()){ | |||
if(schema.getID().equals(schemaId)){ | |||
xmlSchema = schema; | |||
break; |
@@ -94,10 +94,11 @@ public class SingleXmlCells extends POIXMLDocumentPart { | |||
* | |||
* @return all the SimpleXmlCell contained in this SingleXmlCells element | |||
*/ | |||
@SuppressWarnings("deprecation") | |||
public List<XSSFSingleXmlCell> getAllSimpleXmlCell(){ | |||
List<XSSFSingleXmlCell> list = new Vector<XSSFSingleXmlCell>(); | |||
for(CTSingleXmlCell singleXmlCell: singleXMLCells.getSingleXmlCellList()){ | |||
for(CTSingleXmlCell singleXmlCell: singleXMLCells.getSingleXmlCellArray()){ | |||
list.add(new XSSFSingleXmlCell(singleXmlCell,this)); | |||
} | |||
return list; |
@@ -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 | |||
} | |||
} |
@@ -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)); | |||
} | |||
} |
@@ -25,16 +25,16 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; | |||
* Represents a color in SpreadsheetML | |||
*/ | |||
public class XSSFColor implements Color { | |||
private CTColor ctColor; | |||
private CTColor ctColor; | |||
/** | |||
* Create an instance of XSSFColor from the supplied XML bean | |||
*/ | |||
public XSSFColor(CTColor color) { | |||
this.ctColor = color; | |||
} | |||
this.ctColor = color; | |||
} | |||
/** | |||
* Create an new instance of XSSFColor | |||
*/ | |||
@@ -56,50 +56,29 @@ public class XSSFColor implements Color { | |||
* A boolean value indicating the ctColor is automatic and system ctColor dependent. | |||
*/ | |||
public boolean isAuto() { | |||
return ctColor.getAuto(); | |||
} | |||
return ctColor.getAuto(); | |||
} | |||
/** | |||
* A boolean value indicating the ctColor is automatic and system ctColor dependent. | |||
*/ | |||
public void setAuto(boolean auto) { | |||
ctColor.setAuto(auto); | |||
} | |||
public void setAuto(boolean auto) { | |||
ctColor.setAuto(auto); | |||
} | |||
/** | |||
* Indexed ctColor value. Only used for backwards compatibility. References a ctColor in indexedColors. | |||
*/ | |||
public short getIndexed() { | |||
return (short)ctColor.getIndexed(); | |||
} | |||
return (short)ctColor.getIndexed(); | |||
} | |||
/** | |||
* Indexed ctColor value. Only used for backwards compatibility. References a ctColor in indexedColors. | |||
*/ | |||
public void setIndexed(int indexed) { | |||
ctColor.setIndexed(indexed); | |||
} | |||
/** | |||
* For RGB colours, but not ARGB (we think...) | |||
* Excel gets black and white the wrong way around, so switch them | |||
*/ | |||
private byte[] correctRGB(byte[] rgb) { | |||
if(rgb.length == 4) { | |||
// Excel doesn't appear to get these wrong | |||
// Nothing to change | |||
return rgb; | |||
} else { | |||
// Excel gets black and white the wrong way around, so switch them | |||
if (rgb[0] == 0 && rgb[1] == 0 && rgb[2] == 0) { | |||
rgb = new byte[] {-1, -1, -1}; | |||
} | |||
else if (rgb[0] == -1 && rgb[1] == -1 && rgb[2] == -1) { | |||
rgb = new byte[] {0, 0, 0}; | |||
} | |||
return rgb; | |||
} | |||
} | |||
public void setIndexed(int indexed) { | |||
ctColor.setIndexed(indexed); | |||
} | |||
/** | |||
* Standard Red Green Blue ctColor value (RGB). | |||
@@ -108,7 +87,7 @@ public class XSSFColor implements Color { | |||
public byte[] getRgb() { | |||
byte[] rgb = getRGBOrARGB(); | |||
if(rgb == null) return null; | |||
if(rgb.length == 4) { | |||
// Need to trim off the alpha | |||
byte[] tmp = new byte[3]; | |||
@@ -125,7 +104,7 @@ public class XSSFColor implements Color { | |||
public byte[] getARgb() { | |||
byte[] rgb = getRGBOrARGB(); | |||
if(rgb == null) return null; | |||
if(rgb.length == 3) { | |||
// Pad with the default Alpha | |||
byte[] tmp = new byte[4]; | |||
@@ -136,7 +115,7 @@ public class XSSFColor implements Color { | |||
return rgb; | |||
} | |||
} | |||
private byte[] getRGBOrARGB() { | |||
byte[] rgb = null; | |||
@@ -150,7 +129,7 @@ public class XSSFColor implements Color { | |||
return rgb; | |||
} | |||
} | |||
if (!ctColor.isSetRgb()) { | |||
// No colour is available, sorry | |||
return null; | |||
@@ -158,9 +137,7 @@ public class XSSFColor implements Color { | |||
// Grab the colour | |||
rgb = ctColor.getRgb(); | |||
// Correct it as needed, and return | |||
return correctRGB(rgb); | |||
return rgb; | |||
} | |||
/** | |||
@@ -181,64 +158,63 @@ public class XSSFColor implements Color { | |||
} | |||
return rgb; | |||
} | |||
/** | |||
* Return the ARGB value in hex format, eg FF00FF00. | |||
* Works for both regular and indexed colours. | |||
* Works for both regular and indexed colours. | |||
*/ | |||
public String getARGBHex() { | |||
StringBuffer sb = new StringBuffer(); | |||
byte[] rgb = getARgb(); | |||
if(rgb == null) { | |||
return null; | |||
} | |||
for(byte c : rgb) { | |||
int i = (int)c; | |||
if(i < 0) { | |||
i += 256; | |||
} | |||
String cs = Integer.toHexString(i); | |||
if(cs.length() == 1) { | |||
sb.append('0'); | |||
} | |||
sb.append(cs); | |||
} | |||
return sb.toString().toUpperCase(); | |||
} | |||
private static byte applyTint(int lum, double tint){ | |||
if(tint > 0){ | |||
return (byte)(lum * (1.0-tint) + (255 - 255 * (1.0-tint))); | |||
} else if (tint < 0){ | |||
return (byte)(lum*(1+tint)); | |||
} else { | |||
return (byte)lum; | |||
} | |||
} | |||
public String getARGBHex() { | |||
StringBuffer sb = new StringBuffer(); | |||
byte[] rgb = getARgb(); | |||
if(rgb == null) { | |||
return null; | |||
} | |||
for(byte c : rgb) { | |||
int i = (int)c; | |||
if(i < 0) { | |||
i += 256; | |||
} | |||
String cs = Integer.toHexString(i); | |||
if(cs.length() == 1) { | |||
sb.append('0'); | |||
} | |||
sb.append(cs); | |||
} | |||
return sb.toString().toUpperCase(); | |||
} | |||
private static byte applyTint(int lum, double tint){ | |||
if(tint > 0){ | |||
return (byte)(lum * (1.0-tint) + (255 - 255 * (1.0-tint))); | |||
} else if (tint < 0){ | |||
return (byte)(lum*(1+tint)); | |||
} else { | |||
return (byte)lum; | |||
} | |||
} | |||
/** | |||
* Standard Alpha Red Green Blue ctColor value (ARGB). | |||
*/ | |||
public void setRgb(byte[] rgb) { | |||
// Correct it and save | |||
ctColor.setRgb(correctRGB(rgb)); | |||
} | |||
public void setRgb(byte[] rgb) { | |||
ctColor.setRgb(rgb); | |||
} | |||
/** | |||
* Index into the <clrScheme> collection, referencing a particular <sysClr> or | |||
* <srgbClr> value expressed in the Theme part. | |||
*/ | |||
public int getTheme() { | |||
return (int)ctColor.getTheme(); | |||
} | |||
} | |||
/** | |||
* Index into the <clrScheme> collection, referencing a particular <sysClr> or | |||
* <srgbClr> value expressed in the Theme part. | |||
*/ | |||
public void setTheme(int theme) { | |||
ctColor.setTheme(theme); | |||
} | |||
public void setTheme(int theme) { | |||
ctColor.setTheme(theme); | |||
} | |||
/** | |||
* Specifies the tint value applied to the ctColor. | |||
@@ -282,9 +258,9 @@ public class XSSFColor implements Color { | |||
* @return the tint value | |||
*/ | |||
public double getTint() { | |||
return ctColor.getTint(); | |||
} | |||
return ctColor.getTint(); | |||
} | |||
/** | |||
* Specifies the tint value applied to the ctColor. | |||
* | |||
@@ -326,9 +302,9 @@ public class XSSFColor implements Color { | |||
* | |||
* @param tint the tint value | |||
*/ | |||
public void setTint(double tint) { | |||
ctColor.setTint(tint); | |||
} | |||
public void setTint(double tint) { | |||
ctColor.setTint(tint); | |||
} | |||
/** | |||
* Returns the underlying XML bean | |||
@@ -339,7 +315,7 @@ public class XSSFColor implements Color { | |||
public CTColor getCTColor(){ | |||
return ctColor; | |||
} | |||
public int hashCode(){ | |||
return ctColor.toString().hashCode(); | |||
} |
@@ -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); |
@@ -240,7 +240,6 @@ public class XSSFPivotTable extends POIXMLDocumentPart { | |||
} | |||
CTPivotFields pivotFields = pivotTableDefinition.getPivotFields(); | |||
List<CTPivotField> pivotFieldList = pivotTableDefinition.getPivotFields().getPivotFieldList(); | |||
CTPivotField pivotField = CTPivotField.Factory.newInstance(); | |||
CTItems items = pivotField.addNewItems(); | |||
@@ -249,10 +248,8 @@ public class XSSFPivotTable extends POIXMLDocumentPart { | |||
for(int i = 0; i <= lastRowIndex; i++) { | |||
items.addNewItem().setT(STItemType.DEFAULT); | |||
} | |||
items.setCount(items.getItemList().size()); | |||
pivotFieldList.set(columnIndex, pivotField); | |||
pivotFields.setPivotFieldArray(pivotFieldList.toArray(new CTPivotField[pivotFieldList.size()])); | |||
items.setCount(items.sizeOfItemArray()); | |||
pivotFields.setPivotFieldArray(columnIndex, pivotField); | |||
CTRowFields rowFields; | |||
if(pivotTableDefinition.getRowFields() != null) { | |||
@@ -262,7 +259,7 @@ public class XSSFPivotTable extends POIXMLDocumentPart { | |||
} | |||
rowFields.addNewField().setX(columnIndex); | |||
rowFields.setCount(rowFields.getFieldList().size()); | |||
rowFields.setCount(rowFields.sizeOfFieldArray()); | |||
} | |||
@Beta | |||
@@ -307,7 +304,7 @@ public class XSSFPivotTable extends POIXMLDocumentPart { | |||
colFields = pivotTableDefinition.addNewColFields(); | |||
} | |||
colFields.addNewField().setX(-2); | |||
colFields.setCount(colFields.getFieldList().size()); | |||
colFields.setCount(colFields.sizeOfFieldArray()); | |||
} | |||
} | |||
@@ -338,7 +335,7 @@ public class XSSFPivotTable extends POIXMLDocumentPart { | |||
cell.setCellType(Cell.CELL_TYPE_STRING); | |||
dataField.setName(function.getName()); | |||
dataField.setFld(columnIndex); | |||
dataFields.setCount(dataFields.getDataFieldList().size()); | |||
dataFields.setCount(dataFields.sizeOfDataFieldArray()); | |||
} | |||
/** | |||
@@ -354,13 +351,11 @@ public class XSSFPivotTable extends POIXMLDocumentPart { | |||
throw new IndexOutOfBoundsException(); | |||
} | |||
CTPivotFields pivotFields = pivotTableDefinition.getPivotFields(); | |||
List<CTPivotField> pivotFieldList = pivotFields.getPivotFieldList(); | |||
CTPivotField pivotField = CTPivotField.Factory.newInstance(); | |||
pivotField.setDataField(isDataField); | |||
pivotField.setShowAll(false); | |||
pivotFieldList.set(columnIndex, pivotField); | |||
pivotFields.setPivotFieldArray(pivotFieldList.toArray(new CTPivotField[pivotFieldList.size()])); | |||
pivotFields.setPivotFieldArray(columnIndex, pivotField); | |||
} | |||
/** | |||
@@ -378,7 +373,6 @@ public class XSSFPivotTable extends POIXMLDocumentPart { | |||
} | |||
CTPivotFields pivotFields = pivotTableDefinition.getPivotFields(); | |||
List<CTPivotField> pivotFieldList = pivotTableDefinition.getPivotFields().getPivotFieldList(); | |||
CTPivotField pivotField = CTPivotField.Factory.newInstance(); | |||
CTItems items = pivotField.addNewItems(); | |||
@@ -387,8 +381,8 @@ public class XSSFPivotTable extends POIXMLDocumentPart { | |||
for(int i = 0; i <= lastRowIndex; i++) { | |||
items.addNewItem().setT(STItemType.DEFAULT); | |||
} | |||
items.setCount(items.getItemList().size()); | |||
pivotFieldList.set(columnIndex, pivotField); | |||
items.setCount(items.sizeOfItemArray()); | |||
pivotFields.setPivotFieldArray(columnIndex, pivotField); | |||
CTPageFields pageFields; | |||
if (pivotTableDefinition.getPageFields()!= null) { | |||
@@ -402,7 +396,7 @@ public class XSSFPivotTable extends POIXMLDocumentPart { | |||
pageField.setHier(-1); | |||
pageField.setFld(columnIndex); | |||
pageFields.setCount(pageFields.getPageFieldList().size()); | |||
pageFields.setCount(pageFields.sizeOfPageFieldArray()); | |||
pivotTableDefinition.getLocation().setColPageCount(pageFields.getCount()); | |||
} | |||
@@ -459,6 +453,6 @@ public class XSSFPivotTable extends POIXMLDocumentPart { | |||
pivotField.setDataField(false); | |||
pivotField.setShowAll(false); | |||
} | |||
pivotFields.setCount(pivotFields.getPivotFieldList().size()); | |||
pivotFields.setCount(pivotFields.sizeOfPivotFieldArray()); | |||
} | |||
} |
@@ -439,16 +439,18 @@ public class XSSFRow implements Row, Comparable<XSSFRow> { | |||
* | |||
* @see org.apache.poi.xssf.usermodel.XSSFSheet#write(java.io.OutputStream) () | |||
*/ | |||
@SuppressWarnings("deprecation") | |||
protected void onDocumentWrite(){ | |||
// check if cells in the CTRow are ordered | |||
boolean isOrdered = true; | |||
if(_row.sizeOfCArray() != _cells.size()) { | |||
CTCell[] cArray = _row.getCArray(); | |||
if (cArray.length != _cells.size()) { | |||
isOrdered = false; | |||
} else { | |||
int i = 0; | |||
for (XSSFCell cell : _cells.values()) { | |||
CTCell c1 = cell.getCTCell(); | |||
CTCell c2 = _row.getCArray(i++); | |||
CTCell c2 = cArray[i++]; | |||
String r1 = c1.getR(); | |||
String r2 = c2.getR(); | |||
@@ -460,17 +462,17 @@ public class XSSFRow implements Row, Comparable<XSSFRow> { | |||
} | |||
if(!isOrdered){ | |||
CTCell[] cArray = new CTCell[_cells.size()]; | |||
cArray = new CTCell[_cells.size()]; | |||
int i = 0; | |||
for (Map.Entry<Integer, XSSFCell> entry : _cells.entrySet()) { | |||
cArray[i] = (CTCell) entry.getValue().getCTCell().copy(); | |||
for (XSSFCell xssfCell : _cells.values()) { | |||
cArray[i] = (CTCell) xssfCell.getCTCell().copy(); | |||
// we have to copy and re-create the XSSFCell here because the | |||
// elements as otherwise setCArray below invalidates all the columns! | |||
// see Bug 56170, XMLBeans seems to always release previous objects | |||
// in the CArray, so we need to provide completely new ones here! | |||
//_cells.put(entry.getKey(), new XSSFCell(this, cArray[i])); | |||
entry.getValue().setCTCell(cArray[i]); | |||
xssfCell.setCTCell(cArray[i]); | |||
i++; | |||
} | |||
@@ -19,21 +19,21 @@ | |||
package org.apache.poi.xssf.usermodel; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import org.apache.poi.hssf.record.cf.CellRangeUtil; | |||
import org.apache.poi.ss.SpreadsheetVersion; | |||
import org.apache.poi.ss.usermodel.ComparisonOperator; | |||
import org.apache.poi.ss.usermodel.ConditionalFormatting; | |||
import org.apache.poi.ss.usermodel.ConditionalFormattingRule; | |||
import org.apache.poi.ss.usermodel.SheetConditionalFormatting; | |||
import org.apache.poi.ss.usermodel.ComparisonOperator; | |||
import org.apache.poi.ss.util.CellRangeAddress; | |||
import org.apache.poi.ss.SpreadsheetVersion; | |||
import org.apache.poi.hssf.record.cf.CellRangeUtil; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfRule; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCfType; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTConditionalFormatting; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STConditionalFormattingOperator; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; | |||
import java.util.List; | |||
import java.util.ArrayList; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCfType; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STConditionalFormattingOperator; | |||
/** | |||
* @author Yegor Kozlov | |||
@@ -115,6 +115,7 @@ public class XSSFSheetConditionalFormatting implements SheetConditionalFormattin | |||
return rule; | |||
} | |||
@SuppressWarnings("deprecation") | |||
public int addConditionalFormatting(CellRangeAddress[] regions, ConditionalFormattingRule[] cfRules) { | |||
if (regions == null) { | |||
throw new IllegalArgumentException("regions must not be null"); | |||
@@ -130,21 +131,15 @@ public class XSSFSheetConditionalFormatting implements SheetConditionalFormattin | |||
if (cfRules.length > 3) { | |||
throw new IllegalArgumentException("Number of rules must not exceed 3"); | |||
} | |||
XSSFConditionalFormattingRule[] hfRules; | |||
if(cfRules instanceof XSSFConditionalFormattingRule[]) hfRules = (XSSFConditionalFormattingRule[])cfRules; | |||
else { | |||
hfRules = new XSSFConditionalFormattingRule[cfRules.length]; | |||
System.arraycopy(cfRules, 0, hfRules, 0, hfRules.length); | |||
} | |||
CellRangeAddress[] mergeCellRanges = CellRangeUtil.mergeCellRanges(regions); | |||
CTConditionalFormatting cf = _sheet.getCTWorksheet().addNewConditionalFormatting(); | |||
List<String> refs = new ArrayList<String>(); | |||
for(CellRangeAddress a : mergeCellRanges) refs.add(a.formatAsString()); | |||
cf.setSqref(refs); | |||
int priority = 1; | |||
for(CTConditionalFormatting c : _sheet.getCTWorksheet().getConditionalFormattingList()){ | |||
for(CTConditionalFormatting c : _sheet.getCTWorksheet().getConditionalFormattingArray()){ | |||
priority += c.sizeOfCfRuleArray(); | |||
} | |||
@@ -220,7 +215,7 @@ public class XSSFSheetConditionalFormatting implements SheetConditionalFormattin | |||
*/ | |||
public void removeConditionalFormatting(int index) { | |||
checkIndex(index); | |||
_sheet.getCTWorksheet().getConditionalFormattingList().remove(index); | |||
_sheet.getCTWorksheet().removeConditionalFormatting(index); | |||
} | |||
private void checkIndex(int index) { |
@@ -128,13 +128,14 @@ public class XSSFTable extends POIXMLDocumentPart { | |||
* | |||
* @return the xpath of the table's root element | |||
*/ | |||
@SuppressWarnings("deprecation") | |||
public String getCommonXpath() { | |||
if(commonXPath == null){ | |||
String[] commonTokens ={}; | |||
for(CTTableColumn column :ctTable.getTableColumns().getTableColumnList()){ | |||
for(CTTableColumn column :ctTable.getTableColumns().getTableColumnArray()){ | |||
if(column.getXmlColumnPr()!=null){ | |||
String xpath = column.getXmlColumnPr().getXpath(); | |||
String[] tokens = xpath.split("/"); | |||
@@ -173,11 +174,12 @@ public class XSSFTable extends POIXMLDocumentPart { | |||
} | |||
@SuppressWarnings("deprecation") | |||
public List<XSSFXmlColumnPr> getXmlColumnPrs() { | |||
if(xmlColumnPr==null){ | |||
xmlColumnPr = new ArrayList<XSSFXmlColumnPr>(); | |||
for (CTTableColumn column:ctTable.getTableColumns().getTableColumnList()){ | |||
for (CTTableColumn column:ctTable.getTableColumns().getTableColumnArray()){ | |||
if (column.getXmlColumnPr()!=null){ | |||
XSSFXmlColumnPr columnPr = new XSSFXmlColumnPr(this,column,column.getXmlColumnPr()); | |||
xmlColumnPr.add(columnPr); | |||
@@ -285,6 +287,7 @@ public class XSSFTable extends POIXMLDocumentPart { | |||
* Headers <em>must</em> be in sync, otherwise Excel will display a | |||
* "Found unreadable content" message on startup. | |||
*/ | |||
@SuppressWarnings("deprecation") | |||
public void updateHeaders(){ | |||
XSSFSheet sheet = (XSSFSheet)getParent(); | |||
CellReference ref = getStartCellReference(); | |||
@@ -296,7 +299,7 @@ public class XSSFTable extends POIXMLDocumentPart { | |||
if (row != null && row.getCTRow().validate()) { | |||
int cellnum = firstHeaderColumn; | |||
for (CTTableColumn col : getCTTable().getTableColumns().getTableColumnList()) { | |||
for (CTTableColumn col : getCTTable().getTableColumns().getTableColumnArray()) { | |||
XSSFCell cell = row.getCell(cellnum); | |||
if (cell != null) { | |||
col.setName(cell.getStringCellValue()); |
@@ -17,6 +17,9 @@ | |||
package org.apache.poi.xssf.usermodel; | |||
import static org.apache.poi.xssf.usermodel.helpers.XSSFPaswordHelper.setPassword; | |||
import static org.apache.poi.xssf.usermodel.helpers.XSSFPaswordHelper.validatePassword; | |||
import java.io.ByteArrayInputStream; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.File; | |||
@@ -47,6 +50,7 @@ import org.apache.poi.openxml4j.opc.PackageRelationship; | |||
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes; | |||
import org.apache.poi.openxml4j.opc.PackagingURIHelper; | |||
import org.apache.poi.openxml4j.opc.TargetMode; | |||
import org.apache.poi.poifs.crypt.HashAlgorithm; | |||
import org.apache.poi.ss.formula.SheetNameFormatter; | |||
import org.apache.poi.ss.formula.udf.IndexedUDFFinder; | |||
import org.apache.poi.ss.formula.udf.UDFFinder; | |||
@@ -1366,6 +1370,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X | |||
* @param pos the position that we want to insert the sheet into (0 based) | |||
*/ | |||
@Override | |||
@SuppressWarnings("deprecation") | |||
public void setSheetOrder(String sheetname, int pos) { | |||
int idx = getSheetIndex(sheetname); | |||
sheets.add(pos, sheets.remove(idx)); | |||
@@ -1377,8 +1382,9 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X | |||
newcts.set(cts); | |||
//notify sheets | |||
for(int i=0; i < sheets.size(); i++) { | |||
sheets.get(i).sheet = ct.getSheetArray(i); | |||
CTSheet[] sheetArray = ct.getSheetArray(); | |||
for(int i=0; i < sheetArray.length; i++) { | |||
sheets.get(i).sheet = sheetArray[i]; | |||
} | |||
} | |||
@@ -1410,10 +1416,11 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X | |||
} | |||
} | |||
@SuppressWarnings("deprecation") | |||
private void reprocessNamedRanges() { | |||
namedRanges = new ArrayList<XSSFName>(); | |||
if(workbook.isSetDefinedNames()) { | |||
for(CTDefinedName ctName : workbook.getDefinedNames().getDefinedNameList()) { | |||
for(CTDefinedName ctName : workbook.getDefinedNames().getDefinedNameArray()) { | |||
namedRanges.add(new XSSFName(ctName, this)); | |||
} | |||
} | |||
@@ -1735,60 +1742,108 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X | |||
* Locks the structure of workbook. | |||
*/ | |||
public void lockStructure() { | |||
createProtectionFieldIfNotPresent(); | |||
workbook.getWorkbookProtection().setLockStructure(true); | |||
safeGetWorkbookProtection().setLockStructure(true); | |||
} | |||
/** | |||
* Unlocks the structure of workbook. | |||
*/ | |||
public void unLockStructure() { | |||
createProtectionFieldIfNotPresent(); | |||
workbook.getWorkbookProtection().setLockStructure(false); | |||
safeGetWorkbookProtection().setLockStructure(false); | |||
} | |||
/** | |||
* Locks the windows that comprise the workbook. | |||
*/ | |||
public void lockWindows() { | |||
createProtectionFieldIfNotPresent(); | |||
workbook.getWorkbookProtection().setLockWindows(true); | |||
safeGetWorkbookProtection().setLockWindows(true); | |||
} | |||
/** | |||
* Unlocks the windows that comprise the workbook. | |||
*/ | |||
public void unLockWindows() { | |||
createProtectionFieldIfNotPresent(); | |||
workbook.getWorkbookProtection().setLockWindows(false); | |||
safeGetWorkbookProtection().setLockWindows(false); | |||
} | |||
/** | |||
* Locks the workbook for revisions. | |||
*/ | |||
public void lockRevision() { | |||
createProtectionFieldIfNotPresent(); | |||
workbook.getWorkbookProtection().setLockRevision(true); | |||
safeGetWorkbookProtection().setLockRevision(true); | |||
} | |||
/** | |||
* Unlocks the workbook for revisions. | |||
*/ | |||
public void unLockRevision() { | |||
createProtectionFieldIfNotPresent(); | |||
workbook.getWorkbookProtection().setLockRevision(false); | |||
safeGetWorkbookProtection().setLockRevision(false); | |||
} | |||
private boolean workbookProtectionPresent() { | |||
return workbook.getWorkbookProtection() != null; | |||
/** | |||
* Sets the workbook password. | |||
* | |||
* @param password if null, the password will be removed | |||
* @param hashAlgo if null, the password will be set as XOR password (Excel 2010 and earlier) | |||
* otherwise the given algorithm is used for calculating the hash password (Excel 2013) | |||
*/ | |||
public void setWorkbookPassword(String password, HashAlgorithm hashAlgo) { | |||
if (password == null && !workbookProtectionPresent()) return; | |||
setPassword(safeGetWorkbookProtection(), password, hashAlgo, "workbook"); | |||
} | |||
private void createProtectionFieldIfNotPresent() { | |||
if (workbook.getWorkbookProtection() == null){ | |||
workbook.setWorkbookProtection(CTWorkbookProtection.Factory.newInstance()); | |||
} | |||
/** | |||
* Validate the password against the stored hash, the hashing method will be determined | |||
* by the existing password attributes | |||
* @return true, if the hashes match (... though original password may differ ...) | |||
*/ | |||
public boolean validateWorkbookPassword(String password) { | |||
if (!workbookProtectionPresent()) return (password == null); | |||
return validatePassword(safeGetWorkbookProtection(), password, "workbook"); | |||
} | |||
/** | |||
* Sets the revisions password. | |||
* | |||
* @param password if null, the password will be removed | |||
* @param hashAlgo if null, the password will be set as XOR password (Excel 2010 and earlier) | |||
* otherwise the given algorithm is used for calculating the hash password (Excel 2013) | |||
*/ | |||
public void setRevisionsPassword(String password, HashAlgorithm hashAlgo) { | |||
if (password == null && !workbookProtectionPresent()) return; | |||
setPassword(safeGetWorkbookProtection(), password, hashAlgo, "revisions"); | |||
} | |||
/** | |||
* Validate the password against the stored hash, the hashing method will be determined | |||
* by the existing password attributes | |||
* @return true if the hashes match (... though original password may differ ...) | |||
*/ | |||
public boolean validateRevisionsPassword(String password) { | |||
if (!workbookProtectionPresent()) return (password == null); | |||
return validatePassword(safeGetWorkbookProtection(), password, "revisions"); | |||
} | |||
/** | |||
* Removes the workbook protection settings | |||
*/ | |||
public void unLock() { | |||
if (workbookProtectionPresent()) { | |||
workbook.unsetWorkbookProtection(); | |||
} | |||
} | |||
private boolean workbookProtectionPresent() { | |||
return workbook.isSetWorkbookProtection(); | |||
} | |||
private CTWorkbookProtection safeGetWorkbookProtection() { | |||
if (!workbookProtectionPresent()){ | |||
return workbook.addNewWorkbookProtection(); | |||
} | |||
return workbook.getWorkbookProtection(); | |||
} | |||
/** | |||
* | |||
* Returns the locator of user-defined functions. |
@@ -19,7 +19,6 @@ package org.apache.poi.xssf.usermodel.helpers; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Comparator; | |||
import java.util.HashSet; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
@@ -50,52 +49,39 @@ public class ColumnHelper { | |||
cleanColumns(); | |||
} | |||
@SuppressWarnings("deprecation") | |||
public void cleanColumns() { | |||
this.newCols = CTCols.Factory.newInstance(); | |||
CTCols aggregateCols = CTCols.Factory.newInstance(); | |||
List<CTCols> colsList = worksheet.getColsList(); | |||
assert(colsList != null); | |||
CTCols[] colsArray = worksheet.getColsArray(); | |||
assert(colsArray != null); | |||
for (CTCols cols : colsList) { | |||
for (CTCol col : cols.getColList()) { | |||
for (CTCols cols : colsArray) { | |||
for (CTCol col : cols.getColArray()) { | |||
cloneCol(aggregateCols, col); | |||
} | |||
} | |||
sortColumns(aggregateCols); | |||
CTCol[] colArray = new CTCol[aggregateCols.getColList().size()]; | |||
aggregateCols.getColList().toArray(colArray); | |||
CTCol[] colArray = aggregateCols.getColArray(); | |||
sweepCleanColumns(newCols, colArray, null); | |||
int i = colsList.size(); | |||
int i = colsArray.length; | |||
for (int y = i - 1; y >= 0; y--) { | |||
worksheet.removeCols(y); | |||
} | |||
worksheet.addNewCols(); | |||
worksheet.setColsArray(0, newCols); | |||
} | |||
private static class CTColByMaxComparator implements Comparator<CTCol> { | |||
public int compare(CTCol arg0, CTCol arg1) { | |||
if (arg0.getMax() < arg1.getMax()) { | |||
return -1; | |||
} else { | |||
if (arg0.getMax() > arg1.getMax()) return 1; | |||
else return 0; | |||
} | |||
} | |||
} | |||
/** | |||
* @see <a href="http://en.wikipedia.org/wiki/Sweep_line_algorithm">Sweep line algorithm</a> | |||
*/ | |||
private void sweepCleanColumns(CTCols cols, CTCol[] flattenedColsArray, CTCol overrideColumn) { | |||
List<CTCol> flattenedCols = new ArrayList<CTCol>(Arrays.asList(flattenedColsArray)); | |||
TreeSet<CTCol> currentElements = new TreeSet<CTCol>(new CTColByMaxComparator()); | |||
TreeSet<CTCol> currentElements = new TreeSet<CTCol>(CTColComparator.BY_MAX); | |||
ListIterator<CTCol> flIter = flattenedCols.listIterator(); | |||
CTCol haveOverrideColumn = null; | |||
long lastMaxIndex = 0; | |||
@@ -103,7 +89,8 @@ public class ColumnHelper { | |||
while (flIter.hasNext()) { | |||
CTCol col = flIter.next(); | |||
long currentIndex = col.getMin(); | |||
long nextIndex = (col.getMax() > currentMax) ? col.getMax() : currentMax; | |||
long colMax = col.getMax(); | |||
long nextIndex = (colMax > currentMax) ? colMax : currentMax; | |||
if (flIter.hasNext()) { | |||
nextIndex = flIter.next().getMin(); | |||
flIter.previous(); | |||
@@ -116,10 +103,10 @@ public class ColumnHelper { | |||
} | |||
if (!currentElements.isEmpty() && lastMaxIndex < currentIndex) { | |||
// we need to process previous elements first | |||
insertCol(cols, lastMaxIndex, currentIndex - 1, currentElements.toArray(new CTCol[]{}), true, haveOverrideColumn); | |||
insertCol(cols, lastMaxIndex, currentIndex - 1, currentElements.toArray(new CTCol[currentElements.size()]), true, haveOverrideColumn); | |||
} | |||
currentElements.add(col); | |||
if (col.getMax() > currentMax) currentMax = col.getMax(); | |||
if (colMax > currentMax) currentMax = colMax; | |||
if (col.equals(overrideColumn)) haveOverrideColumn = overrideColumn; | |||
while (currentIndex <= nextIndex && !currentElements.isEmpty()) { | |||
Set<CTCol> currentIndexElements = new HashSet<CTCol>(); | |||
@@ -130,26 +117,21 @@ public class ColumnHelper { | |||
CTCol currentElem = currentElements.first(); | |||
currentElemIndex = currentElem.getMax(); | |||
currentIndexElements.add(currentElem); | |||
for (CTCol cc : currentElements.tailSet(currentElem)) { | |||
if (cc == null || cc.getMax() == currentElemIndex) break; | |||
currentIndexElements.add(cc); | |||
if (col.getMax() > currentMax) currentMax = col.getMax(); | |||
while (true) { | |||
CTCol higherElem = currentElements.higher(currentElem); | |||
if (higherElem == null || higherElem.getMax() != currentElemIndex) | |||
break; | |||
currentElem = higherElem; | |||
currentIndexElements.add(currentElem); | |||
if (colMax > currentMax) currentMax = colMax; | |||
if (col.equals(overrideColumn)) haveOverrideColumn = overrideColumn; | |||
} | |||
// JDK 6 code | |||
// while (currentElements.higher(currentElem) != null && currentElements.higher(currentElem).getMax() == currentElemIndex) { | |||
// currentElem = currentElements.higher(currentElem); | |||
// currentIndexElements.add(currentElem); | |||
// if (col.getMax() > currentMax) currentMax = col.getMax(); | |||
// if (col.equals(overrideColumn)) haveOverrideColumn = overrideColumn; | |||
// } | |||
} | |||
if (currentElemIndex < nextIndex || !flIter.hasNext()) { | |||
insertCol(cols, currentIndex, currentElemIndex, currentElements.toArray(new CTCol[]{}), true, haveOverrideColumn); | |||
insertCol(cols, currentIndex, currentElemIndex, currentElements.toArray(new CTCol[currentElements.size()]), true, haveOverrideColumn); | |||
if (flIter.hasNext()) { | |||
if (nextIndex > currentElemIndex) { | |||
currentElements.removeAll(currentIndexElements); | |||
@@ -170,10 +152,10 @@ public class ColumnHelper { | |||
sortColumns(cols); | |||
} | |||
@SuppressWarnings("deprecation") | |||
public static void sortColumns(CTCols newCols) { | |||
CTCol[] colArray = new CTCol[newCols.getColList().size()]; | |||
newCols.getColList().toArray(colArray); | |||
Arrays.sort(colArray, new CTColComparator()); | |||
CTCol[] colArray = newCols.getColArray(); | |||
Arrays.sort(colArray, CTColComparator.BY_MIN_MAX); | |||
newCols.setColArray(colArray); | |||
} | |||
@@ -198,46 +180,46 @@ public class ColumnHelper { | |||
* as 1 based. | |||
*/ | |||
public CTCol getColumn1Based(long index1, boolean splitColumns) { | |||
CTCols colsArray = worksheet.getColsArray(0); | |||
CTCols cols = worksheet.getColsArray(0); | |||
// Fetching the array is quicker than working on the new style | |||
// list, assuming we need to read many of them (which we often do), | |||
// and assuming we're not making many changes (which we're not) | |||
@SuppressWarnings("deprecation") | |||
CTCol[] cols = colsArray.getColArray(); | |||
for (int i = 0; i < cols.length; i++) { | |||
CTCol colArray = cols[i]; | |||
if (colArray.getMin() <= index1 && colArray.getMax() >= index1) { | |||
CTCol[] colArray = cols.getColArray(); | |||
for (CTCol col : colArray) { | |||
long colMin = col.getMin(); | |||
long colMax = col.getMax(); | |||
if (colMin <= index1 && colMax >= index1) { | |||
if (splitColumns) { | |||
if (colArray.getMin() < index1) { | |||
insertCol(colsArray, colArray.getMin(), (index1 - 1), new CTCol[]{colArray}); | |||
if (colMin < index1) { | |||
insertCol(cols, colMin, (index1 - 1), new CTCol[]{col}); | |||
} | |||
if (colArray.getMax() > index1) { | |||
insertCol(colsArray, (index1 + 1), colArray.getMax(), new CTCol[]{colArray}); | |||
if (colMax > index1) { | |||
insertCol(cols, (index1 + 1), colMax, new CTCol[]{col}); | |||
} | |||
colArray.setMin(index1); | |||
colArray.setMax(index1); | |||
col.setMin(index1); | |||
col.setMax(index1); | |||
} | |||
return colArray; | |||
return col; | |||
} | |||
} | |||
return null; | |||
} | |||
@SuppressWarnings("deprecation") | |||
public CTCols addCleanColIntoCols(CTCols cols, CTCol col) { | |||
CTCols newCols = CTCols.Factory.newInstance(); | |||
for (CTCol c : cols.getColList()) { | |||
for (CTCol c : cols.getColArray()) { | |||
cloneCol(newCols, c); | |||
} | |||
cloneCol(newCols, col); | |||
sortColumns(newCols); | |||
CTCol[] colArray = new CTCol[newCols.getColList().size()]; | |||
newCols.getColList().toArray(colArray); | |||
CTCol[] colArray = newCols.getColArray(); | |||
CTCols returnCols = CTCols.Factory.newInstance(); | |||
sweepCleanColumns(returnCols, colArray, col); | |||
colArray = new CTCol[returnCols.getColList().size()]; | |||
returnCols.getColList().toArray(colArray); | |||
colArray = returnCols.getColArray(); | |||
cols.setColArray(colArray); | |||
return returnCols; | |||
} | |||
@@ -272,9 +254,11 @@ public class ColumnHelper { | |||
public boolean columnExists(CTCols cols, long index) { | |||
return columnExists1Based(cols, index+1); | |||
} | |||
@SuppressWarnings("deprecation") | |||
private boolean columnExists1Based(CTCols cols, long index1) { | |||
for (int i = 0; i < cols.sizeOfColArray(); i++) { | |||
if (cols.getColArray(i).getMin() == index1) { | |||
for (CTCol col : cols.getColArray()) { | |||
if (col.getMin() == index1) { | |||
return true; | |||
} | |||
} | |||
@@ -343,20 +327,24 @@ public class ColumnHelper { | |||
return -1; | |||
} | |||
@SuppressWarnings("deprecation") | |||
private boolean columnExists(CTCols cols, long min, long max) { | |||
for (int i = 0; i < cols.sizeOfColArray(); i++) { | |||
if (cols.getColArray(i).getMin() == min && cols.getColArray(i).getMax() == max) { | |||
for (CTCol col : cols.getColArray()) { | |||
if (col.getMin() == min && col.getMax() == max) { | |||
return true; | |||
} | |||
} | |||
return false; | |||
} | |||
public int getIndexOfColumn(CTCols cols, CTCol col) { | |||
for (int i = 0; i < cols.sizeOfColArray(); i++) { | |||
if (cols.getColArray(i).getMin() == col.getMin() && cols.getColArray(i).getMax() == col.getMax()) { | |||
@SuppressWarnings("deprecation") | |||
public int getIndexOfColumn(CTCols cols, CTCol searchCol) { | |||
int i = 0; | |||
for (CTCol col : cols.getColArray()) { | |||
if (col.getMin() == searchCol.getMin() && col.getMax() == searchCol.getMax()) { | |||
return i; | |||
} | |||
i++; | |||
} | |||
return -1; | |||
} |
@@ -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)); | |||
} | |||
} | |||
} |
@@ -18,7 +18,9 @@ | |||
package org.apache.poi.xssf.usermodel.helpers; | |||
import java.util.ArrayList; | |||
import java.util.HashSet; | |||
import java.util.List; | |||
import java.util.Set; | |||
import org.apache.poi.ss.formula.FormulaParseException; | |||
import org.apache.poi.ss.formula.FormulaParser; | |||
@@ -43,6 +45,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfRule; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTConditionalFormatting; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType; | |||
/** | |||
@@ -66,8 +69,10 @@ public final class XSSFRowShifter { | |||
*/ | |||
public List<CellRangeAddress> shiftMerged(int startRow, int endRow, int n) { | |||
List<CellRangeAddress> shiftedRegions = new ArrayList<CellRangeAddress>(); | |||
Set<Integer> removedIndices = new HashSet<Integer>(); | |||
//move merged regions completely if they fall within the new region boundaries when they are shifted | |||
for (int i = 0; i < sheet.getNumMergedRegions(); i++) { | |||
int size = sheet.getNumMergedRegions(); | |||
for (int i = 0; i < size; i++) { | |||
CellRangeAddress merged = sheet.getMergedRegion(i); | |||
boolean inStart = (merged.getFirstRow() >= startRow || merged.getLastRow() >= startRow); | |||
@@ -84,10 +89,13 @@ public final class XSSFRowShifter { | |||
merged.setLastRow(merged.getLastRow() + n); | |||
//have to remove/add it back | |||
shiftedRegions.add(merged); | |||
sheet.removeMergedRegion(i); | |||
i = i - 1; // we have to back up now since we removed one | |||
removedIndices.add(i); | |||
} | |||
} | |||
if(!removedIndices.isEmpty()) { | |||
sheet.removeMergedRegions(removedIndices); | |||
} | |||
//read so it doesn't get shifted again | |||
for (CellRangeAddress region : shiftedRegions) { | |||
@@ -213,28 +221,29 @@ public final class XSSFRowShifter { | |||
} | |||
} | |||
@SuppressWarnings("deprecation") | |||
public void updateConditionalFormatting(FormulaShifter shifter) { | |||
XSSFWorkbook wb = sheet.getWorkbook(); | |||
int sheetIndex = wb.getSheetIndex(sheet); | |||
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); | |||
List<CTConditionalFormatting> cfList = sheet.getCTWorksheet().getConditionalFormattingList(); | |||
for(int j = 0; j< cfList.size(); j++){ | |||
CTConditionalFormatting cf = cfList.get(j); | |||
CTWorksheet ctWorksheet = sheet.getCTWorksheet(); | |||
CTConditionalFormatting[] conditionalFormattingArray = ctWorksheet.getConditionalFormattingArray(); | |||
// iterate backwards due to possible calls to ctWorksheet.removeConditionalFormatting(j) | |||
for (int j = conditionalFormattingArray.length - 1; j >= 0; j--) { | |||
CTConditionalFormatting cf = conditionalFormattingArray[j]; | |||
ArrayList<CellRangeAddress> cellRanges = new ArrayList<CellRangeAddress>(); | |||
for (Object stRef : cf.getSqref()) { | |||
String[] regions = stRef.toString().split(" "); | |||
for (int i = 0; i < regions.length; i++) { | |||
cellRanges.add(CellRangeAddress.valueOf(regions[i])); | |||
for (String region : regions) { | |||
cellRanges.add(CellRangeAddress.valueOf(region)); | |||
} | |||
} | |||
boolean changed = false; | |||
List<CellRangeAddress> temp = new ArrayList<CellRangeAddress>(); | |||
for (int i = 0; i < cellRanges.size(); i++) { | |||
CellRangeAddress craOld = cellRanges.get(i); | |||
for (CellRangeAddress craOld : cellRanges) { | |||
CellRangeAddress craNew = shiftRange(shifter, craOld, sheetIndex); | |||
if (craNew == null) { | |||
changed = true; | |||
@@ -249,7 +258,7 @@ public final class XSSFRowShifter { | |||
if (changed) { | |||
int nRanges = temp.size(); | |||
if (nRanges == 0) { | |||
cfList.remove(j); | |||
ctWorksheet.removeConditionalFormatting(j); | |||
continue; | |||
} | |||
List<String> refs = new ArrayList<String>(); | |||
@@ -257,14 +266,14 @@ public final class XSSFRowShifter { | |||
cf.setSqref(refs); | |||
} | |||
for(CTCfRule cfRule : cf.getCfRuleList()){ | |||
List<String> formulas = cfRule.getFormulaList(); | |||
for (int i = 0; i < formulas.size(); i++) { | |||
String formula = formulas.get(i); | |||
for(CTCfRule cfRule : cf.getCfRuleArray()){ | |||
String[] formulaArray = cfRule.getFormulaArray(); | |||
for (int i = 0; i < formulaArray.length; i++) { | |||
String formula = formulaArray[i]; | |||
Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex); | |||
if (shifter.adjustFormula(ptgs, sheetIndex)) { | |||
String shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs); | |||
formulas.set(i, shiftedFmla); | |||
cfRule.setFormulaArray(i, shiftedFmla); | |||
} | |||
} | |||
} |
@@ -21,26 +21,26 @@ import java.util.Comparator; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol; | |||
public class CTColComparator implements Comparator<CTCol>{ | |||
public class CTColComparator { | |||
public int compare(CTCol o1, CTCol o2) { | |||
if (o1.getMin() < o2.getMin()) { | |||
return -1; | |||
} | |||
else if (o1.getMin() > o2.getMin()) { | |||
return 1; | |||
private CTColComparator() {} | |||
public static final Comparator<CTCol> BY_MAX = new Comparator<CTCol>() { | |||
@Override | |||
public int compare(CTCol col1, CTCol col2) { | |||
long col1max = col1.getMax(); | |||
long col2max = col2.getMax(); | |||
return col1max < col2max ? -1 : col1max > col2max ? 1 : 0; | |||
} | |||
else { | |||
if (o1.getMax() < o2.getMax()) { | |||
return -1; | |||
} | |||
if (o1.getMax() > o2.getMax()) { | |||
return 1; | |||
} | |||
return 0; | |||
}; | |||
public static final Comparator<CTCol> BY_MIN_MAX = new Comparator<CTCol>() { | |||
@Override | |||
public int compare(CTCol col1, CTCol col2) { | |||
long col11min = col1.getMin(); | |||
long col2min = col2.getMin(); | |||
return col11min < col2min ? -1 : col11min > col2min ? 1 : BY_MAX.compare(col1, col2); | |||
} | |||
} | |||
}; | |||
} |
@@ -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()); |
@@ -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()); | |||
} | |||
} |
@@ -35,17 +35,18 @@ public abstract class AbstractXWPFSDT implements ISDTContents { | |||
private final String tag; | |||
private final IBody part; | |||
@SuppressWarnings("deprecation") | |||
public AbstractXWPFSDT(CTSdtPr pr, IBody part){ | |||
List<CTString> aliases = pr.getAliasList(); | |||
if (aliases != null && aliases.size() > 0){ | |||
title = aliases.get(0).getVal(); | |||
CTString[] aliases = pr.getAliasArray(); | |||
if (aliases != null && aliases.length > 0){ | |||
title = aliases[0].getVal(); | |||
} else { | |||
title = ""; | |||
} | |||
List<CTString> tags = pr.getTagList(); | |||
if (tags != null && tags.size() > 0){ | |||
tag = tags.get(0).getVal(); | |||
CTString[] tags = pr.getTagArray(); | |||
if (tags != null && tags.length > 0){ | |||
tag = tags[0].getVal(); | |||
} else { | |||
tag = ""; | |||
} |
@@ -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()); |
@@ -184,7 +184,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { | |||
} else if (relation.equals(XWPFRelation.COMMENT.getRelation())) { | |||
// TODO Create according XWPFComment class, extending POIXMLDocumentPart | |||
CommentsDocument cmntdoc = CommentsDocument.Factory.parse(p.getPackagePart().getInputStream()); | |||
for (CTComment ctcomment : cmntdoc.getComments().getCommentList()) { | |||
for (CTComment ctcomment : cmntdoc.getComments().getCommentArray()) { | |||
comments.add(new XWPFComment(ctcomment, this)); | |||
} | |||
} else if (relation.equals(XWPFRelation.SETTINGS.getRelation())) { | |||
@@ -232,6 +232,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { | |||
} | |||
} | |||
@SuppressWarnings("deprecation") | |||
private void initFootnotes() throws XmlException, IOException { | |||
for(POIXMLDocumentPart p : getRelations()){ | |||
String relation = p.getPackageRelationship().getRelationshipType(); | |||
@@ -241,7 +242,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { | |||
} else if (relation.equals(XWPFRelation.ENDNOTE.getRelation())){ | |||
EndnotesDocument endnotesDocument = EndnotesDocument.Factory.parse(p.getPackagePart().getInputStream()); | |||
for(CTFtnEdn ctFtnEdn : endnotesDocument.getEndnotes().getEndnoteList()) { | |||
for(CTFtnEdn ctFtnEdn : endnotesDocument.getEndnotes().getEndnoteArray()) { | |||
endnotes.put(ctFtnEdn.getId().intValue(), new XWPFFootnote(this, ctFtnEdn)); | |||
} | |||
} | |||
@@ -364,10 +365,8 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { | |||
} | |||
public XWPFHyperlink getHyperlinkByID(String id) { | |||
Iterator<XWPFHyperlink> iter = hyperlinks.iterator(); | |||
while (iter.hasNext()) { | |||
XWPFHyperlink link = iter.next(); | |||
if(link.getId().equals(id)) | |||
for (XWPFHyperlink link : hyperlinks) { | |||
if (link.getId().equals(id)) | |||
return link; | |||
} | |||
@@ -396,10 +395,8 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { | |||
} | |||
public XWPFComment getCommentByID(String id) { | |||
Iterator<XWPFComment> iter = comments.iterator(); | |||
while (iter.hasNext()) { | |||
XWPFComment comment = iter.next(); | |||
if(comment.getId().equals(id)) | |||
for (XWPFComment comment : comments) { | |||
if (comment.getId().equals(id)) | |||
return comment; | |||
} | |||
@@ -1187,14 +1184,15 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { | |||
* @param table | |||
*/ | |||
@Override | |||
@SuppressWarnings("deprecation") | |||
public void insertTable(int pos, XWPFTable table) { | |||
bodyElements.add(pos, table); | |||
int i; | |||
for (i = 0; i < ctDocument.getBody().getTblList().size(); i++) { | |||
CTTbl tbl = ctDocument.getBody().getTblArray(i); | |||
int i = 0; | |||
for (CTTbl tbl : ctDocument.getBody().getTblArray()) { | |||
if (tbl == table.getCTTbl()) { | |||
break; | |||
} | |||
i++; | |||
} | |||
tables.add(i, table); | |||
} |
@@ -123,14 +123,15 @@ public class XWPFFootnote implements Iterable<XWPFParagraph>,IBody { | |||
* @param table | |||
* @see org.apache.poi.xwpf.usermodel.IBody#insertTable(int pos, XWPFTable table) | |||
*/ | |||
@SuppressWarnings("deprecation") | |||
public void insertTable(int pos, XWPFTable table) { | |||
bodyElements.add(pos, table); | |||
int i; | |||
for (i = 0; i < ctFtnEdn.getTblList().size(); i++) { | |||
CTTbl tbl = ctFtnEdn.getTblArray(i); | |||
int i = 0; | |||
for (CTTbl tbl : ctFtnEdn.getTblArray()) { | |||
if(tbl == table.getCTTbl()){ | |||
break; | |||
} | |||
i++; | |||
} | |||
tables.add(i, table); | |||
@@ -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)); | |||
} | |||
} |
@@ -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); | |||
@@ -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; | |||
} |
@@ -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(); |
@@ -137,7 +137,7 @@ public class XWPFParagraph implements IBodyElement, IRunBody, ISDTContents { | |||
} | |||
if (o instanceof CTHyperlink) { | |||
CTHyperlink link = (CTHyperlink) o; | |||
for (CTR r : link.getRList()) { | |||
for (CTR r : link.getRArray()) { | |||
XWPFHyperlinkRun hr = new XWPFHyperlinkRun(link, r, this); | |||
runs.add(hr); | |||
iruns.add(hr); | |||
@@ -152,14 +152,14 @@ public class XWPFParagraph implements IBodyElement, IRunBody, ISDTContents { | |||
iruns.add(cc); | |||
} | |||
if (o instanceof CTRunTrackChange) { | |||
for (CTR r : ((CTRunTrackChange) o).getRList()) { | |||
for (CTR r : ((CTRunTrackChange) o).getRArray()) { | |||
XWPFRun cr = new XWPFRun(r, this); | |||
runs.add(cr); | |||
iruns.add(cr); | |||
} | |||
} | |||
if (o instanceof CTSimpleField) { | |||
for (CTR r : ((CTSimpleField) o).getRList()) { | |||
for (CTR r : ((CTSimpleField) o).getRArray()) { | |||
XWPFRun cr = new XWPFRun(r, this); | |||
runs.add(cr); | |||
iruns.add(cr); | |||
@@ -1170,7 +1170,7 @@ public class XWPFParagraph implements IBodyElement, IRunBody, ISDTContents { | |||
*/ | |||
protected void addRun(CTR run){ | |||
int pos; | |||
pos = paragraph.getRList().size(); | |||
pos = paragraph.sizeOfRArray(); | |||
paragraph.addNewR(); | |||
paragraph.setRArray(pos, run); | |||
} | |||
@@ -1230,9 +1230,10 @@ public class XWPFParagraph implements IBodyElement, IRunBody, ISDTContents { | |||
startChar = startPos.getChar(); | |||
int beginRunPos = 0, candCharPos = 0; | |||
boolean newList = false; | |||
for (int runPos=startRun; runPos<paragraph.getRList().size(); runPos++) { | |||
CTR[] rArray = paragraph.getRArray(); | |||
for (int runPos=startRun; runPos<rArray.length; runPos++) { | |||
int beginTextPos = 0,beginCharPos = 0, textPos = 0, charPos = 0; | |||
CTR ctRun = paragraph.getRArray(runPos); | |||
CTR ctRun = rArray[runPos]; | |||
XmlCursor c = ctRun.newCursor(); | |||
c.selectPath("./*"); | |||
while(c.toNextSelection()){ | |||
@@ -1298,15 +1299,17 @@ public class XWPFParagraph implements IBodyElement, IRunBody, ISDTContents { | |||
int runEnd = segment.getEndRun(); | |||
int textEnd = segment.getEndText(); | |||
int charEnd = segment.getEndChar(); | |||
StringBuffer out = new StringBuffer(); | |||
StringBuilder out = new StringBuilder(); | |||
CTR[] rArray = paragraph.getRArray(); | |||
for(int i=runBegin; i<=runEnd;i++){ | |||
int startText=0, endText = paragraph.getRArray(i).getTList().size()-1; | |||
CTText[] tArray = rArray[i].getTArray(); | |||
int startText=0, endText = tArray.length-1; | |||
if(i==runBegin) | |||
startText=textBegin; | |||
if(i==runEnd) | |||
endText = textEnd; | |||
for(int j=startText;j<=endText;j++){ | |||
String tmpText = paragraph.getRArray(i).getTArray(j).getStringValue(); | |||
String tmpText = tArray[j].getStringValue(); | |||
int startChar=0, endChar = tmpText.length()-1; | |||
if((j==textBegin)&&(i==runBegin)) | |||
startChar=charBegin; | |||
@@ -1314,7 +1317,6 @@ public class XWPFParagraph implements IBodyElement, IRunBody, ISDTContents { | |||
endChar = charEnd; | |||
} | |||
out.append(tmpText.substring(startChar, endChar+1)); | |||
} | |||
} | |||
return out.toString(); |
@@ -20,6 +20,7 @@ import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.math.BigInteger; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.List; | |||
import javax.xml.namespace.QName; | |||
@@ -95,6 +96,7 @@ public class XWPFRun implements ISDTContents, IRunElement{ | |||
* @param r the CTR bean which holds the run attributes | |||
* @param p the parent paragraph | |||
*/ | |||
@SuppressWarnings("deprecation") | |||
public XWPFRun(CTR r, IRunBody p) { | |||
this.run = r; | |||
this.parent = p; | |||
@@ -103,16 +105,13 @@ public class XWPFRun implements ISDTContents, IRunElement{ | |||
* reserve already occupied drawing ids, so reserving new ids later will | |||
* not corrupt the document | |||
*/ | |||
List<CTDrawing> drawingList = r.getDrawingList(); | |||
for (CTDrawing ctDrawing : drawingList) { | |||
List<CTAnchor> anchorList = ctDrawing.getAnchorList(); | |||
for (CTAnchor anchor : anchorList) { | |||
for (CTDrawing ctDrawing : r.getDrawingArray()) { | |||
for (CTAnchor anchor : ctDrawing.getAnchorArray()) { | |||
if (anchor.getDocPr() != null) { | |||
getDocument().getDrawingIdManager().reserve(anchor.getDocPr().getId()); | |||
} | |||
} | |||
List<CTInline> inlineList = ctDrawing.getInlineList(); | |||
for (CTInline inline : inlineList) { | |||
for (CTInline inline : ctDrawing.getInlineArray()) { | |||
if (inline.getDocPr() != null) { | |||
getDocument().getDrawingIdManager().reserve(inline.getDocPr().getId()); | |||
} | |||
@@ -120,17 +119,17 @@ public class XWPFRun implements ISDTContents, IRunElement{ | |||
} | |||
// Look for any text in any of our pictures or drawings | |||
StringBuffer text = new StringBuffer(); | |||
StringBuilder text = new StringBuilder(); | |||
List<XmlObject> pictTextObjs = new ArrayList<XmlObject>(); | |||
pictTextObjs.addAll(r.getPictList()); | |||
pictTextObjs.addAll(drawingList); | |||
pictTextObjs.addAll(Arrays.asList(r.getPictArray())); | |||
pictTextObjs.addAll(Arrays.asList(r.getDrawingArray())); | |||
for(XmlObject o : pictTextObjs) { | |||
XmlObject[] t = o.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:t"); | |||
for (int m = 0; m < t.length; m++) { | |||
NodeList kids = t[m].getDomNode().getChildNodes(); | |||
XmlObject[] ts = o.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:t"); | |||
for (XmlObject t : ts) { | |||
NodeList kids = t.getDomNode().getChildNodes(); | |||
for (int n = 0; n < kids.getLength(); n++) { | |||
if (kids.item(n) instanceof Text) { | |||
if(text.length() > 0) | |||
if (text.length() > 0) | |||
text.append("\n"); | |||
text.append(kids.item(n).getNodeValue()); | |||
} | |||
@@ -317,7 +316,7 @@ public class XWPFRun implements ISDTContents, IRunElement{ | |||
* @param value the literal text which shall be displayed in the document | |||
*/ | |||
public void setText(String value) { | |||
setText(value,run.getTList().size()); | |||
setText(value,run.sizeOfTArray()); | |||
} | |||
/** |
@@ -50,8 +50,8 @@ public class XWPFSDTContent implements ISDTContent { | |||
private List<ISDTContents> bodyElements = new ArrayList<ISDTContents>(); | |||
public XWPFSDTContent(CTSdtContentRun sdtRun, IBody part, IRunBody parent){ | |||
for (CTR ctr : sdtRun.getRList()){ | |||
XWPFRun run = new XWPFRun((CTR) ctr, parent); | |||
for (CTR ctr : sdtRun.getRArray()){ | |||
XWPFRun run = new XWPFRun(ctr, parent); | |||
runs.add(run); | |||
bodyElements.add(run); | |||
} |
@@ -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()); | |||
} | |||
/** |
@@ -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'); |
@@ -79,7 +79,7 @@ public class XWPFTableCell implements IBody, ICell { | |||
this.part = part; | |||
this.tableRow = tableRow; | |||
// NB: If a table cell does not include at least one block-level element, then this document shall be considered corrupt. | |||
if(cell.getPList().size()<1) | |||
if(cell.sizeOfPArray()<1) | |||
cell.addNewP(); | |||
bodyElements = new ArrayList<IBodyElement>(); | |||
paragraphs = new ArrayList<XWPFParagraph>(); | |||
@@ -398,16 +398,17 @@ public class XWPFTableCell implements IBody, ICell { | |||
* inserts an existing XWPFTable to the arrays bodyElements and tables | |||
* @see org.apache.poi.xwpf.usermodel.IBody#insertTable(int, org.apache.poi.xwpf.usermodel.XWPFTable) | |||
*/ | |||
@SuppressWarnings("deprecation") | |||
public void insertTable(int pos, XWPFTable table) { | |||
bodyElements.add(pos, table); | |||
int i; | |||
for (i = 0; i < ctTc.getTblList().size(); i++) { | |||
CTTbl tbl = ctTc.getTblArray(i); | |||
if(tbl == table.getCTTbl()){ | |||
break; | |||
} | |||
} | |||
tables.add(i, table); | |||
bodyElements.add(pos, table); | |||
int i = 0; | |||
for (CTTbl tbl : ctTc.getTblArray()) { | |||
if (tbl == table.getCTTbl()) { | |||
break; | |||
} | |||
i++; | |||
} | |||
tables.add(i, table); | |||
} | |||
public String getText(){ |
@@ -152,10 +152,11 @@ public class XWPFTableRow { | |||
* who belongs to this row | |||
* @return a list of {@link XWPFTableCell} | |||
*/ | |||
@SuppressWarnings("deprecation") | |||
public List<XWPFTableCell> getTableCells(){ | |||
if(tableCells == null){ | |||
List<XWPFTableCell> cells = new ArrayList<XWPFTableCell>(); | |||
for (CTTc tableCell : ctRow.getTcList()) { | |||
for (CTTc tableCell : ctRow.getTcArray()) { | |||
cells.add(new XWPFTableCell(tableCell, this, table.getBody())); | |||
} | |||
//TODO: it is possible to have an SDT that contains a cell in within a row | |||
@@ -201,7 +202,7 @@ public class XWPFTableRow { | |||
boolean isCant = false; | |||
CTTrPr trpr = getTrPr(); | |||
if (trpr.sizeOfCantSplitArray() > 0) { | |||
CTOnOff onoff = trpr.getCantSplitList().get(0); | |||
CTOnOff onoff = trpr.getCantSplitArray(0); | |||
isCant = onoff.getVal().equals(STOnOff.ON); | |||
} | |||
return isCant; | |||
@@ -229,7 +230,7 @@ public class XWPFTableRow { | |||
boolean repeat = false; | |||
CTTrPr trpr = getTrPr(); | |||
if (trpr.sizeOfTblHeaderArray() > 0) { | |||
CTOnOff rpt = trpr.getTblHeaderList().get(0); | |||
CTOnOff rpt = trpr.getTblHeaderArray(0); | |||
repeat = rpt.getVal().equals(STOnOff.ON); | |||
} | |||
return repeat; |
@@ -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()); | |||
} | |||
@@ -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); |
@@ -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; |
@@ -70,10 +70,10 @@ import org.apache.poi.poifs.crypt.dsig.services.TimeStampService; | |||
import org.apache.poi.poifs.crypt.dsig.services.TimeStampServiceValidator; | |||
import org.apache.poi.poifs.crypt.dsig.services.XmlSignatureService; | |||
import org.apache.poi.poifs.crypt.dsig.spi.DigestInfo; | |||
import org.apache.poi.util.DocumentHelper; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.POILogFactory; | |||
import org.apache.poi.util.POILogger; | |||
import org.apache.poi.util.SAXHelper; | |||
import org.apache.xmlbeans.XmlObject; | |||
import org.bouncycastle.asn1.x509.KeyUsage; | |||
import org.bouncycastle.cert.ocsp.OCSPResp; | |||
@@ -336,7 +336,7 @@ public class TestSignatureInfo { | |||
signatureService.initFacets(cal.getTime()); | |||
initKeyPair(alias, signerDn); | |||
Document document = SAXHelper.getDocumentBuilder().newDocument(); | |||
Document document = DocumentHelper.createDocument(); | |||
// operate | |||
List<X509Certificate> x509Chain = Collections.singletonList(x509); |
@@ -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()); |
@@ -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()); |
@@ -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(); | |||
} | |||
} |
@@ -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 { |
@@ -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")); | |||
} | |||
} |
@@ -49,7 +49,8 @@ import org.xml.sax.SAXException; | |||
* @author Roberto Manicardi | |||
*/ | |||
public final class TestXSSFExportToXML extends TestCase { | |||
public void testExportToXML() throws Exception { | |||
public void testExportToXML() throws Exception { | |||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXMLMappings.xlsx"); | |||
@@ -580,4 +581,37 @@ public final class TestXSSFExportToXML extends TestCase { | |||
} | |||
assertTrue(found); | |||
} | |||
public void testRefElementsInXmlSchema_Bugzilla_56730() throws Exception { | |||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56730.xlsx"); | |||
boolean found = false; | |||
for (POIXMLDocumentPart p : wb.getRelations()) { | |||
if (!(p instanceof MapInfo)) { | |||
continue; | |||
} | |||
MapInfo mapInfo = (MapInfo) p; | |||
XSSFMap map = mapInfo.getXSSFMapById(1); | |||
assertNotNull("XSSFMap is null", map); | |||
XSSFExportToXml exporter = new XSSFExportToXml(map); | |||
ByteArrayOutputStream os = new ByteArrayOutputStream(); | |||
exporter.exportToXML(os, true); | |||
String xmlData = os.toString("UTF-8"); | |||
assertNotNull(xmlData); | |||
assertFalse(xmlData.equals("")); | |||
assertEquals("2014-12-31", xmlData.split("<DATE>")[1].split("</DATE>")[0].trim()); | |||
assertEquals("12.5", xmlData.split("<REFELEMENT>")[1].split("</REFELEMENT>")[0].trim()); | |||
parseXML(xmlData); | |||
found = true; | |||
} | |||
assertTrue(found); | |||
} | |||
} |
@@ -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()); |
@@ -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(); |
@@ -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(); | |||
} | |||
} | |||
} |
@@ -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 |
@@ -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()); | |||
} | |||
} |